changeset 525:8c18bdaad04f c++11-mutex

Avoid simple static allocation of mutex, as it could lead to mutex being destroyed before last adapter that needs to use it (since adapters are usually also static)
author Chris Cannam
date Mon, 09 Sep 2019 10:24:13 +0100
parents 762b79b49c31
children 459cddd7e64a
files src/vamp-sdk/PluginAdapter.cpp
diffstat 1 files changed, 14 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/vamp-sdk/PluginAdapter.cpp	Mon Sep 09 10:23:37 2019 +0100
+++ b/src/vamp-sdk/PluginAdapter.cpp	Mon Sep 09 10:24:13 2019 +0100
@@ -124,7 +124,7 @@
     // maps both plugins and descriptors to adapters
     typedef map<const void *, Impl *> AdapterMap;
     static AdapterMap *m_adapterMap;
-    static mutex m_adapterMapMutex;
+    static mutex *m_adapterMapMutex;
     static Impl *lookupAdapter(VampPluginHandle);
 
     mutex m_mutex; // guards all of the below
@@ -275,7 +275,7 @@
     m_descriptor.getRemainingFeatures = vampGetRemainingFeatures;
     m_descriptor.releaseFeatureSet = vampReleaseFeatureSet;
 
-    lock_guard<mutex> adapterMapGuard(m_adapterMapMutex);
+    lock_guard<mutex> adapterMapGuard(*m_adapterMapMutex);
     
     if (!m_adapterMap) {
         m_adapterMap = new AdapterMap;
@@ -325,12 +325,12 @@
     }
     free((void *)m_descriptor.programs);
 
-    lock_guard<mutex> adapterMapGuard(m_adapterMapMutex);
+    lock_guard<mutex> adapterMapGuard(*m_adapterMapMutex);
     
     if (m_adapterMap) {
         
         m_adapterMap->erase(&m_descriptor);
-
+        
         if (m_adapterMap->empty()) {
             delete m_adapterMap;
             m_adapterMap = 0;
@@ -345,7 +345,7 @@
     cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << endl;
 #endif
 
-    lock_guard<mutex> adapterMapGuard(m_adapterMapMutex);
+    lock_guard<mutex> adapterMapGuard(*m_adapterMapMutex);
     
     if (!m_adapterMap) return 0;
     AdapterMap::const_iterator i = m_adapterMap->find(handle);
@@ -361,7 +361,7 @@
     cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << endl;
 #endif
 
-    lock_guard<mutex> adapterMapGuard(m_adapterMapMutex);
+    lock_guard<mutex> adapterMapGuard(*m_adapterMapMutex);
     
     if (!m_adapterMap) {
         m_adapterMap = new AdapterMap();
@@ -625,7 +625,7 @@
 {
     // at this point no mutex is held
     
-    lock_guard<mutex> adapterMapGuard(m_adapterMapMutex);
+    lock_guard<mutex> adapterMapGuard(*m_adapterMapMutex);
     lock_guard<mutex> guard(m_mutex);
     
     if (m_fs.find(plugin) != m_fs.end()) {
@@ -990,8 +990,13 @@
 PluginAdapterBase::Impl::AdapterMap *
 PluginAdapterBase::Impl::m_adapterMap = 0;
 
-mutex
-PluginAdapterBase::Impl::m_adapterMapMutex;
+// This is allocated on the heap so that we can be sure it outlives
+// the adapters themselves, which are typically static within the
+// plugin library. If this was also static, then it might be destroyed
+// before the last adapter, and we would end up trying to lock an
+// invalid mutex when removing an adapter from the adapter map.
+mutex *
+PluginAdapterBase::Impl::m_adapterMapMutex = new mutex;
 
 }