Mercurial > hg > vamp-plugin-sdk
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 |