From 9f2ab81df6709d7b5d5701abbedc63d39e7330ab Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 11 Sep 2013 21:00:21 -0400 Subject: always add a timeout value of 200msec to jack, just like qjackctl does. THIS IS A HACK. LONG TERM GOAL: understand why ardour gets zombified on the way up. --- libs/backends/jack/jack_utils.cc | 7 ++++++- libs/backends/jack/jack_utils.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libs/backends/jack/jack_utils.cc b/libs/backends/jack/jack_utils.cc index 77f3d95aa1..93fc3d440a 100644 --- a/libs/backends/jack/jack_utils.cc +++ b/libs/backends/jack/jack_utils.cc @@ -682,7 +682,7 @@ ARDOUR::JackCommandLineOptions::JackCommandLineOptions () } bool -ARDOUR::get_jack_command_line_string (const JackCommandLineOptions& options, string& command_line) +ARDOUR::get_jack_command_line_string (JackCommandLineOptions& options, string& command_line) { vector args; @@ -699,6 +699,11 @@ ARDOUR::get_jack_command_line_string (const JackCommandLineOptions& options, str } #endif + /* XXX hack to enforce qjackctl-like behaviour */ + if (options.timeout == 0) { + options.timeout = 200; + } + if (options.timeout) { args.push_back ("-t"); args.push_back (to_string (options.timeout, std::dec)); diff --git a/libs/backends/jack/jack_utils.h b/libs/backends/jack/jack_utils.h index 7565353198..a7521ad1c4 100644 --- a/libs/backends/jack/jack_utils.h +++ b/libs/backends/jack/jack_utils.h @@ -231,5 +231,5 @@ namespace ARDOUR { /** * @return true if able to build a valid command line based on options */ - bool get_jack_command_line_string (const JackCommandLineOptions& options, std::string& command_line); + bool get_jack_command_line_string (JackCommandLineOptions& options, std::string& command_line); } -- cgit v1.2.3 From 4df3666738607039445ebc9fa083bf5c23ac5539 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 12 Sep 2013 11:29:47 -0400 Subject: add AudioBackendNativeThread to serve the same role as jack_native_thread_t --- libs/ardour/ardour/audio_backend.h | 8 +++++++- libs/ardour/ardour/audioengine.h | 3 ++- libs/ardour/ardour/graph.h | 3 ++- libs/ardour/ardour/types.h | 11 +++++++++++ libs/ardour/audioengine.cc | 10 +++++++++- libs/ardour/graph.cc | 11 +++++------ libs/backends/jack/jack_audiobackend.cc | 8 ++++++++ libs/backends/jack/jack_audiobackend.h | 3 ++- 8 files changed, 46 insertions(+), 11 deletions(-) diff --git a/libs/ardour/ardour/audio_backend.h b/libs/ardour/ardour/audio_backend.h index ab37bea526..6c4a54da3e 100644 --- a/libs/ardour/ardour/audio_backend.h +++ b/libs/ardour/ardour/audio_backend.h @@ -399,7 +399,13 @@ class AudioBackend { * stacksize. The thread will begin executing @param func, and will exit * when that function returns. */ - virtual int create_process_thread (boost::function func, pthread_t*, size_t stacksize) = 0; + virtual int create_process_thread (boost::function func, AudioBackendNativeThread*, size_t stacksize) = 0; + + /** Wait for the thread specified by @param thread to exit. + * + * Return zero on success, non-zero on failure. + */ + virtual int wait_for_process_thread_exit (AudioBackendNativeThread thread) = 0; virtual void update_latencies () = 0; diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index cf4f91d4d0..21206da8fc 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -100,7 +100,8 @@ public: pframes_t sample_time_at_cycle_start (); pframes_t samples_since_cycle_start (); bool get_sync_offset (pframes_t& offset) const; - int create_process_thread (boost::function func, pthread_t*, size_t stacksize); + int create_process_thread (boost::function func, AudioBackendNativeThread*, size_t stacksize); + int wait_for_process_thread_exit (AudioBackendNativeThread); bool is_realtime() const; bool connected() const; diff --git a/libs/ardour/ardour/graph.h b/libs/ardour/ardour/graph.h index cac09d34af..08af6fb721 100644 --- a/libs/ardour/ardour/graph.h +++ b/libs/ardour/ardour/graph.h @@ -36,6 +36,7 @@ #include "pbd/semutils.h" #include "ardour/types.h" +#include "ardour/audio_backend.h" #include "ardour/session_handle.h" namespace ARDOUR @@ -92,7 +93,7 @@ protected: virtual void session_going_away (); private: - std::list _thread_list; + std::list _thread_list; volatile bool _quit_threads; void reset_thread_list (); diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 17bffc20e4..f2319d7669 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -609,6 +610,16 @@ namespace ARDOUR { uint32_t max; //< samples }; +/* PLATFORM SPECIFIC #ifdef's here */ + + /** Define the native thread type used on the platform */ + typedef pthread_t AudioBackendNativeThread; + static inline bool self_thread_equal (AudioBackendNativeThread thr) { + return pthread_equal (thr, pthread_self()); + } + +/* PLATFORM SPECIFIC #endif's here */ + } // namespace ARDOUR diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 329de68bee..ba5b5ad525 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -816,7 +816,7 @@ AudioEngine::get_sync_offset (pframes_t& offset) const } int -AudioEngine::create_process_thread (boost::function func, pthread_t* thr, size_t stacksize) +AudioEngine::create_process_thread (boost::function func, AudioBackendNativeThread* thr, size_t stacksize) { if (!_backend) { return -1; @@ -824,6 +824,14 @@ AudioEngine::create_process_thread (boost::function func, pthread_t* thr return _backend->create_process_thread (func, thr, stacksize); } +int +AudioEngine::wait_for_process_thread_exit (AudioBackendNativeThread thr) +{ + if (!_backend) { + return 0; + } + return _backend->wait_for_process_thread_exit (thr); +} int AudioEngine::set_device_name (const std::string& name) diff --git a/libs/ardour/graph.cc b/libs/ardour/graph.cc index cb0fa1b21a..c8e374cddc 100644 --- a/libs/ardour/graph.cc +++ b/libs/ardour/graph.cc @@ -101,7 +101,7 @@ Graph::reset_thread_list () } Glib::Threads::Mutex::Lock lm (_session.engine().process_lock()); - pthread_t a_thread; + AudioBackendNativeThread a_thread; if (!_thread_list.empty()) { drop_threads (); @@ -146,9 +146,8 @@ Graph::drop_threads () _callback_start_sem.signal (); - for (list::iterator i = _thread_list.begin(); i != _thread_list.end(); ++i) { - void* status; - pthread_join (*i, &status); + for (list::iterator i = _thread_list.begin(); i != _thread_list.end(); ++i) { + AudioEngine::instance()->wait_for_process_thread_exit (*i); } _thread_list.clear (); @@ -584,8 +583,8 @@ Graph::process_one_route (Route* route) bool Graph::in_process_thread () const { - for (list::const_iterator i = _thread_list.begin (); i != _thread_list.end(); ++i) { - if (*i == pthread_self()) { + for (list::const_iterator i = _thread_list.begin (); i != _thread_list.end(); ++i) { + if (self_thread_equal (*i)) { return true; } } diff --git a/libs/backends/jack/jack_audiobackend.cc b/libs/backends/jack/jack_audiobackend.cc index e004849896..89a93a76f6 100644 --- a/libs/backends/jack/jack_audiobackend.cc +++ b/libs/backends/jack/jack_audiobackend.cc @@ -789,6 +789,14 @@ JACKAudioBackend::create_process_thread (boost::function f, pthread_t* t return 0; } +int +JACKAudioBackend::wait_for_process_thread_exit (AudioBackendNativeThread thr) +{ + void* status; + /* this doesn't actively try to stop the thread, it just waits till it exits */ + return pthread_join (thr, &status); +} + void* JACKAudioBackend::_start_process_thread (void* arg) { diff --git a/libs/backends/jack/jack_audiobackend.h b/libs/backends/jack/jack_audiobackend.h index 1389e15c4a..61f1bbb602 100644 --- a/libs/backends/jack/jack_audiobackend.h +++ b/libs/backends/jack/jack_audiobackend.h @@ -100,7 +100,8 @@ class JACKAudioBackend : public AudioBackend { size_t raw_buffer_size (DataType t); - int create_process_thread (boost::function func, pthread_t*, size_t stacksize); + int create_process_thread (boost::function func, AudioBackendNativeThread*, size_t stacksize); + int wait_for_process_thread_exit (AudioBackendNativeThread); void transport_start (); void transport_stop (); -- cgit v1.2.3