From f9b99e7eacd72ec2e65ab74b325b7f727ec222eb Mon Sep 17 00:00:00 2001 From: Miguel de Icaza Date: Sat, 17 Aug 2002 19:53:51 +0000 Subject: [PATCH] 2002-08-17 Miguel de Icaza * gtk/ThreadNotify.cs: New file, used to notify invoke code in the main Gtk thread. svn path=/trunk/gtk-sharp/; revision=6712 --- ChangeLog | 5 +++ gtk/ThreadNotify.cs | 89 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 gtk/ThreadNotify.cs diff --git a/ChangeLog b/ChangeLog index de98dfd7b..adcf0a1bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2002-08-17 Miguel de Icaza + + * gtk/ThreadNotify.cs: New file, used to notify invoke code in the + main Gtk thread. + 2002-08-17 Duncan Mak * gnome/CanvasProxy.cs: diff --git a/gtk/ThreadNotify.cs b/gtk/ThreadNotify.cs new file mode 100644 index 000000000..3301829e6 --- /dev/null +++ b/gtk/ThreadNotify.cs @@ -0,0 +1,89 @@ +// +// ThreadNotify.cs: implements a notification for the thread running the Gtk main +// loop from another thread +// +// Author: +// Miguel de Icaza (miguel@ximian.com). +// +// (C) 2002 Ximian, Inc. +// + +namespace Gtk { + using System.Runtime.InteropServices; + using System.Threading; + using System; + + // + // This delegate will be invoked on the main Gtk thread. + // + delegate void ReadyEvent (); + + /// + /// Utility class to help writting multi-threaded Gtk applications + /// + /// + /// + public class ThreadNotify { + + // + // DllImport functions from Gtk + // + [DllImport ("gtk-x11-2.0")] + public static extern int gdk_input_add (int s, int cond, GdkInputFunction f, IntPtr data); + public delegate void GdkInputFunction (IntPtr data, int source, int cond); + + // + // Libc stuff + // + [DllImport ("libc.so.6")] + public static extern int pipe (int [] fd); + + [DllImport ("libc.so.6")] + public static extern unsafe int read (int fd, byte *b, int count); + + [DllImport ("libc.so.6")] + public static extern unsafe int write (int fd, byte *b, int count); + + + GdkInputFunction notify_pipe; + int [] pipes; + + ReadyEvent re; + + /// + /// The ReadyEvent delegate will be invoked on the current thread (which should + /// be the Gtk thread) when another thread wakes us up by calling WakeupMain + /// + public ThreadNotify (ReadyEvent re) + { + notify_pipe = new GdkInputFunction (NotifyPipe); + pipes = new int [2]; + pipe (pipes); + gdk_input_add (pipes [0], 1, notify_pipe, (IntPtr) 0); + this.re = re; + } + + void NotifyPipe (IntPtr data, int source, int cond) + { + byte s; + + unsafe { + read (pipes [0], &s, 1); + } + + re (); + } + + /// + /// Invoke this function from a thread to call the `ReadyEvent' + /// delegate provided in the constructor on the Main Gtk thread + /// + public void WakeupMain () + { + unsafe { + byte s; + write (pipes [1], &s, 1); + } + } + } +}