summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-05-12 19:15:07 +0000
committerDavid Robillard <d@drobilla.net>2009-05-12 19:15:07 +0000
commitddc09de45b45bdf2afdeff68eb8a17ad237ef6c3 (patch)
treed71c279860fb016e79be2fb7ea1ba3fa66e6babd
parent61e8765a7b9afda01eb52b5a240701849fd9e116 (diff)
downloadpatchage-ddc09de45b45bdf2afdeff68eb8a17ad237ef6c3.tar.gz
patchage-ddc09de45b45bdf2afdeff68eb8a17ad237ef6c3.tar.bz2
patchage-ddc09de45b45bdf2afdeff68eb8a17ad237ef6c3.zip
Fix threading issues on Jack exit.
git-svn-id: http://svn.drobilla.net/lad/trunk/patchage@1988 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/AlsaDriver.hpp2
-rw-r--r--src/Driver.hpp3
-rw-r--r--src/JackDriver.cpp17
-rw-r--r--src/JackDriver.hpp2
-rw-r--r--src/Patchage.cpp12
-rw-r--r--src/Patchage.hpp4
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<PatchagePort> 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<PatchagePort> 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<PatchageModule> 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<JackDriver*>(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;