Re: strange deadlock ... - FAQ.



Hi Owen,

On 18 Jul 2001, Owen Taylor wrote:
> Look at the GTK+ FAQ. The rules are pretty simple, if not
> perhaps obvious:

	Sorry, I missed this totaly.

> If you call g_thread_init(), then:

	I get to this at the end.

> This type of thing makes me quite uncomfortable in a general
> sense:

	Precicely, the suggestion was a horrendous non-solution to any
locking problem :-)

> For GTK+ I'd much rather stick to the current set of deterministic
> rules. The one obvious improvement would be to separate out whether
> GDK/GTK+ is in multi-threaded mode from whether g_thread_init() has
> been called to make something like gnome-vfs easier to use.

	Ok, so my issue boils down to this: 

	I do a g_main_loop_iterate in my non-GUI ORB, that is called from
a Gtk+ program. This happens to try and process a gdk event and deadlocks.

	So should I:

		a) reccommend people do:

		gdk_threads_enter ();
		Bonobo_Some_call (foo);
		gdk_threads_leave ();

		[ in addition to having to do ]

		gdk_threads_enter ();
		gtk_label_set (GTK_LABEL (l), ...);
		gdk_threads_leave ();

	Or.

		b) Build knowledge of gdk_threads_enter into the otherwise
		totaly non-GUI ORB.

	Or.

		c) Do a violence to glib, and write my own duplicate
		polling routine for only the fd's I'm interested in.

	Or.

		d) Abandon hope in a thread safe ORB.

	Or. ? ...

	NB. c) would have the nice effect of at least not causing GUI
re-enterancy in CORBA calls.

> In fact, I think it is infeasible. What probably is feasible is moving
> to the GLib model -- you could have multiple threads using multiple
> toplevels, but if you wanted to have two threads working on the same
> toplevel, you have to do your own locking.

	I wouldn't care whether if you wanted to access it from 2 threads,
there was a load of problems - but I don't. I just want to access it from
a single thread - but with threads initialized.

> > 	And again, I know little about good practice with locking, but
> > things like this:
> > 
> >   if (g_main_is_running (main_loops->data))
> >     {
> >       GDK_THREADS_LEAVE ();
> >       g_main_run (loop);
> >       GDK_THREADS_ENTER ();
> >       gdk_flush ();
> >     }
> > 
> > 	Looks like a recepie for disaster. 
> 
> Why? 

	Well, I see now how this fits in with the Gtk+ approach to
locking, but I've never seen anything like it. Releasing locks that you
havn't taken yourself, and extensive implicit lock passing is not to my
mind good practice - but I see why you do it now - for 'simplicity' 8)

> Perhaps :-) I'm not exceedingly happy with the way things work, but it
> was thought out, and if you follow the rules, there is good evidence
> that things do work.

	Right, ok so back to my issue:

> If you call g_thread_init(), then:
> 
>  - All calls to GTK+ or GDK must be within a 
>    gdk_threads_enter() / gdK_thread_leaves() pair.
> 
>  - The GDK lock is held on entry for signals, but not for timeout or
>    idle functions, which are run directly from the GLib
>    main loop.
>
> So, if you are going to call GTK+ functions from a timout, you
> must put a gdk_threads_enter()/leave() pair around it.

	This advice while good is not sufficient, you also need to do a
gdk_threads_enter (), gdk_threads_leave () when you hit / iterate the glib
mainloop - if that is Gtk+ is around, and has registered it's X event
processing. Or ... you need to do the leave / enter magic in every user
signal handler that might invoke code that hits the glib event loop.

	Problem is - non GUI glib code can not then be integrated with GUI
glib code if threads are enabled, and people plan to usse GIOChannels a
lot.

	Does that state the problem better?

	Thanks for your advice,

		Michael.

-- 
 mmeeks gnu org  <><, Pseudo Engineer, itinerant idiot






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