Mercurial > hg > svcore
comparison plugin/NativeVampPluginFactory.cpp @ 1776:5750b9e60818
Don't even ask to unload a library if we know about other plugins that are loaded from it. Plus debug tweaks
author | Chris Cannam |
---|---|
date | Mon, 09 Sep 2019 10:25:16 +0100 |
parents | 70e172e6cc59 |
children | 5f8fbbde08ff |
comparison
equal
deleted
inserted
replaced
1775:e3db163e3f50 | 1776:5750b9e60818 |
---|---|
51 | 51 |
52 PluginDeletionNotifyAdapter::~PluginDeletionNotifyAdapter() | 52 PluginDeletionNotifyAdapter::~PluginDeletionNotifyAdapter() |
53 { | 53 { |
54 // see notes in vamp-sdk/hostext/PluginLoader.cpp from which this is drawn | 54 // see notes in vamp-sdk/hostext/PluginLoader.cpp from which this is drawn |
55 Vamp::Plugin *p = m_plugin; | 55 Vamp::Plugin *p = m_plugin; |
56 | |
57 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | |
58 SVCERR << "PluginDeletionNotifyAdapter::~PluginDeletionNotifyAdapter(" | |
59 << this << " for plugin " << p << ")" << endl; | |
60 #endif | |
61 | |
56 delete m_plugin; | 62 delete m_plugin; |
57 m_plugin = nullptr; | 63 m_plugin = nullptr; |
58 // acceptable use after free here, as pluginDeleted uses p only as | 64 // acceptable use after free here, as pluginDeleted uses p only as |
59 // pointer key and does not deref it | 65 // pointer key and does not deref it |
60 if (m_factory) m_factory->pluginDeleted(p); | 66 if (m_factory) m_factory->pluginDeleted(p); |
142 } | 148 } |
143 continue; | 149 continue; |
144 } | 150 } |
145 | 151 |
146 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 152 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
147 cerr << "NativeVampPluginFactory::getPluginIdentifiers: Vamp descriptor found" << endl; | 153 SVCERR << "NativeVampPluginFactory::getPluginIdentifiers: Vamp descriptor found" << endl; |
148 #endif | 154 #endif |
149 | 155 |
150 const VampPluginDescriptor *descriptor = nullptr; | 156 const VampPluginDescriptor *descriptor = nullptr; |
151 int index = 0; | 157 int index = 0; |
152 | 158 |
181 QString id = PluginIdentifier::createIdentifier | 187 QString id = PluginIdentifier::createIdentifier |
182 ("vamp", libpath, descriptor->identifier); | 188 ("vamp", libpath, descriptor->identifier); |
183 m_identifiers.push_back(id); | 189 m_identifiers.push_back(id); |
184 m_libraries[id] = libpath; | 190 m_libraries[id] = libpath; |
185 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 191 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
186 cerr << "NativeVampPluginFactory::getPluginIdentifiers: Found plugin id " << id << " at index " << index << endl; | 192 SVCERR << "NativeVampPluginFactory::getPluginIdentifiers: Found plugin id " << id << " at index " << index << endl; |
187 #endif | 193 #endif |
188 ++index; | 194 ++index; |
189 } | 195 } |
190 } | 196 } |
191 | 197 |
198 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | |
199 SVCERR << "NativeVampPluginFactory::getPluginIdentifiers: unloading library " << libraryHandle << endl; | |
200 #endif | |
201 | |
192 if (DLCLOSE(libraryHandle) != 0) { | 202 if (DLCLOSE(libraryHandle) != 0) { |
193 SVDEBUG << "WARNING: NativeVampPluginFactory::getPluginIdentifiers: Failed to unload library " << libpath << endl; | 203 SVDEBUG << "WARNING: NativeVampPluginFactory::getPluginIdentifiers: Failed to unload library " << libpath << endl; |
194 } | 204 } |
195 } | 205 } |
196 | 206 |
206 NativeVampPluginFactory::findPluginFile(QString soname, QString inDir) | 216 NativeVampPluginFactory::findPluginFile(QString soname, QString inDir) |
207 { | 217 { |
208 QString file = ""; | 218 QString file = ""; |
209 | 219 |
210 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 220 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
211 cerr << "NativeVampPluginFactory::findPluginFile(\"" | 221 SVCERR << "NativeVampPluginFactory::findPluginFile(\"" |
212 << soname << "\", \"" << inDir << "\")" | 222 << soname << "\", \"" << inDir << "\")" |
213 << endl; | 223 << endl; |
214 #endif | 224 #endif |
215 | 225 |
216 if (inDir != "") { | 226 if (inDir != "") { |
223 file = dir.filePath(QFileInfo(soname).fileName()); | 233 file = dir.filePath(QFileInfo(soname).fileName()); |
224 | 234 |
225 if (QFileInfo(file).exists() && QFileInfo(file).isFile()) { | 235 if (QFileInfo(file).exists() && QFileInfo(file).isFile()) { |
226 | 236 |
227 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 237 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
228 cerr << "NativeVampPluginFactory::findPluginFile: " | 238 SVCERR << "NativeVampPluginFactory::findPluginFile: " |
229 << "found trivially at " << file << endl; | 239 << "found trivially at " << file << endl; |
230 #endif | 240 #endif |
231 | 241 |
232 return file; | 242 return file; |
233 } | 243 } |
235 for (unsigned int j = 0; j < dir.count(); ++j) { | 245 for (unsigned int j = 0; j < dir.count(); ++j) { |
236 file = dir.filePath(dir[j]); | 246 file = dir.filePath(dir[j]); |
237 if (QFileInfo(file).baseName() == QFileInfo(soname).baseName()) { | 247 if (QFileInfo(file).baseName() == QFileInfo(soname).baseName()) { |
238 | 248 |
239 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 249 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
240 cerr << "NativeVampPluginFactory::findPluginFile: " | 250 SVCERR << "NativeVampPluginFactory::findPluginFile: " |
241 << "found \"" << soname << "\" at " << file << endl; | 251 << "found \"" << soname << "\" at " << file << endl; |
242 #endif | 252 #endif |
243 | 253 |
244 return file; | 254 return file; |
245 } | 255 } |
246 } | 256 } |
247 | 257 |
248 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 258 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
249 cerr << "NativeVampPluginFactory::findPluginFile (with dir): " | 259 SVCERR << "NativeVampPluginFactory::findPluginFile (with dir): " |
250 << "not found" << endl; | 260 << "not found" << endl; |
251 #endif | 261 #endif |
252 | 262 |
253 return ""; | 263 return ""; |
254 | 264 |
256 | 266 |
257 QFileInfo fi(soname); | 267 QFileInfo fi(soname); |
258 | 268 |
259 if (fi.isAbsolute() && fi.exists() && fi.isFile()) { | 269 if (fi.isAbsolute() && fi.exists() && fi.isFile()) { |
260 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 270 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
261 cerr << "NativeVampPluginFactory::findPluginFile: " | 271 SVCERR << "NativeVampPluginFactory::findPluginFile: " |
262 << "found trivially at " << soname << endl; | 272 << "found trivially at " << soname << endl; |
263 #endif | 273 #endif |
264 return soname; | 274 return soname; |
265 } | 275 } |
266 | 276 |
277 if (file != "") return file; | 287 if (file != "") return file; |
278 } | 288 } |
279 } | 289 } |
280 | 290 |
281 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 291 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
282 cerr << "NativeVampPluginFactory::findPluginFile: " | 292 SVCERR << "NativeVampPluginFactory::findPluginFile: " |
283 << "not found" << endl; | 293 << "not found" << endl; |
284 #endif | 294 #endif |
285 | 295 |
286 return ""; | 296 return ""; |
287 } | 297 } |
301 | 311 |
302 QString type, soname, label; | 312 QString type, soname, label; |
303 PluginIdentifier::parseIdentifier(identifier, type, soname, label); | 313 PluginIdentifier::parseIdentifier(identifier, type, soname, label); |
304 if (type != "vamp") { | 314 if (type != "vamp") { |
305 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 315 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
306 cerr << "NativeVampPluginFactory::instantiatePlugin: Wrong factory for plugin type " << type << endl; | 316 SVCERR << "NativeVampPluginFactory::instantiatePlugin: Wrong factory for plugin type " << type << endl; |
307 #endif | 317 #endif |
308 return nullptr; | 318 return nullptr; |
309 } | 319 } |
310 | 320 |
311 QString found = findPluginFile(soname); | 321 QString found = findPluginFile(soname); |
314 SVDEBUG << "NativeVampPluginFactory::instantiatePlugin: Failed to find library file " << soname << endl; | 324 SVDEBUG << "NativeVampPluginFactory::instantiatePlugin: Failed to find library file " << soname << endl; |
315 return nullptr; | 325 return nullptr; |
316 } else if (found != soname) { | 326 } else if (found != soname) { |
317 | 327 |
318 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 328 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
319 cerr << "NativeVampPluginFactory::instantiatePlugin: Given library name was " << soname << ", found at " << found << endl; | 329 SVCERR << "NativeVampPluginFactory::instantiatePlugin: Given library name was " << soname << ", found at " << found << endl; |
320 cerr << soname << " -> " << found << endl; | 330 SVCERR << soname << " -> " << found << endl; |
321 #endif | 331 #endif |
322 | 332 |
323 } | 333 } |
324 | 334 |
325 soname = found; | 335 soname = found; |
354 if (plugin) { | 364 if (plugin) { |
355 m_handleMap[plugin] = libraryHandle; | 365 m_handleMap[plugin] = libraryHandle; |
356 rv = new PluginDeletionNotifyAdapter(plugin, this); | 366 rv = new PluginDeletionNotifyAdapter(plugin, this); |
357 } | 367 } |
358 | 368 |
359 // SVDEBUG << "NativeVampPluginFactory::instantiatePlugin: Constructed Vamp plugin, rv is " << rv << endl; | 369 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE |
360 | 370 if (rv) { |
361 //!!! need to dlclose() when plugins from a given library are unloaded | 371 SVCERR << "NativeVampPluginFactory::instantiatePlugin: Instantiated plugin " << label << " from library " << soname << ": descriptor " << descriptor << ", rv "<< rv << ", label " << rv->getName() << ", outputs " << rv->getOutputDescriptors().size() << endl; |
372 } | |
373 #endif | |
362 | 374 |
363 done: | 375 done: |
364 if (!rv) { | 376 if (!rv) { |
377 SVCERR << "NativeVampPluginFactory::instantiatePlugin: Failed to construct plugin" << endl; | |
365 if (DLCLOSE(libraryHandle) != 0) { | 378 if (DLCLOSE(libraryHandle) != 0) { |
366 SVDEBUG << "WARNING: NativeVampPluginFactory::instantiatePlugin: Failed to unload library " << soname << endl; | 379 SVDEBUG << "WARNING: NativeVampPluginFactory::instantiatePlugin: Failed to unload library " << soname << endl; |
367 } | 380 } |
368 } | 381 } |
369 | |
370 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | |
371 cerr << "NativeVampPluginFactory::instantiatePlugin: Instantiated plugin " << label << " from library " << soname << ": descriptor " << descriptor << ", rv "<< rv << ", label " << rv->getName() << ", outputs " << rv->getOutputDescriptors().size() << endl; | |
372 #endif | |
373 | 382 |
374 return rv; | 383 return rv; |
375 } | 384 } |
376 | 385 |
377 void | 386 void |
378 NativeVampPluginFactory::pluginDeleted(Vamp::Plugin *plugin) | 387 NativeVampPluginFactory::pluginDeleted(Vamp::Plugin *plugin) |
379 { | 388 { |
380 void *handle = m_handleMap[plugin]; | 389 void *handle = m_handleMap[plugin]; |
381 if (handle) { | 390 if (!handle) return; |
382 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | 391 |
383 cerr << "unloading library " << handle << " for plugin " << plugin << endl; | |
384 #endif | |
385 DLCLOSE(handle); | |
386 } | |
387 m_handleMap.erase(plugin); | 392 m_handleMap.erase(plugin); |
393 | |
394 #ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE | |
395 SVCERR << "NativeVampPluginFactory::pluginDeleted: Removed from handle map, which now has " << m_handleMap.size() << " entries" << endl; | |
396 #endif | |
397 | |
398 for (auto h: m_handleMap) { | |
399 if (h.second == handle) { | |
400 // still in use | |
401 SVDEBUG << "NativeVampPluginFactory::pluginDeleted: Not unloading library " << handle << " as other plugins are still loaded from it" << endl; | |
402 return; | |
403 } | |
404 } | |
405 | |
406 SVDEBUG << "NativeVampPluginFactory::pluginDeleted: Unloading library " << handle << " after last plugin from this library " << plugin << " was deleted" << endl; | |
407 DLCLOSE(handle); | |
388 } | 408 } |
389 | 409 |
390 QString | 410 QString |
391 NativeVampPluginFactory::getPluginCategory(QString identifier) | 411 NativeVampPluginFactory::getPluginCategory(QString identifier) |
392 { | 412 { |
425 QFile file(path[i] + "/" + dir[j]); | 445 QFile file(path[i] + "/" + dir[j]); |
426 | 446 |
427 // SVDEBUG << "LADSPAPluginFactory::generateFallbackCategories: about to open " << (path[i]+ "/" + dir[j]) << endl; | 447 // SVDEBUG << "LADSPAPluginFactory::generateFallbackCategories: about to open " << (path[i]+ "/" + dir[j]) << endl; |
428 | 448 |
429 if (file.open(QIODevice::ReadOnly)) { | 449 if (file.open(QIODevice::ReadOnly)) { |
430 // cerr << "...opened" << endl; | |
431 QTextStream stream(&file); | 450 QTextStream stream(&file); |
432 QString line; | 451 QString line; |
433 | 452 |
434 while (!stream.atEnd()) { | 453 while (!stream.atEnd()) { |
435 line = stream.readLine(); | 454 line = stream.readLine(); |
436 // cerr << "line is: \"" << line << "\"" << endl; | |
437 QString id = PluginIdentifier::canonicalise | 455 QString id = PluginIdentifier::canonicalise |
438 (line.section("::", 0, 0)); | 456 (line.section("::", 0, 0)); |
439 QString cat = line.section("::", 1, 1); | 457 QString cat = line.section("::", 1, 1); |
440 m_taxonomy[id] = cat; | 458 m_taxonomy[id] = cat; |
441 // cerr << "NativeVampPluginFactory: set id \"" << id << "\" to cat \"" << cat << "\"" << endl; | |
442 } | 459 } |
443 } | 460 } |
444 } | 461 } |
445 } | 462 } |
446 } | 463 } |