Since PassRegistry is currently a shared global object, it needs locking. While...
authorOwen Anderson <resistor@mac.com>
Wed, 15 Sep 2010 23:03:33 +0000 (23:03 +0000)
committerOwen Anderson <resistor@mac.com>
Wed, 15 Sep 2010 23:03:33 +0000 (23:03 +0000)
that all the setup of this class currently happens at static initialization time, this misses the fact
that some later events can cause mutation of the PassRegistrationListeners list, and thus cause race issues.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114036 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/PassRegistry.h
lib/VMCore/PassRegistry.cpp

index 31d48a4e28f0b782b183981ffc82ac3d40cfb3fe..8b7f036e20c181b0ca37321b95242121dfbc7476 100644 (file)
@@ -18,6 +18,7 @@
 #define LLVM_PASSREGISTRY_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/System/Mutex.h"
 
 namespace llvm {
 
@@ -32,6 +33,7 @@ struct PassRegistrationListener;
 /// each thread.
 class PassRegistry {
   mutable void *pImpl;
+  mutable sys::SmartMutex<true> Lock;
   void *getImpl() const;
    
 public:
index c6dc9210cb2a41add4a9142fff016aa421e00270..0b4e59dc0e608385e7365353004f6b373915df91 100644 (file)
@@ -88,6 +88,7 @@ const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
 //
 
 void PassRegistry::registerPass(const PassInfo &PI) {
+  sys::SmartScopedLock<true> Guard(Lock);
   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
   bool Inserted =
     Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
@@ -101,6 +102,7 @@ void PassRegistry::registerPass(const PassInfo &PI) {
 }
 
 void PassRegistry::unregisterPass(const PassInfo &PI) {
+  sys::SmartScopedLock<true> Guard(Lock);
   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
   PassRegistryImpl::MapType::iterator I = 
     Impl->PassInfoMap.find(PI.getTypeInfo());
@@ -112,6 +114,7 @@ void PassRegistry::unregisterPass(const PassInfo &PI) {
 }
 
 void PassRegistry::enumerateWith(PassRegistrationListener *L) {
+  sys::SmartScopedLock<true> Guard(Lock);
   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
   for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(),
        E = Impl->PassInfoMap.end(); I != E; ++I)
@@ -124,6 +127,7 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID,
                                          const void *PassID,
                                          PassInfo& Registeree,
                                          bool isDefault) {
+  sys::SmartScopedLock<true> Guard(Lock);
   PassInfo *InterfaceInfo =  const_cast<PassInfo*>(getPassInfo(InterfaceID));
   if (InterfaceInfo == 0) {
     // First reference to Interface, register it now.
@@ -159,11 +163,14 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID,
 }
 
 void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
+  sys::SmartScopedLock<true> Guard(Lock);
   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
   Impl->Listeners.push_back(L);
 }
 
 void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) {
+  sys::SmartScopedLock<true> Guard(Lock);
+  
   // NOTE: This is necessary, because removeRegistrationListener() can be called
   // as part of the llvm_shutdown sequence.  Since we have no control over the
   // order of that sequence, we need to gracefully handle the case where the