start of new crossthread-safe design
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 16 Nov 2006 03:18:30 +0000 (03:18 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 16 Nov 2006 03:18:30 +0000 (03:18 +0000)
git-svn-id: svn://localhost/ardour2/trunk@1133 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/gui_thread.h
libs/gtkmm2ext/gtkmm2ext/gtk_ui.h
libs/pbd/pbd/crossthread.h [new file with mode: 0644]

index 22381e353625174f66260dc1cb7bed3c2eb96320..1f53f9700474257ca371b55745d751161dc8ac1f 100644 (file)
@@ -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__ */
index 14af137680577d4cf3508277c01a33c5aae0a67a..a692e64c9c36df5e817b958d18c082fb8f0635e1 100644 (file)
@@ -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 (file)
index 0000000..413dea0
--- /dev/null
@@ -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__ */