summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/gui_thread.h5
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/gtk_ui.h2
-rw-r--r--libs/pbd/pbd/crossthread.h38
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__ */