diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 3be0a96d9..c5c2197e6 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -41,7 +41,22 @@ Client::Client(std::string const& _clientVersion, Address _us, std::string const m_s.sync(m_tq); m_changed = true; - m_work = new thread([&](){ setThreadName("eth"); while (m_workState != Deleting) work(); m_workState = Deleted; }); + static std::string thread_name = "eth"; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + m_work = dispatch_queue_create(thread_name.c_str(), DISPATCH_QUEUE_SERIAL); + }); + +#if defined(__APPLE__) + dispatch_async(m_work, ^{ +#else + m_work = new thread([&](){ + setThreadName(thread_name); +#endif + + while (m_workState != Deleting) work(); m_workState = Deleted; + }); } Client::~Client() diff --git a/libethereum/Client.h b/libethereum/Client.h index 5f193fea2..e75369be9 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -120,7 +120,13 @@ private: Overlay m_stateDB; ///< Acts as the central point for the state database, so multiple States can share it. State m_s; ///< The present state of the client. PeerServer* m_net = nullptr; ///< Should run in background and send us events when blocks found and allow us to send blocks as required. + +#if defined(__APPLE__) + dispatch_queue_t m_work; +#else std::thread* m_work; ///< The work thread. +#endif + std::mutex m_lock; enum { Active = 0, Deleting, Deleted } m_workState = Active; bool m_doMine = false; ///< Are we supposed to be mining? diff --git a/libethereum/Common.cpp b/libethereum/Common.cpp index c05662ef8..bc9d7e8ec 100644 --- a/libethereum/Common.cpp +++ b/libethereum/Common.cpp @@ -41,8 +41,11 @@ using namespace eth; // Logging int eth::g_logVerbosity = 6; map eth::g_logOverride; + +#if !defined(__APPLE__) thread_local std::string eth::t_logThreadName = "???"; static std::string g_mainThreadName = (eth::t_logThreadName = "main"); +#endif void eth::simpleDebugOut(std::string const& _s, char const*) { diff --git a/libethereum/Common.h b/libethereum/Common.h index e7ecabf35..8ca6b4da9 100644 --- a/libethereum/Common.h +++ b/libethereum/Common.h @@ -41,6 +41,11 @@ #include #include "vector_ref.h" +// OSX likes GCD whichs runs threads within queues +#if defined(__APPLE__) +#include +#endif + namespace eth { @@ -151,9 +156,11 @@ public: }; extern std::map g_logOverride; -extern thread_local std::string t_logThreadName; +#if !defined(__APPLE__) +extern thread_local std::string t_logThreadName; inline void setThreadName(std::string const& _n) { t_logThreadName = _n; } +#endif struct LogChannel { static const char constexpr* name = " "; static const int verbosity = 1; }; struct LeftChannel: public LogChannel { static const char constexpr* name = "<<<"; }; @@ -180,7 +187,13 @@ public: time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); char buf[9]; strftime(buf, 9, "%X", localtime(&rawTime)); + +#if defined(__APPLE__) + const char *threadName = dispatch_queue_get_label(dispatch_get_current_queue()); + sstr << Id::name << " [ " << buf << " | " << dispatch_queue_get_label(dispatch_get_current_queue()) << (_term ? " ] " : ""); +#else sstr << Id::name << " [ " << buf << " | " << t_logThreadName << (_term ? " ] " : ""); +#endif } } ~LogOutputStream() { if (Id::verbosity <= g_logVerbosity) g_logPost(sstr.str(), Id::name); }