summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/ModuleList.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2014-03-24 16:50:33 +0000
committerGreg Clayton <gclayton@apple.com>2014-03-24 16:50:33 +0000
commit1d77a8203be147ae41692fecad4c41035dbe69a1 (patch)
tree3bb3b713621b23fe787023bb4b436382c83d237d /lldb/source/Core/ModuleList.cpp
parentd89b13625e3087b94212356b64f3d011e65852e4 (diff)
downloadbcm5719-llvm-1d77a8203be147ae41692fecad4c41035dbe69a1.tar.gz
bcm5719-llvm-1d77a8203be147ae41692fecad4c41035dbe69a1.zip
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
Diffstat (limited to 'lldb/source/Core/ModuleList.cpp')
-rw-r--r--lldb/source/Core/ModuleList.cpp44
1 files changed, 34 insertions, 10 deletions
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 <stdint.h>
+
// 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;
}
OpenPOWER on IntegriCloud