Mercurial > hg > orthanc
changeset 6962:3948b93ed918
improved concurrency by making threadNamesMutex_ a readers-writer lock
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Fri, 26 Jun 2026 15:02:11 +0200 |
| parents | 714b20840e91 |
| children | a710e864790d c60dae105872 |
| files | OrthancFramework/Sources/Logging.cpp |
| diffstat | 1 files changed, 41 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancFramework/Sources/Logging.cpp Fri Jun 26 14:33:02 2026 +0200 +++ b/OrthancFramework/Sources/Logging.cpp Fri Jun 26 15:02:11 2026 +0200 @@ -628,7 +628,7 @@ static std::string pluginName_; // this string can only be non-empty if running from a plugin static bool hasOrthancAdvancedLogging_ = false; // Whether the Orthanc runtime is >= 1.12.4 static bool hasClearThreadName_ = false; // Whether the Orthanc runtime is >= 1.12.12 -static boost::recursive_mutex threadNamesMutex_; +static boost::shared_mutex threadNamesMutex_; static std::map<boost::thread::id, std::string> threadNames_; static bool enableThreadNames_ = true; static std::list<Orthanc::Logging::ILoggingListener*> loggingListeners_; @@ -702,29 +702,26 @@ } - void SetCurrentThreadNameInternal(const boost::thread::id& id, const std::string& name) + void SetCurrentThreadName(const std::string& name) { - boost::recursive_mutex::scoped_lock lock(threadNamesMutex_); - if (name.size() > 16) { throw OrthancException(ErrorCode_InternalError, std::string("Thread name can not exceed 16 characters: ") + name); } - threadNames_[id] = name; + if (pluginContext_ == NULL) + { + const boost::thread::id threadId = boost::this_thread::get_id(); + + { + boost::unique_lock<boost::shared_mutex> lock(threadNamesMutex_); + threadNames_[threadId] = name; + } #if defined(__linux__) && !defined(NDEBUG) && !defined(__LSB_VERSION__) - // set the thread name at "system" level too -> required to have the thread names visible in GDB ! - pthread_setname_np(pthread_self(), name.substr(0, 15).c_str()); // thread names are limited to 15 in Linux + // set the thread name at "system" level too -> required to have the thread names visible in GDB ! + pthread_setname_np(pthread_self(), name.substr(0, 15).c_str()); // thread names are limited to 15 in Linux #endif - } - - void SetCurrentThreadName(const std::string& name) - { - if (pluginContext_ == NULL) - { - boost::recursive_mutex::scoped_lock lock(threadNamesMutex_); - SetCurrentThreadNameInternal(boost::this_thread::get_id(), name); } else { @@ -732,50 +729,61 @@ } } + bool HasCurrentThreadName() { - boost::thread::id threadId = boost::this_thread::get_id(); + const boost::thread::id threadId = boost::this_thread::get_id(); - boost::recursive_mutex::scoped_lock lock(threadNamesMutex_); - return threadNames_.find(threadId) != threadNames_.end(); + { + boost::shared_lock<boost::shared_mutex> lock(threadNamesMutex_); + return threadNames_.find(threadId) != threadNames_.end(); + } } + void ClearCurrentThreadName() { if (pluginContext_ == NULL) { - boost::thread::id threadId = boost::this_thread::get_id(); + const boost::thread::id threadId = boost::this_thread::get_id(); - boost::recursive_mutex::scoped_lock lock(threadNamesMutex_); - threadNames_.erase(threadId); + { + boost::unique_lock<boost::shared_mutex> lock(threadNamesMutex_); + threadNames_.erase(threadId); + } } else if (hasClearThreadName_) // only recent runtimes support it (from 1.12.12) { pluginContext_->InvokeService(pluginContext_, _OrthancPluginService_ClearCurrentThreadName, NULL); } + } - } static std::string GetCurrentThreadName() { - boost::thread::id threadId = boost::this_thread::get_id(); + const boost::thread::id threadId = boost::this_thread::get_id(); - boost::recursive_mutex::scoped_lock lock(threadNamesMutex_); + { + boost::shared_lock<boost::shared_mutex> lock(threadNamesMutex_); - if (threadNames_.find(threadId) == threadNames_.end()) - { - // set the threadId as the thread name - SetCurrentThreadNameInternal(threadId, boost::lexical_cast<std::string>(threadId)); + std::map<boost::thread::id, std::string>::const_iterator found = threadNames_.find(threadId); + if (found != threadNames_.end()) + { + return found->second; + } } - return threadNames_[threadId]; + // "SetCurrentThreadName()" has not been invoked for this thread + return boost::lexical_cast<std::string>(threadId); } + ScopedThreadNameSetter::ScopedThreadNameSetter(const std::string& threadName) { SetCurrentThreadName(threadName); } + ScopedThreadNameSetter::~ScopedThreadNameSetter() { ClearCurrentThreadName(); @@ -788,12 +796,14 @@ loggingListeners_.push_back(listener); } + void ClearLoggingListeners() { boost::unique_lock<boost::shared_mutex> lock(loggingListenersMutex_); loggingListeners_.clear(); } + static void GetLinePrefix(std::string& prefix, LogLevel level, const char* pluginName, // when logging in the core but coming from a plugin, pluginName_ is NULL but this argument is != NULL @@ -926,12 +936,14 @@ } } + void Finalize() { boost::mutex::scoped_lock lock(loggingStreamsMutex_); loggingStreamsContext_.reset(NULL); } + void Reset() { {
