Re: thread safe gtk?




Rob Browning <rlb@cs.utexas.edu> writes:

> Owen Taylor <otaylor@gtk.org> writes:
> 
> > - 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.
> 
> Which is why each thread needs to remove a token from the pipe before
> it returns from its critical section rather than letting gtk_main do
> it.  The way it's structured right now that doesn't happen, but it
> should.

I thought of that, fooled around with it a while, couldn't
get it to work, and decided that there was a fundemental
flaw in that approach. I just looked over my code, and realized
that the fundemental flaw was trying to lock a lock I already
had locked:

 ftp://ftp.gtk.org/pub/users/otaylor/gtkthreads-0.2.tar.gz

Quite a bit simpler than 0.1.

> That gets me around to my main question which is, why do we need a
> pipe at all?  As long as we're providing a gtk_threads_main anyway,
> why not just do something like this?  (Note that I haven't had time to
> consider this extremely carefully, so I may be overlooking something):
> 
> void
> gtk_threads_enter() { pthread_mutex_lock(&gtk_lock_mutex); }
> 
> gtk_threads_leave() { pthread_mutex_unlock(&gtk_lock_mutex); }
> 
> void
> gtk_threads_main() {
> 
>   while(!gtk_should_quit()) {
>     pthread_mutex_lock(&gtk_lock_mutex);  
>     gtk_main_iteration();
>     pthread_mutex_unlock(&gtk_lock_mutex);  
>   }
> }

The problem is, gtk_main_iteration() will just block on the
select() until an event happens, without regard to the 
desires of the other threads. I don't think you can get
this sort of thing working properly without basically modifying
the main loop. (One approach which avoids putting threading
dependent code into GTK+ is to allow the application to
supply a replacemnt for select())
 
> Now everyone uses this enter/leave pari and just queues up (blocks) on
> the mutex until it's their turn; no condition variables, sleeps, or
> other stuff needed.  The mutex keeps track of who wants in and whose
> turn it is...
 
> For fairness, this relies on pthread_mutex_lock to be (fifo) which was
> not true last time I checked libc6 (POSIX doesn't mandate this).  I
> believe it was actually LIFO (ugh) when I looked at the source.
> However, If we think this general approach is good, I can provide
> wrapper code I've already written which will guarantee fifo
> locking/unlocking behavior.

I'm not sure how important fairness is here. Hopefully, a meaningful
threaded application would be doing enough stuff without the
lock so that things should balance out fairly well. (My test
program suffers fairly badly from fairness, but it isn't
representative).

Regards,
                                        Owen



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