diff --git a/libcaf_core/caf/detail/logging.hpp b/libcaf_core/caf/detail/logging.hpp index fb5ae898e1..9f1012f5b1 100644 --- a/libcaf_core/caf/detail/logging.hpp +++ b/libcaf_core/caf/detail/logging.hpp @@ -20,10 +20,12 @@ #ifndef CAF_LOGGING_HPP #define CAF_LOGGING_HPP +#include #include #include #include #include +#include #include "caf/config.hpp" #include "caf/to_string.hpp" @@ -31,6 +33,7 @@ #include "caf/detail/singletons.hpp" #include "caf/detail/scope_guard.hpp" +#include "caf/detail/shared_spinlock.hpp" /* * To enable logging, you have to define CAF_DEBUG. This enables @@ -51,40 +54,35 @@ namespace detail { class singletons; class logging { - + public: friend class detail::singletons; - public: + // returns the actor ID for the current thread or 0 if none is assigned + actor_id get_aid(); // associates given actor id with this thread, // returns the previously set actor id actor_id set_aid(actor_id aid); virtual void log(const char* level, const char* class_name, - const char* function_name, const char* file_name, - int line_num, const std::string& msg) = 0; + const char* function_name, const char* file_name, + int line_num, const std::string& msg) = 0; class trace_helper { - public: - trace_helper(std::string class_name, const char* fun_name, - const char* file_name, int line_num, - const std::string& msg); + const char* file_name, int line_num, const std::string& msg); ~trace_helper(); private: - std::string m_class; const char* m_fun_name; const char* m_file_name; int m_line_num; - }; protected: - virtual ~logging(); static logging* create_singleton(); @@ -93,20 +91,29 @@ class logging { virtual void stop() = 0; - inline void dispose() { delete this; } + inline void dispose() { + delete this; + } + private: + detail::shared_spinlock m_aids_lock; + std::unordered_map m_aids; }; struct oss_wr { + inline oss_wr() { + // nop + } - inline oss_wr() { } - - inline oss_wr(oss_wr&& other) : m_str(std::move(other.m_str)) {} + inline oss_wr(oss_wr&& other) : m_str(std::move(other.m_str)) { + // nop + } std::string m_str; - inline std::string str() { return std::move(m_str); } - + inline std::string str() { + return std::move(m_str); + } }; inline oss_wr operator<<(oss_wr&& lhs, std::string str) { diff --git a/libcaf_core/src/logging.cpp b/libcaf_core/src/logging.cpp index 39c02ceb80..ffe30d4f2f 100644 --- a/libcaf_core/src/logging.cpp +++ b/libcaf_core/src/logging.cpp @@ -50,8 +50,6 @@ namespace detail { namespace { -__thread actor_id t_self_id; - constexpr struct pop_aid_log_event_t { constexpr pop_aid_log_event_t() { // nop @@ -156,7 +154,7 @@ class logging_impl : public logging { } std::ostringstream line; line << time(0) << " " << level << " " - << "actor" << t_self_id << " " << std::this_thread::get_id() << " " + << "actor" << get_aid() << " " << std::this_thread::get_id() << " " << class_name << " " << function_name << " " << file_name << ":" << line_num << " " << msg << std::endl; m_queue.synchronized_enqueue(m_queue_mtx, m_queue_cv, @@ -196,10 +194,31 @@ logging* logging::create_singleton() { return new logging_impl; } +// returns the actor ID for the current thread +actor_id logging::get_aid() { + shared_lock guard{m_aids_lock}; + auto i = m_aids.find(std::this_thread::get_id()); + if (i != m_aids.end()) { + return i->second; + } + return 0; +} + actor_id logging::set_aid(actor_id aid) { - actor_id prev = t_self_id; - t_self_id = aid; - return prev; + auto tid = std::this_thread::get_id(); + upgrade_lock guard{m_aids_lock}; + auto i = m_aids.find(tid); + if (i != m_aids.end()) { + // we modify it despite the shared lock because the elements themselves + // are considered thread-local + auto res = i->second; + i->second = aid; + return res; + } + // upgrade to unique lock and insert new element + upgrade_to_unique_lock uguard{guard}; + m_aids.insert(std::make_pair(tid, aid)); + return 0; // was empty before } } // namespace detail