[Gtk-sharp-list] GIo or another mechanism of signaling Application.Run

Miguel de Icaza miguel@ximian.com
15 Aug 2002 15:23:57 -0400


Hello!

> 	Very odd; of course threads need to be initialized before the glib main
> context is created; but that should happen right.
> 
> 	To satisfy yourself that this has to work, see glib/gmain.c and search
> for 'wake_up_pipe'.

Yeah, I saw that code, but for some reason I could not get it to work.

I encapsulated this into a class, maybe we should get this class into
Gtk# directly, as it seems useful?

// <summary>
//    Utility class to notify the main Gtk thread from a worker thread
// </summary>

delegate void ReadyEvent ();

class GtkThreadNotify {
	Util.GdkInputFunction notify_pipe;
	int [] pipes;

	ReadyEvent re;
	
	/// <summary>
	///   Constructor: the ReadyEvent is a delegate that will be 
	///   invoked on the main Gtk thread
	/// </summary>
	public GtkThreadNotify (ReadyEvent re)
	{
		notify_pipe = new Util.GdkInputFunction (NotifyPipe);
		pipes = new int [2];
		Util.pipe (pipes);
		Util.gdk_input_add (pipes [0], 1, notify_pipe, (IntPtr) 0);
		this.re = re;
	}

	void NotifyPipe (IntPtr data, int source, int cond)
	{
		byte s;

		unsafe {
			Util.read (pipes [0], &s, 1);
		}

		re ();
	}

	/// <summary>
	///   Invokes the delegate `re' specified in the constructor
	///   on the Gtk thread by waking up Gtk
	/// </summary>
	public void WakeupMain ()
	{
		unsafe {
			byte s;
			Util.write (pipes [1], &s, 1);
		}
	}
}

class Util {
#region Dll imports
	[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);

	[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);
#endregion
}