explicitly drop control surface protocols before disconnecting from engine.

This is not bomb/thread proof yet, because it still requires at least one process callback to function
This commit is contained in:
Paul Davis 2015-10-02 19:22:16 -04:00
parent fd4a34251c
commit 3bc7f863ca
3 changed files with 35 additions and 19 deletions

View File

@ -64,8 +64,9 @@ class LIBARDOUR_API ControlProtocolManager : public PBD::Stateful, public ARDOUR
void foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)>);
void load_mandatory_protocols ();
void midi_connectivity_established ();
int activate (ControlProtocolInfo&);
void drop_protocols ();
int activate (ControlProtocolInfo&);
int deactivate (ControlProtocolInfo&);
std::list<ControlProtocolInfo*> control_protocol_info;

View File

@ -126,26 +126,35 @@ void
ControlProtocolManager::session_going_away()
{
SessionHandlePtr::session_going_away ();
/* Session::destroy() will explicitly call drop_protocols() so we don't
* have to worry about that here.
*/
}
{
Glib::Threads::Mutex::Lock lm (protocols_lock);
for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
delete *p;
}
control_protocols.clear ();
for (list<ControlProtocolInfo*>::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
if ((*p)->protocol) {
(*p)->requested = true;
(*p)->protocol = 0;
}
void
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<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
delete *p;
}
control_protocols.clear ();
for (list<ControlProtocolInfo*>::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
if ((*p)->protocol) {
(*p)->requested = true;
(*p)->protocol = 0;
}
}
}
}
ControlProtocol*
ControlProtocolManager::instantiate (ControlProtocolInfo& cpi)

View File

@ -551,6 +551,12 @@ Session::destroy ()
drop_connections ();
/* shutdown control surface protocols while we still have ports
and the engine to move data to any devices.
*/
ControlProtocolManager::instance().drop_protocols ();
_engine.remove_session ();
#ifdef USE_TRACKS_CODE_FEATURES