From 1d77a8203be147ae41692fecad4c41035dbe69a1 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Mon, 24 Mar 2014 16:50:33 +0000 Subject: Modified patch from Piotr Rak that makes GetSharedModuleList() more thread safe and also fixed a missed member initialization on the copy contractor and also makes the assignment operator safer. llvm-svn: 204622 --- lldb/source/Core/ModuleList.cpp | 44 +++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) (limited to 'lldb/source/Core/ModuleList.cpp') diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 215611e4242..32af1eaf50d 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -10,6 +10,8 @@ #include "lldb/Core/ModuleList.h" // C Includes +#include + // C++ Includes // Other libraries and framework includes // Project includes @@ -40,7 +42,8 @@ ModuleList::ModuleList() : //---------------------------------------------------------------------- ModuleList::ModuleList(const ModuleList& rhs) : m_modules(), - m_modules_mutex (Mutex::eMutexTypeRecursive) + m_modules_mutex (Mutex::eMutexTypeRecursive), + m_notifier(NULL) { Mutex::Locker lhs_locker(m_modules_mutex); Mutex::Locker rhs_locker(rhs.m_modules_mutex); @@ -62,9 +65,28 @@ ModuleList::operator= (const ModuleList& rhs) { if (this != &rhs) { - Mutex::Locker lhs_locker(m_modules_mutex); - Mutex::Locker rhs_locker(rhs.m_modules_mutex); - m_modules = rhs.m_modules; + // That's probably me nit-picking, but in theoretical situation: + // + // * that two threads A B and + // * two ModuleList's x y do opposite assignemnts ie.: + // + // in thread A: | in thread B: + // x = y; | y = x; + // + // This establishes correct(same) lock taking order and thus + // avoids priority inversion. + if (uintptr_t(this) > uintptr_t(&rhs)) + { + Mutex::Locker lhs_locker(m_modules_mutex); + Mutex::Locker rhs_locker(rhs.m_modules_mutex); + m_modules = rhs.m_modules; + } + else + { + Mutex::Locker rhs_locker(rhs.m_modules_mutex); + Mutex::Locker lhs_locker(m_modules_mutex); + m_modules = rhs.m_modules; + } } return *this; } @@ -832,13 +854,15 @@ ModuleList::GetIndexForModule (const Module *module) const static ModuleList & GetSharedModuleList () { - // NOTE: Intentionally leak the module list so a program doesn't have to - // cleanup all modules and object files as it exits. This just wastes time - // doing a bunch of cleanup that isn't required. static ModuleList *g_shared_module_list = NULL; - if (g_shared_module_list == NULL) - g_shared_module_list = new ModuleList(); // <--- Intentional leak!!! - + static std::once_flag g_once_flag; + std::call_once(g_once_flag, [](){ + // NOTE: Intentionally leak the module list so a program doesn't have to + // cleanup all modules and object files as it exits. This just wastes time + // doing a bunch of cleanup that isn't required. + if (g_shared_module_list == NULL) + g_shared_module_list = new ModuleList(); // <--- Intentional leak!!! + }); return *g_shared_module_list; } -- cgit v1.2.3