From 14f6d63934ea76fc875199b3b54a846885583826 Mon Sep 17 00:00:00 2001 From: waxfrenzy Date: Mon, 20 Jan 2003 20:14:31 +0000 Subject: [PATCH] Slight changes to LADSPAInfo class --- SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.C | 96 +++++++++---------- SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.h | 39 +++++--- .../Plugins/LADSPAPlugin/LADSPAPlugin.C | 6 +- 3 files changed, 73 insertions(+), 68 deletions(-) diff --git a/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.C b/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.C index adbe3c4..007b9b2 100644 --- a/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.C +++ b/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.C @@ -85,10 +85,6 @@ LADSPAInfo::RescanPlugins(void) cerr << m_Plugins.size() << " plugins found in " << m_Libraries.size() << " libraries" << endl; } -// No last loaded library or plugin - m_LastLoadedLibraryIndex = m_Libraries.size(); - m_LastLoadedPluginIndex = m_Plugins.size(); - // Sort list by name sort(m_OrderedPluginList.begin(), m_OrderedPluginList.end(), PluginEntrySortAsc()); @@ -115,29 +111,12 @@ LADSPAInfo::UnloadAllLibraries(void) for (vector::iterator i = m_Libraries.begin(); i != m_Libraries.end(); i++) { if (i->Handle) dlclose(i->Handle); - } - -// No last loaded library or plugin - m_LastLoadedLibraryIndex = m_Libraries.size(); - m_LastLoadedPluginIndex = m_Plugins.size(); -} - -void -LADSPAInfo::UnloadLibraryByID(unsigned long unique_id) -{ - if (m_IDLookup.find(unique_id) == m_IDLookup.end()) { - cerr << "LADSPA Plugin ID " << unique_id << " not found!" << endl; - } else { - - // Get plugin index - unsigned long plugin_index = m_IDLookup[unique_id]; - UnloadLibraryByPlugin(plugin_index); + i->RefCount = 0; } } const LADSPA_Descriptor * -LADSPAInfo::GetDescriptorByID(unsigned long unique_id, - bool unload_previous_library) +LADSPAInfo::GetDescriptorByID(unsigned long unique_id) { if (m_IDLookup.find(unique_id) == m_IDLookup.end()) { cerr << "LADSPA Plugin ID " << unique_id << " not found!" << endl; @@ -148,20 +127,55 @@ LADSPAInfo::GetDescriptorByID(unsigned long unique_id, unsigned long plugin_index = m_IDLookup[unique_id]; PluginInfo *pi = &(m_Plugins[plugin_index]); + LibraryInfo *li = &(m_Libraries[pi->LibraryIndex]); + if (!(pi->Descriptor)) { LADSPA_Descriptor_Function desc_func = GetDescriptorFunctionForLibrary(pi->LibraryIndex); - if (desc_func) { - pi->Descriptor = desc_func(pi->Index); + if (desc_func) pi->Descriptor = desc_func(pi->Index); + } + + if (pi->Descriptor) { + // Success, so increment ref counter for library + li->RefCount++; + } + + return pi->Descriptor; +} + +void +LADSPAInfo::DiscardDescriptorByID(unsigned long unique_id) +{ + if (m_IDLookup.find(unique_id) == m_IDLookup.end()) { + cerr << "LADSPA Plugin ID " << unique_id << " not found!" << endl; + } else { + + // Get plugin index + unsigned long plugin_index = m_IDLookup[unique_id]; - // Unload previously loaded library (if different) - if ((m_LastLoadedLibraryIndex != m_Libraries.size()) && - (m_LastLoadedLibraryIndex != pi->LibraryIndex)) { - UnloadLibraryByPlugin(plugin_index); + PluginInfo *pi = &(m_Plugins[plugin_index]); + LibraryInfo *li = &(m_Libraries[pi->LibraryIndex]); + + // Decrement reference counter for library, and unload if last + if (li->RefCount > 0) { + li->RefCount--; + if (li->RefCount == 0) { + dlclose(li->Handle); + // Need to unset all plugin descriptors that may have been + // set from this library + // Plugins in library will be a contiguous block, so we + // just check each direction from given plugin + unsigned long i = plugin_index - 1; + while (m_Plugins[i].LibraryIndex == pi->LibraryIndex) { + m_Plugins[i--].Descriptor = NULL; + } + i = plugin_index + 1; + while (m_Plugins[i].LibraryIndex == pi->LibraryIndex) { + m_Plugins[i++].Descriptor = NULL; + } } } } - return pi->Descriptor; } unsigned long @@ -503,25 +517,3 @@ LADSPAInfo::GetDescriptorFunctionForLibrary(unsigned long library_index) return desc_func; } - -void -LADSPAInfo::UnloadLibraryByPlugin(unsigned long plugin_index) -{ -// Unload library corresponding to given plugin index - PluginInfo *pi = &(m_Plugins[plugin_index]); - LibraryInfo *li = &(m_Libraries[pi->LibraryIndex]); - if (li->Handle) dlclose(li->Handle); - -// Need to unset all plugin descriptors that may have been -// set from this library -// Plugins in library will be a contiguous block, so we -// just check each direction from given plugin - unsigned long i = plugin_index - 1; - while (m_Plugins[i].LibraryIndex == pi->LibraryIndex) { - m_Plugins[i--].Descriptor = NULL; - } - i = plugin_index + 1; - while (m_Plugins[i].LibraryIndex == pi->LibraryIndex) { - m_Plugins[i++].Descriptor = NULL; - } -} diff --git a/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.h b/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.h index 435cbde..6ff0a3b 100644 --- a/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.h +++ b/SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.h @@ -38,22 +38,36 @@ public: // Unload all loaded plugins and clean up ~LADSPAInfo(); - // Rescan all paths in $LADSPA_PATH, as per constructor - // This will also unload all libraries + // ************************************************************************ + // Loading/Unloading plugin libraries + // + // At first, no library dlls are loaded. + // + // Each library has an associated reference count, which is initially 0. + // As descriptors are requested, using GetDescriptorByID, this count + // is incremented. The library dll is loaded on the first request. + // At descriptors are discarded, the count is decremented, and when this + // reaches 0, the library is unloaded. + + // Rescan all paths in $LADSPA_PATH, as per constructor. + // This will also unload all libraries, and make any descriptors that + // have not been discarded with DiscardDescriptorByID invalid. void RescanPlugins(void); - // Unload all dlopened libraries + // Unload all dlopened libraries. This will make any descriptors that + // have not been discarded with DiscardDescriptorByID invalid. void UnloadAllLibraries(void); - // Unload library containing plugin id - void UnloadLibraryByID(unsigned long unique_id); + // Get descriptor of plugin with given ID. This increments the descriptor + // count for the corresponding library. + const LADSPA_Descriptor *GetDescriptorByID(unsigned long unique_id); - // Get descriptor of plugin in list, loading library if necessary - // and optionally unloading previously loaded library (if different - // from library containing requested plugin. Phew!) - const LADSPA_Descriptor *GetDescriptorByID(unsigned long unique_id, - bool unload_previous_library); + // Notify that a descriptor corresponding to the given ID has been + // discarded. This decrements the descriptor count for the corresponding + // library. + void DiscardDescriptorByID(unsigned long unique_id); + // Get unique ID of plugin identified by given library filename and label. unsigned long GetIDFromFilenameAndLabel(std::string filename, std::string label); @@ -81,12 +95,12 @@ private: void ExaminePath(const char *path); bool CheckPlugin(LADSPA_Descriptor_Function desc_func); LADSPA_Descriptor_Function GetDescriptorFunctionForLibrary(unsigned long library_index); - void UnloadLibraryByPlugin(unsigned long plugin_index); struct LibraryInfo { unsigned long PathIndex; // Index of path in m_Paths std::string Basename; // Filename + unsigned long RefCount; // Count of descriptors requested from library void *Handle; // DLL Handle, NULL }; @@ -121,9 +135,6 @@ private: std::vector m_Libraries; std::vector m_Plugins; - unsigned long m_LastLoadedLibraryIndex; - unsigned long m_LastLoadedPluginIndex; - IDMap m_IDLookup; StringMap m_FilenameLookup; diff --git a/SpiralSound/Plugins/LADSPAPlugin/LADSPAPlugin.C b/SpiralSound/Plugins/LADSPAPlugin/LADSPAPlugin.C index aebc5cc..a991532 100644 --- a/SpiralSound/Plugins/LADSPAPlugin/LADSPAPlugin.C +++ b/SpiralSound/Plugins/LADSPAPlugin/LADSPAPlugin.C @@ -767,13 +767,13 @@ bool LADSPAPlugin::SelectPlugin(unsigned long UniqueID) // Reject trivial case if (UniqueID == 0) return false; - m_PlugDesc = m_LADSPAInfo->GetDescriptorByID(UniqueID, true); + m_PlugDesc = m_LADSPAInfo->GetDescriptorByID(UniqueID); if (m_PlugDesc) { // Create instance if (!(m_PlugInstHandle = m_PlugDesc->instantiate(m_PlugDesc, m_HostInfo->SAMPLERATE))) { cerr << "WARNING: Could not instantiate plugin " << UniqueID << endl; - m_LADSPAInfo->UnloadLibraryByID(UniqueID); + m_LADSPAInfo->DiscardDescriptorByID(UniqueID); m_PlugDesc = 0; return false; } @@ -884,6 +884,8 @@ void LADSPAPlugin::ClearPlugin(void) if (m_PlugDesc->deactivate) m_PlugDesc->deactivate(m_PlugInstHandle); m_PlugDesc->cleanup(m_PlugInstHandle); m_PlugDesc = NULL; + + m_LADSPAInfo->DiscardDescriptorByID(m_UniqueID); } m_TabIndex = 1;