Re: thread safe gtk?
- From: Owen Taylor <otaylor gtk org>
- To: gtk-list redhat com
- Cc: Rob Browning <rlb cs utexas edu>, M Stekelenburg student utwente nl
- Subject: Re: thread safe gtk?
- Date: 11 May 1998 13:42:31 -0400
Rob Browning <rlb@cs.utexas.edu> writes:
> I thought I'd forward this too since it's relevant to anyone following
> this thread. It's an improved way to handle the X pipe from Max.
>
> ------- Start of forwarded message -------
> Date: Sun, 10 May 1998 01:07:41 +0200 (MET DST)
> From: "M.Stekelenburg" <root@cal052304.student.utwente.nl>
> Reply-To: M.Stekelenburg@student.utwente.nl
> To: Rob Browning <rlb@cs.utexas.edu>
> Subject: Re: [gtk-list] Re: thread safe gtk?
> Message-ID: <Pine.LNX.3.95q.980510010212.1128B-100000@noviomagus.student.utwente.nl>
> MIME-Version: 1.0
> Content-Type: TEXT/PLAIN; charset=US-ASCII
>
> ok a better version of my code:
> #define XOPEN write(Xpipe[1],"A",1);lock(xmutex);
> #define XCLOSE signal(xthreadcond);unlock(xmutex);
>
> the pipes etc remain the same but this also changes;
>
> threadcall(){
> read(Xpipe[0],&c,1);
> wait(xthreadcond);
> }
>
>
> This use of threadconditions should make sure that control is transfered
> from the gtk_main thread to the requesting and back.
>
> But this construction is NOT tested.
I think if there are multiple threads trying to get the
lock, a problem can happen:
- Subsidiary thread A tries to get the lock , so it writes
to the pipe, then blocks on the lock.
- Subsidiary thread B tries to get the lock, so it writes
to the pipe, then blocks on the lock.
- Main thread M reads one byte from the pipe, then releases
the lock. and waits on the condition variable.
- thread A gets the lock, runs, signals the condition variable,
then release the lock.
- thread B gets the lock, runs, signals the condition variable,
then releases the lock.
- Main thread M gets the lock, goes back to the main loop,
sees there still is one byte in the pipe, releases the
lock and waits on the condition variable. But neither
A nor B wants the lock now, so the main loop hangs.
There seems like there should be a simple solution to this,
but I really couldn't figure one out. So what I did
in "gtkthreads" was more complicated:
I kept a three-way state variable (unlocked, mainloop, locked),
then as soon as a subsidiary thread wrote to the pipe,
it changed the state from mainloop to locked so that future
threads waiting on the lock would not try to do the same.
The state variable then has to be guarded by a mutex itself,
so the main lock is no longer just a mutex, but is more
like a condpair.
void
gtk_threads_enter (void)
{
pthread_mutex_lock (>k_lock_mutex);
while (gtk_lock_state != GTK_UNLOCKED)
{
gtk_lock_nwaiting++;
if (gtk_lock_state == GTK_MAINLOOP)
{
gtk_lock_state = GTK_LOCKED;
write(gtk_lock_pipe[1], "A", 1);
}
pthread_cond_wait (>k_lock_cond, >k_lock_mutex);
gtk_lock_nwaiting--;
}
gtk_lock_state = GTK_LOCKED;
pthread_mutex_unlock (>k_lock_mutex);
}
void
gtk_threads_leave (void)
{
pthread_mutex_lock (>k_lock_mutex);
gtk_lock_state = GTK_UNLOCKED;
pthread_cond_signal (>k_lock_cond);
pthread_mutex_unlock (>k_lock_mutex);
}
As I said, it seems like there should be a simpler solution.
Regards,
Owen
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]