X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fcontrol_protocol_manager.cc;h=7423d3b5c6a4c82ac464b1fd2d4b26c56d254369;hb=da087e920b32d2b55044e337becff9f15524c060;hp=8b137843dd6864435db38f9fefa5f924034b15b1;hpb=4dc63966f0872efe768dad61eb9b8785d06b92d1;p=ardour.git diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc index 8b137843dd..7423d3b5c6 100644 --- a/libs/ardour/control_protocol_manager.cc +++ b/libs/ardour/control_protocol_manager.cc @@ -22,6 +22,7 @@ #include #include "pbd/compose.h" +#include "pbd/event_loop.h" #include "pbd/file_utils.h" #include "pbd/error.h" @@ -113,7 +114,7 @@ ControlProtocolManager::activate (ControlProtocolInfo& cpi) cp->set_active (true); return 0; -} +} int ControlProtocolManager::deactivate (ControlProtocolInfo& cpi) @@ -137,15 +138,15 @@ ControlProtocolManager::drop_protocols () /* called explicitly by Session::destroy() so that we can clean up * before the process cycle stops and ports vanish. */ - + Glib::Threads::Mutex::Lock lm (protocols_lock); - + for (list::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) { delete *p; } - + control_protocols.clear (); - + for (list::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) { // mark existing protocols as requested // otherwise the ControlProtocol instances are not recreated in set_session @@ -154,7 +155,7 @@ ControlProtocolManager::drop_protocols () (*p)->protocol = 0; } } -} +} ControlProtocol* ControlProtocolManager::instantiate (ControlProtocolInfo& cpi) @@ -192,6 +193,18 @@ int ControlProtocolManager::teardown (ControlProtocolInfo& cpi) { if (!cpi.protocol) { + + /* we could still have a descriptor even if the protocol was + never instantiated. Close the associated module (shared + object/DLL) and make sure we forget about it. + */ + + if (cpi.descriptor) { + cerr << "Closing descriptor for CPI anyway\n"; + delete (Glib::Module*) cpi.descriptor->module; + cpi.descriptor = 0; + } + return 0; } @@ -202,7 +215,7 @@ ControlProtocolManager::teardown (ControlProtocolInfo& cpi) if (cpi.mandatory) { return 0; } - + /* save current state */ delete cpi.state; @@ -222,9 +235,15 @@ ControlProtocolManager::teardown (ControlProtocolInfo& cpi) } cpi.protocol = 0; + delete cpi.state; cpi.state = 0; - delete (Glib::Module*)cpi.descriptor->module; + delete (Glib::Module*) cpi.descriptor->module; + /* cpi->descriptor is now inaccessible since dlclose() or equivalent + * has been performed, and the descriptor is (or could be) a static + * object made accessible by dlopen(). + */ + cpi.descriptor = 0; ProtocolStatusChange (&cpi); @@ -288,7 +307,7 @@ ControlProtocolManager::discover_control_protocols () DEBUG_TRACE (DEBUG::ControlProtocols, string_compose (_("looking for control protocols in %1\n"), control_protocol_search_path().to_string())); - + for (vector::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) { control_protocol_discover (*i); } @@ -331,8 +350,6 @@ ControlProtocolManager::control_protocol_discover (string path) DEBUG_TRACE (DEBUG::ControlProtocols, string_compose(_("Control surface protocol discovered: \"%1\"\n"), cpi->name)); } - - delete (Glib::Module*)descriptor->module; } return 0; @@ -364,8 +381,6 @@ ControlProtocolManager::get_descriptor (string path) if (descriptor) { descriptor->module = (void*)module; - } else { - delete module; } return descriptor; @@ -409,16 +424,16 @@ ControlProtocolManager::set_state (const XMLNode& node, int /*version*/) } bool active = string_is_affirmative (prop->value()); - + if ((prop = (*citer)->property (X_("name"))) == 0) { continue; } ControlProtocolInfo* cpi = cpi_by_name (prop->value()); - + if (cpi) { cpi->state = new XMLNode (**citer); - + if (active) { if (_session) { instantiate (*cpi); @@ -487,3 +502,21 @@ ControlProtocolManager::midi_connectivity_established () (*p)->midi_connectivity_established (); } } + +void +ControlProtocolManager::register_request_buffer_factories () +{ + Glib::Threads::Mutex::Lock lm (protocols_lock); + + for (list::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) { + + if ((*i)->descriptor == 0) { + warning << string_compose (_("Control protocol \"%1\" has no descriptor"), (*i)->name) << endmsg; + continue; + } + + if ((*i)->descriptor->request_buffer_factory) { + EventLoop::register_request_buffer_factory ((*i)->descriptor->name, (*i)->descriptor->request_buffer_factory); + } + } +}