diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2006-11-16 03:18:30 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2006-11-16 03:18:30 +0000 |
commit | 7bbf76132164d3bd293c3bfdf2038dd47f1cc63b (patch) | |
tree | b0ff92173f83b13d9aa395d50f63b72cdfea0be1 | |
parent | 3f207b1e4f6ef356a45fb3648de36e17c5e91d73 (diff) |
start of new crossthread-safe design
git-svn-id: svn://localhost/ardour2/trunk@1133 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/gui_thread.h | 5 | ||||
-rw-r--r-- | libs/gtkmm2ext/gtkmm2ext/gtk_ui.h | 2 | ||||
-rw-r--r-- | libs/pbd/pbd/crossthread.h | 38 |
3 files changed, 45 insertions, 0 deletions
diff --git a/gtk2_ardour/gui_thread.h b/gtk2_ardour/gui_thread.h index 22381e3536..1f53f97004 100644 --- a/gtk2_ardour/gui_thread.h +++ b/gtk2_ardour/gui_thread.h @@ -2,6 +2,7 @@ #define __ardour_gtk_gui_thread_h__ #include <gtkmm2ext/gtk_ui.h> +#include <pbd/crossthread.h> #define ENSURE_GUI_THREAD(slot) \ if (!Gtkmm2ext::UI::instance()->caller_is_ui_thread()) {\ @@ -9,4 +10,8 @@ return;\ } +#define GTK_SAFE(theSlot) crossthread_safe (Gtkmm2ext::UI::instance()->thread_id(),\ + *Gtkmm2ext::UI::instance(), \ + (theSlot)) + #endif /* __ardour_gtk_gui_thread_h__ */ diff --git a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h index 14af137680..a692e64c9c 100644 --- a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h +++ b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h @@ -101,6 +101,8 @@ class UI : public Receiver, public AbstractUI<UIRequest> bool caller_is_ui_thread (); + static pthread_t thread_id() { return gui_thread; } + /* Gtk-UI specific interfaces */ bool running (); diff --git a/libs/pbd/pbd/crossthread.h b/libs/pbd/pbd/crossthread.h new file mode 100644 index 0000000000..413dea024e --- /dev/null +++ b/libs/pbd/pbd/crossthread.h @@ -0,0 +1,38 @@ +#ifndef __pbd__crossthread_h__ +#define __pbd__crossthread_h__ + +#include <pbd/abstract_ui.h> +#include <sigc++/sigc++.h> +#include <pthread.h> + +template<class RequestType> +void +call_slot_from_thread_or_dispatch_it (pthread_t thread_id, AbstractUI<RequestType>& ui, sigc::slot<void> theSlot) +{ + /* when called, this function will determine whether the calling thread + is the same as thread specified by the first argument. if it is, + the we execute the slot. if not, we ask the interface given by the second + argument to call the slot. + */ + + if (pthread_self() == thread_id) { + theSlot (); + } else { + ui.call_slot (theSlot); + } +} + +template<class RequestType> +sigc::slot<void> +crossthread_safe (pthread_t thread_id, AbstractUI<RequestType>& ui, sigc::slot<void> theSlot) +{ + /* this function returns a slot that will ensure that theSlot is either + called by the specified thread or passed to the interface via + AbstractUI::call_slot(). + */ + + return sigc::bind (sigc::ptr_fun (call_slot_from_thread_or_dispatch_it<RequestType>), + thread_id, ui, theSlot); +} + +#endif /* __pbd__crossthread_h__ */ |