diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/graph.h | 12 | ||||
-rw-r--r-- | libs/ardour/graph.cc | 49 | ||||
-rw-r--r-- | libs/ardour/session_process.cc | 2 | ||||
-rw-r--r-- | libs/gtkmm2ext/gtkapplication_quartz.mm | 4 | ||||
-rw-r--r-- | libs/pbd/pbd/semutils.h | 46 | ||||
-rw-r--r-- | libs/pbd/semutils.cc | 49 | ||||
-rw-r--r-- | libs/pbd/wscript | 1 |
7 files changed, 137 insertions, 26 deletions
diff --git a/libs/ardour/ardour/graph.h b/libs/ardour/ardour/graph.h index 56267672b7..bb51c99237 100644 --- a/libs/ardour/ardour/graph.h +++ b/libs/ardour/ardour/graph.h @@ -32,7 +32,8 @@ #include <cassert> #include <pthread.h> -#include <semaphore.h> + +#include "pbd/semutils.h" #include "ardour/types.h" #include "ardour/session_handle.h" @@ -97,10 +98,11 @@ class Graph : public SessionHandleRef std::vector<GraphNode *> _trigger_queue; pthread_mutex_t _trigger_mutex; - sem_t _execution_sem; - sem_t _callback_start_sem; - sem_t _callback_done_sem; - sem_t _cleanup_sem; + PBD::ProcessSemaphore _execution_sem; + + PBD::ProcessSemaphore _callback_start_sem; + PBD::ProcessSemaphore _callback_done_sem; + PBD::ProcessSemaphore _cleanup_sem; volatile gint _execution_tokens; volatile gint _finished_refcount; diff --git a/libs/ardour/graph.cc b/libs/ardour/graph.cc index 6c31c9903c..d98c3619dc 100644 --- a/libs/ardour/graph.cc +++ b/libs/ardour/graph.cc @@ -42,13 +42,12 @@ using namespace std; Graph::Graph (Session & session) : SessionHandleRef (session) + , _execution_sem ("graph_execution", 0) + , _callback_start_sem ("graph_start", 0) + , _callback_done_sem ("graph_done", 0) + , _cleanup_sem ("graph_cleanup", 0) { pthread_mutex_init( &_trigger_mutex, NULL); - sem_init( &_execution_sem, 0, 0 ); - - sem_init( &_callback_start_sem, 0, 0 ); - sem_init( &_callback_done_sem, 0, 0 ); - sem_init( &_cleanup_sem, 0, 0 ); _execution_tokens = 0; @@ -101,10 +100,10 @@ Graph::session_going_away() _quit_threads = true; for (unsigned int i=0; i<_thread_list.size(); i++) { - sem_post( &_execution_sem); + _execution_sem.signal (); } - sem_post( &_callback_start_sem); + _callback_start_sem.signal (); for (list<pthread_t>::iterator i = _thread_list.begin(); i != _thread_list.end(); i++) { void* status; @@ -201,10 +200,10 @@ Graph::restart_cycle() // we are through. wakeup our caller. again: - sem_post( &_callback_done_sem); + _callback_done_sem.signal (); // block until we are triggered. - sem_wait( &_callback_start_sem); + _callback_start_sem.wait(); if (_quit_threads) return; @@ -330,14 +329,14 @@ Graph::run_one() _execution_tokens -= wakeup; for (int i=0; i<wakeup; i++ ) { - sem_post (&_execution_sem); + _execution_sem.signal (); } while (to_run == 0) { _execution_tokens += 1; pthread_mutex_unlock (&_trigger_mutex); DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 goes to sleep\n", pthread_self())); - sem_wait (&_execution_sem); + _execution_sem.signal (); if (_quit_threads) return true; DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 is awake\n", pthread_self())); @@ -399,16 +398,17 @@ Graph::main_thread() get_rt(); again: - sem_wait (&_callback_start_sem); - + _callback_start_sem.wait (); + DEBUG_TRACE(DEBUG::Graph, "main thread is awake\n"); this->prep(); if (_graph_empty && !_quit_threads) { - sem_post (&_callback_done_sem); + _callback_done_sem.signal (); goto again; } while (1) { + DEBUG_TRACE(DEBUG::Graph, "main thread runs one graph node\n"); if (run_one()) { break; } @@ -460,8 +460,9 @@ Graph::silent_process_routes (nframes_t nframes, framepos_t start_frame, framepo _process_need_butler = false; if (!_graph_empty) { - sem_post (&_callback_start_sem); - sem_wait (&_callback_done_sem); + DEBUG_TRACE(DEBUG::Graph, "wake graph for silent process\n"); + _callback_start_sem.signal (); + _callback_done_sem.wait (); } need_butler = _process_need_butler; @@ -473,6 +474,8 @@ int Graph::process_routes (nframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick, bool can_record, bool rec_monitors_input, bool& need_butler) { + DEBUG_TRACE (DEBUG::Graph, string_compose ("graph execution from %1 to %2 = %3\n", start_frame, end_frame, nframes)); + _process_nframes = nframes; _process_start_frame = start_frame; _process_end_frame = end_frame; @@ -485,8 +488,11 @@ Graph::process_routes (nframes_t nframes, framepos_t start_frame, framepos_t end _process_retval = 0; _process_need_butler = false; - sem_post (&_callback_start_sem); - sem_wait (&_callback_done_sem); + DEBUG_TRACE(DEBUG::Graph, "wake graph for non-silent process\n"); + _callback_start_sem.signal (); + _callback_done_sem.wait (); + + DEBUG_TRACE (DEBUG::Graph, "graph execution complete\n"); need_butler = _process_need_butler; @@ -497,6 +503,8 @@ int Graph::routes_no_roll (nframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool non_rt_pending, bool can_record, int declick) { + DEBUG_TRACE (DEBUG::Graph, string_compose ("no-roll graph execution from %1 to %2 = %3\n", start_frame, end_frame, nframes)); + _process_nframes = nframes; _process_start_frame = start_frame; _process_end_frame = end_frame; @@ -509,8 +517,9 @@ Graph::routes_no_roll (nframes_t nframes, framepos_t start_frame, framepos_t end _process_retval = 0; _process_need_butler = false; - sem_post (&_callback_start_sem); - sem_wait (&_callback_done_sem); + DEBUG_TRACE(DEBUG::Graph, "wake graph for no-roll process\n"); + _callback_start_sem.signal (); + _callback_done_sem.wait (); return _process_retval; } diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index b18e00f9fd..7f88642b12 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -106,6 +106,7 @@ Session::no_roll (nframes_t nframes) _click_io->silence (nframes); } + DEBUG_TRACE(DEBUG::Graph,"calling graph/no-roll\n"); route_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), actively_recording(), declick); /* for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { @@ -146,6 +147,7 @@ Session::process_routes (nframes_t nframes, bool& need_butler) const nframes_t start_frame = _transport_frame; const nframes_t end_frame = _transport_frame + (nframes_t)floor(nframes * _transport_speed); + DEBUG_TRACE(DEBUG::Graph,"calling graph/process-routes\n"); route_graph->process_routes( nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler); /* for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { diff --git a/libs/gtkmm2ext/gtkapplication_quartz.mm b/libs/gtkmm2ext/gtkapplication_quartz.mm index f244bd9eb0..694bfedd50 100644 --- a/libs/gtkmm2ext/gtkapplication_quartz.mm +++ b/libs/gtkmm2ext/gtkapplication_quartz.mm @@ -804,7 +804,9 @@ cocoa_menu_item_update_accelerator (NSMenuItem *cocoa_item, is still done by GTK, so this is more cosmetic than it may appear. */ - + + get_menu_label_text (widget, &label); + if (GTK_IS_ACCEL_LABEL (label) && GTK_ACCEL_LABEL (label)->accel_closure) { diff --git a/libs/pbd/pbd/semutils.h b/libs/pbd/pbd/semutils.h new file mode 100644 index 0000000000..1d4a7eb838 --- /dev/null +++ b/libs/pbd/pbd/semutils.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2010 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __pbd_semutils_h__ +#define __pbd_semutils_h__ + +#include <semaphore.h> + +namespace PBD { + +class ProcessSemaphore { + private: +#ifdef __APPLE__ + sem_t* _sem; + sem_t* ptr_to_sem() const { return _sem; } +#else + sem_t _sem; + sem_t* ptr_to_sem() const { return &_sem; } +#endif + + public: + ProcessSemaphore (const char* name, int val); + ~ProcessSemaphore (); + + int signal () { return sem_post (ptr_to_sem()); } + int wait () { return sem_wait (ptr_to_sem()); } +}; + +} + +#endif /* __pbd_semutils_h__ */ diff --git a/libs/pbd/semutils.cc b/libs/pbd/semutils.cc new file mode 100644 index 0000000000..b07b791fd0 --- /dev/null +++ b/libs/pbd/semutils.cc @@ -0,0 +1,49 @@ +/* + Copyright (C) 2010 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "pbd/semutils.h" +#include "pbd/failed_constructor.h" + +using namespace PBD; + +ProcessSemaphore::ProcessSemaphore (const char* name, int val) +{ +#ifdef __APPLE__ + if ((_sem = sem_open (name, O_CREAT, 0600, val)) == (sem_t*) SEM_FAILED) { + throw failed_constructor (); + } + + /* this semaphore does not exist for IPC */ + + if (sem_unlink (name)) { + throw failed_constructor (); + } + +#else + if (sem_init (&sem, 0, val)) { + throw failed_constructor (); + } +#endif +} + +ProcessSemaphore::~ProcessSemaphore () +{ +#ifdef __APPLE__ + sem_close (ptr_to_sem()); +#endif +} diff --git a/libs/pbd/wscript b/libs/pbd/wscript index e707be68df..854aaa2642 100644 --- a/libs/pbd/wscript +++ b/libs/pbd/wscript @@ -87,6 +87,7 @@ def build(bld): pthread_utils.cc receiver.cc search_path.cc + semutils.cc shortpath.cc signals.cc sndfile_manager.cc |