Proposal: threads in glib.



Hi,

Even if I do not want to start another neverending thread (ah, what a
delicious ambiguity;-), I'm afraid, I will. So here's my rational:

1. programming with threads is usefull.

even if you have functions like .._add_idle in gtk, it still makes sense
to program threaded applications (this holds true especially for gui
applications).

2. most platforms have or will have threads.

even though some platforms still do not provide support for threads, those
platforms will eventually be replaced by ones, that do.

3. glib will live in non-posix environments

glib is being ported to win32, where posix threads are not natively
supported .

All of that leads me to the conclusion, that glib needs a simple, but
powerfull thread abstraction.

I implemented such a beast in the spirit of glib, here's the README:

------8<-----------8<---------8<--------------------------
This is a first shot for a cross platform thread library for glib.

it is currently only implemented for posix threads, but should be
portable to win32 and other platforms, that support threads.

The whole thing is kind of similar to the NSPR API of netscapes cross
platform library, but has a simpler interface, that should satisfy
almost all needs. Also there are some functions, that are more nifty
than in NSPR, especially the g_monitor_new_for_resource function,
which is a much better version of the cached monitors in NSPR (it's
faster and uses the same API as usual monitors).

The whole thing is not very big (the stripped version of the lib is
only about 4k on solaris).

Here is the API:

/* create a new thread and start it with the function thread_func,
  which gets the argument arg. stack_size determines the stack for the
  process, if zero the default stack size is taken. */ 
GThread* g_thread_new(GThreadFunc thread_func,
		      gpointer arg, 
		      guint stack_size);

/* the calling thread is blocked until thread is completed, returns
   FALSE, if thread is invalid. */
gboolean g_thread_join(GThread* thread);

/* get a reference to the current thread */
GThread* g_thread_get_current();

/* allocate a new slot for private data. it is associated with the
   returned id. all non-zero data registered by a thread will be
   handed over to destroy_func, whenever the data is set again or
   when the threads ends. */
GThreadPrivate* g_thread_private_new(GDestroyNotify destroy_func);

/* set the private data connected to the current thread and id */
gboolean g_thread_private_set(GThreadPrivate* id, gpointer data);

/* get the private data connected to the current thread and id, if it is
not
   set yet, NULL will be returned */
gpointer g_thread_private_get(GThreadPrivate* id);

/* free the slot for private thread data, that includes running the
   destroy-function for all non-zero instances */
void g_thread_private_free(GThreadPrivate* id);

/* create a new monitor. */
GMonitor* g_monitor_new();

/* get the monitor, that is related to resource. That way you don't
   have to create a mutex centrally, but simply use it on an agreed
   pointer, i.e. a address of an object */
GMonitor* g_monitor_new_for_resource(gpointer resource);

/* free a monitor */
void g_monitor_free(GMonitor* monitor);

/* enter the monitor, if the current thread already is in the monitor,
   then only the entry counter is incremented. otherwise the current
thread
   is suspended till the monitor is left by the holding thread */
void g_monitor_enter(GMonitor* monitor);

/* decrement the entry counter. if zero, leave the monitor. returns
   FALSE, if the monitor is not held by current thread */
gboolean g_monitor_exit(GMonitor* monitor);

/* wait for at most microseconds mu-secs to be notified. the monitor
   is left for that time and reentered afterwards (keeping the
   original entry count). FALSE is returned, if the monitor is not held
   by the calling process.*/
gboolean g_monitor_wait(GMonitor* monitor, gulong microseconds);

/* notify ONE of the threads waiting for monitor */
void g_monitor_notify(GMonitor* monitor);

/* notify ALL of the threads waiting for monitor */
void g_monitor_notify_all(GMonitor* monitor);
------8<-----------8<---------8<--------------------------

It is still questionable, whether there should be more options to the
thread_new and monitor_new functions. But the more options, the more
problems for porting and the benefits are not always obviuos (but might
exist).

Bye
Sebastian

-- 
+--------------============####################============--------------+
| Sebastian Wilhelmi, Institute for Computer Design and Fault Tolerance, |
| University of Karlsruhe;  Building 20.20, Room 263,  D-76128 Karlsruhe |
| mail: wilhelmi@ira.uka.de;  fax: +49 721 370455;  fon: +49 721 6084353 |
+-----------------> http://goethe.ira.uka.de/~wilhelmi <-----------------+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]