From 7bbf76132164d3bd293c3bfdf2038dd47f1cc63b Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 16 Nov 2006 03:18:30 +0000 Subject: [PATCH] start of new crossthread-safe design git-svn-id: svn://localhost/ardour2/trunk@1133 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/gui_thread.h | 5 ++++ libs/gtkmm2ext/gtkmm2ext/gtk_ui.h | 2 ++ libs/pbd/pbd/crossthread.h | 38 +++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 libs/pbd/pbd/crossthread.h 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 +#include #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 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 +#include +#include + +template +void +call_slot_from_thread_or_dispatch_it (pthread_t thread_id, AbstractUI& ui, sigc::slot 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 +sigc::slot +crossthread_safe (pthread_t thread_id, AbstractUI& ui, sigc::slot 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), + thread_id, ui, theSlot); +} + +#endif /* __pbd__crossthread_h__ */ -- 2.30.2