GtkSharp/gtk/ThreadNotify.cs
Mike Kestner c0b574a686 2003-02-21 Mike Kestner <mkestner@speakeasy.net>
* mapdllnames.pl : a little whitespace action
	* api/*-api.xml : move to win32 dllnames
	* */makefile.win32 : remove the mapdllnames step
	* */*.cs : move to win32 dllnames
	* */*.custom : move to win32 dllnames
	* sources/gtk-sharp.sources : move to win32 dllnames

svn path=/trunk/gtk-sharp/; revision=11823
2003-02-22 04:34:56 +00:00

100 lines
2.1 KiB
C#

//
// 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;
// <summary>
// This delegate will be invoked on the main Gtk thread.
// </summary>
public delegate void ReadyEvent ();
/// <summary>
/// Utility class to help writting multi-threaded Gtk applications
/// </summary>
/// <remarks>
///
public class ThreadNotify {
//
// DllImport functions from Gtk
//
[DllImport ("libgtk-win32-2.0-0.dll")]
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;
/// <summary>
/// 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
/// </summary>
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 {
lock (this) {
read (pipes [0], &s, 1);
notified = false;
}
}
re ();
}
bool notified = false;
/// <summary>
/// Invoke this function from a thread to call the `ReadyEvent'
/// delegate provided in the constructor on the Main Gtk thread
/// </summary>
public void WakeupMain ()
{
unsafe {
byte s;
lock (this){
if (notified)
return;
write (pipes [1], &s, 1);
notified = true;
}
}
}
}
}