Re: broken lock API in gtk_main ()



Tim Janik <timj gtk org> writes:

> currently,
> 
> gtk_main() behaves as follows:
> 
> 
> 1)
>   /* gdk-lock locked by other thread */
>   gtk_main (); /* wait for other thread to release lock, then acquire, operate */
>   /* gdk-lock acquired */
>
> 2)
>   /* gdk-lock released */
>   gtk_main (); /* acquire, operate */
>   /* gdk-lock acquired */
> 
> 3)
>   /* gdk-lock acquired by self */
>   gtk_main (); /* operate */
>   /* gdk-lock acquired */

When threads are enabled, gtk_main(), like every other gtk_* function
must be called with the GDK lock already acquired. I don't quite
follow your scenarios here, but I don't think they are following this
fundemental rule.
 
> the behaviour of (3) is fine for calling gtk_main() recursively (modal
> dialogs).
> (2) is what happens in main () { [...] gtk_main(); }, it actually works

You can't write this. If you call g_thread_init(), then you must
write:

 gdk_threads_enter();

 gtk_main();

 gdk_threads_leave();

> just out of luck, that is, releasing a non acquired lock works on most
> platforms nonetheless, while (1) is fundamentally broken.

> cases (1) and (2) have asymetric lock behaviour (not locked by self upon
> entry, locked by self upon return) and need to be fixed.
> (2) could be hacked around (this is the common main() case) with
> figuring lock state via g_mutex_trylock() upon entry and releasing
> the lock upon return if FALSE was returned. that'll still maintain

You simply can't have places in your code where you don't know whether
you own a particular lock or not.

Even if you use a recursive mutex to prevent problems with acquiring
a lock you already own, you still are inviting problems with
deadlocks when a second lock is involved.

Regards,
                                        Owen




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