comparison src/vamp-sdk/PluginAdapter.cpp @ 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 e0ff22b3c888
children bc5e76e90e95
comparison
equal deleted inserted replaced
524:762b79b49c31 525:8c18bdaad04f
122 const Plugin::FeatureSet &features); 122 const Plugin::FeatureSet &features);
123 123
124 // maps both plugins and descriptors to adapters 124 // maps both plugins and descriptors to adapters
125 typedef map<const void *, Impl *> AdapterMap; 125 typedef map<const void *, Impl *> AdapterMap;
126 static AdapterMap *m_adapterMap; 126 static AdapterMap *m_adapterMap;
127 static mutex m_adapterMapMutex; 127 static mutex *m_adapterMapMutex;
128 static Impl *lookupAdapter(VampPluginHandle); 128 static Impl *lookupAdapter(VampPluginHandle);
129 129
130 mutex m_mutex; // guards all of the below 130 mutex m_mutex; // guards all of the below
131 131
132 bool m_populated; 132 bool m_populated;
273 m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor; 273 m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor;
274 m_descriptor.process = vampProcess; 274 m_descriptor.process = vampProcess;
275 m_descriptor.getRemainingFeatures = vampGetRemainingFeatures; 275 m_descriptor.getRemainingFeatures = vampGetRemainingFeatures;
276 m_descriptor.releaseFeatureSet = vampReleaseFeatureSet; 276 m_descriptor.releaseFeatureSet = vampReleaseFeatureSet;
277 277
278 lock_guard<mutex> adapterMapGuard(m_adapterMapMutex); 278 lock_guard<mutex> adapterMapGuard(*m_adapterMapMutex);
279 279
280 if (!m_adapterMap) { 280 if (!m_adapterMap) {
281 m_adapterMap = new AdapterMap; 281 m_adapterMap = new AdapterMap;
282 } 282 }
283 (*m_adapterMap)[&m_descriptor] = this; 283 (*m_adapterMap)[&m_descriptor] = this;
323 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) { 323 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) {
324 free((void *)m_descriptor.programs[i]); 324 free((void *)m_descriptor.programs[i]);
325 } 325 }
326 free((void *)m_descriptor.programs); 326 free((void *)m_descriptor.programs);
327 327
328 lock_guard<mutex> adapterMapGuard(m_adapterMapMutex); 328 lock_guard<mutex> adapterMapGuard(*m_adapterMapMutex);
329 329
330 if (m_adapterMap) { 330 if (m_adapterMap) {
331 331
332 m_adapterMap->erase(&m_descriptor); 332 m_adapterMap->erase(&m_descriptor);
333 333
334 if (m_adapterMap->empty()) { 334 if (m_adapterMap->empty()) {
335 delete m_adapterMap; 335 delete m_adapterMap;
336 m_adapterMap = 0; 336 m_adapterMap = 0;
337 } 337 }
338 } 338 }
343 { 343 {
344 #ifdef DEBUG_PLUGIN_ADAPTER 344 #ifdef DEBUG_PLUGIN_ADAPTER
345 cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << endl; 345 cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << endl;
346 #endif 346 #endif
347 347
348 lock_guard<mutex> adapterMapGuard(m_adapterMapMutex); 348 lock_guard<mutex> adapterMapGuard(*m_adapterMapMutex);
349 349
350 if (!m_adapterMap) return 0; 350 if (!m_adapterMap) return 0;
351 AdapterMap::const_iterator i = m_adapterMap->find(handle); 351 AdapterMap::const_iterator i = m_adapterMap->find(handle);
352 if (i == m_adapterMap->end()) return 0; 352 if (i == m_adapterMap->end()) return 0;
353 return i->second; 353 return i->second;
359 { 359 {
360 #ifdef DEBUG_PLUGIN_ADAPTER 360 #ifdef DEBUG_PLUGIN_ADAPTER
361 cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << endl; 361 cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << endl;
362 #endif 362 #endif
363 363
364 lock_guard<mutex> adapterMapGuard(m_adapterMapMutex); 364 lock_guard<mutex> adapterMapGuard(*m_adapterMapMutex);
365 365
366 if (!m_adapterMap) { 366 if (!m_adapterMap) {
367 m_adapterMap = new AdapterMap(); 367 m_adapterMap = new AdapterMap();
368 } 368 }
369 369
623 void 623 void
624 PluginAdapterBase::Impl::cleanup(Plugin *plugin) 624 PluginAdapterBase::Impl::cleanup(Plugin *plugin)
625 { 625 {
626 // at this point no mutex is held 626 // at this point no mutex is held
627 627
628 lock_guard<mutex> adapterMapGuard(m_adapterMapMutex); 628 lock_guard<mutex> adapterMapGuard(*m_adapterMapMutex);
629 lock_guard<mutex> guard(m_mutex); 629 lock_guard<mutex> guard(m_mutex);
630 630
631 if (m_fs.find(plugin) != m_fs.end()) { 631 if (m_fs.find(plugin) != m_fs.end()) {
632 size_t outputCount = 0; 632 size_t outputCount = 0;
633 if (m_pluginOutputs[plugin]) { 633 if (m_pluginOutputs[plugin]) {
988 } 988 }
989 989
990 PluginAdapterBase::Impl::AdapterMap * 990 PluginAdapterBase::Impl::AdapterMap *
991 PluginAdapterBase::Impl::m_adapterMap = 0; 991 PluginAdapterBase::Impl::m_adapterMap = 0;
992 992
993 mutex 993 // This is allocated on the heap so that we can be sure it outlives
994 PluginAdapterBase::Impl::m_adapterMapMutex; 994 // the adapters themselves, which are typically static within the
995 // plugin library. If this was also static, then it might be destroyed
996 // before the last adapter, and we would end up trying to lock an
997 // invalid mutex when removing an adapter from the adapter map.
998 mutex *
999 PluginAdapterBase::Impl::m_adapterMapMutex = new mutex;
995 1000
996 } 1001 }
997 1002
998 _VAMP_SDK_PLUGSPACE_END(PluginAdapter.cpp) 1003 _VAMP_SDK_PLUGSPACE_END(PluginAdapter.cpp)
999 1004