From ddc09de45b45bdf2afdeff68eb8a17ad237ef6c3 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 12 May 2009 19:15:07 +0000 Subject: Fix threading issues on Jack exit. git-svn-id: http://svn.drobilla.net/lad/trunk/patchage@1988 a436a847-0d15-0410-975c-d299462d15a1 --- src/AlsaDriver.hpp | 2 +- src/Driver.hpp | 3 ++- src/JackDriver.cpp | 17 ++++------------- src/JackDriver.hpp | 2 +- src/Patchage.cpp | 12 ++++++++++-- src/Patchage.hpp | 4 +++- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/AlsaDriver.hpp b/src/AlsaDriver.hpp index 51e2b57..38396f1 100644 --- a/src/AlsaDriver.hpp +++ b/src/AlsaDriver.hpp @@ -60,7 +60,7 @@ private: void add_connections(boost::shared_ptr port); - bool create_refresh_port(); + bool create_refresh_port(); static void* refresh_main(void* me); void _refresh_main(); diff --git a/src/Driver.hpp b/src/Driver.hpp index 6e759a5..4c9d313 100644 --- a/src/Driver.hpp +++ b/src/Driver.hpp @@ -43,7 +43,8 @@ public: virtual void detach() = 0; virtual bool is_attached() const = 0; - virtual void refresh() = 0; + virtual void refresh() = 0; + virtual void destroy_all() {} virtual boost::shared_ptr create_port_view( Patchage* patchage, diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp index 4077b1a..87ab1bf 100644 --- a/src/JackDriver.cpp +++ b/src/JackDriver.cpp @@ -99,14 +99,12 @@ JackDriver::attach(bool launch_daemon) void JackDriver::detach() { + Glib::Mutex::Lock lock(_shutdown_mutex); if (_client) { jack_deactivate(_client); jack_client_close(_client); - _shutdown_mutex.lock(); _client = NULL; - _shutdown_mutex.unlock(); } - destroy_all_ports(); _is_activated = false; signal_detached.emit(); _app->status_msg("[JACK] Detached"); @@ -116,7 +114,7 @@ JackDriver::detach() /** Destroy all JACK (canvas) ports. */ void -JackDriver::destroy_all_ports() +JackDriver::destroy_all() { ItemList modules = _app->canvas()->items(); // copy for (ItemList::iterator m = modules.begin(); m != modules.end(); ++m) { @@ -228,7 +226,6 @@ JackDriver::create_port(boost::shared_ptr parent, jack_port_t* p void JackDriver::shutdown() { - destroy_all_ports(); signal_detached.emit(); } @@ -245,10 +242,9 @@ JackDriver::refresh() // Jack can take _client away from us at any time throughout here :/ // Shortest locks possible is the best solution I can figure out - _shutdown_mutex.lock(); + Glib::Mutex::Lock lock(_shutdown_mutex); if (_client == NULL) { - _shutdown_mutex.unlock(); shutdown(); return; } @@ -256,7 +252,6 @@ JackDriver::refresh() ports = jack_get_ports(_client, NULL, NULL, 0); // get all existing ports if (!ports) { - _shutdown_mutex.unlock(); return; } @@ -356,8 +351,6 @@ JackDriver::refresh() } } - _shutdown_mutex.unlock(); - free(ports); } @@ -535,10 +528,8 @@ JackDriver::jack_shutdown_cb(void* jack_driver) cerr << "[JACK] Shutdown" << endl; assert(jack_driver); JackDriver* me = reinterpret_cast(jack_driver); - me->_shutdown_mutex.lock(); + Glib::Mutex::Lock lock(me->_shutdown_mutex); me->_client = NULL; - me->_shutdown_mutex.unlock(); - me->destroy_all_ports(); me->_is_activated = false; me->signal_detached.emit(); } diff --git a/src/JackDriver.hpp b/src/JackDriver.hpp index 698ed39..d987077 100644 --- a/src/JackDriver.hpp +++ b/src/JackDriver.hpp @@ -49,6 +49,7 @@ public: bool is_realtime() const { return _client && jack_is_realtime(_client); } void refresh(); + void destroy_all(); bool port_names(const PortID& id, std::string& module_name, @@ -96,7 +97,6 @@ private: static void error_cb(const char* msg); - void destroy_all_ports(); void shutdown(); static void jack_client_registration_cb(const char* name, int registered, void* me); diff --git a/src/Patchage.cpp b/src/Patchage.cpp index b00013b..eaa252d 100644 --- a/src/Patchage.cpp +++ b/src/Patchage.cpp @@ -102,6 +102,7 @@ Patchage::Patchage(int argc, char** argv) , _jack_driver(NULL) , _state_manager(NULL) , _attach(true) + , _driver_detached(false) , _refresh(false) , _enable_refresh(true) , INIT_WIDGET(_about_win) @@ -239,7 +240,7 @@ Patchage::Patchage(int argc, char** argv) #if defined(USE_LIBJACK) || defined(HAVE_JACK_DBUS) _jack_driver = new JackDriver(this); - _jack_driver->signal_detached.connect(sigc::mem_fun(this, &Patchage::queue_refresh)); + _jack_driver->signal_detached.connect(sigc::mem_fun(this, &Patchage::driver_detached)); _menu_jack_connect->signal_activate().connect(sigc::bind( sigc::mem_fun(_jack_driver, &JackDriver::attach), true)); @@ -340,8 +341,15 @@ Patchage::idle_callback() // Do a full refresh (ie user clicked refresh) if (_refresh) { refresh(); - _refresh = false; + } else if (_driver_detached) { + if (_jack_driver && !_jack_driver->is_attached()) + _jack_driver->destroy_all(); + if (_alsa_driver && !_alsa_driver->is_attached()) + _alsa_driver->destroy_all(); } + + _refresh = false; + _driver_detached = false; flush_resize(); update_load(); diff --git a/src/Patchage.hpp b/src/Patchage.hpp index a7b970f..4c3da57 100644 --- a/src/Patchage.hpp +++ b/src/Patchage.hpp @@ -68,7 +68,8 @@ public: void quit() { _main_win->hide(); } void refresh(); - inline void queue_refresh() { _refresh = true; } + inline void queue_refresh() { _refresh = true; } + inline void driver_detached() { _driver_detached = true; } void clear_load(); void info_msg(const std::string& msg); @@ -132,6 +133,7 @@ protected: std::string _settings_filename; bool _attach; + bool _driver_detached; bool _refresh; bool _enable_refresh; -- cgit v1.2.1