Re: XInitThreads causing problems to GTK windows.




"Peter Wilson" <peter@stubble.force9.co.uk> writes:

> /*
> 
> Hello there!
> 
>       Can someone tell me if there's something I need to know before calling
> Xlib code directly, within GTK programs? I'm trying to write a proggy that
> will have one thread that does some graphics stuff, talking directly to XLib
> (with it's own connection to the X server). Because that means that there
> might
> be two threads calling XLib concurrently I need to call XInitThreads() -
> it's
> man page states..:-
> 
> 	This function must be the first Xlib
> 	function a multi-threaded program calls,
> 	and it must complete before any other
> 	Xlib call is made.
> 
> 	However - I've found that if I call XInitThreads BEFORE gtk_init, then
> pressing a key with a fileselection on the screen causes the program to hang
> somewhere inside gtk_main_iteration().

Since you aren't calling g_threads_init() - GTK+ isn't doing
any locking, and hence can't be causing the lockups. So
we have to look at Xlib instead. In fact, if you do 
a backtrace of the lockup, you'll see:

#3  0x4020f04d in _XLockDisplay ()
#4  0x40217e35 in XkbGetUpdatedMap ()
#5  0x40217ed0 in XkbGetMap ()
#6  0x4021507c in _XkbLoadDpy ()
#7  0x40215516 in XLookupString ()
#8  0x4023454d in _XimLocalFilter ()
#9  0x4020e9d9 in XFilterEvent ()
#10 0x40158ee6 in gdk_events_queue () at gdkevents.c:1998
#11 0x401590f8 in gdk_event_dispatch (source_data=0x0, 

XFilterEvent() is acquiring the per-display lock, then
XkbGetUpdatedMap() is trying to get it again.

the general conclusion here is one I've reached before -
the Xlib code dealing with the core protocol may
be fairly well tested with XInitThreads() but most
of the extensions aren't. Since GTK+ makes heavy
use of various extension, GTK+ and XInitThreads()
tend not to work well together.

[ Caveat - I've only looked at X11R6.3 so far. X11R6.4
  may fix some of these problems ]
 
> If I call XInitThreads after gtk_init then everything appears fine, but
> I don't know what affects that'll have on XLib. 

Locking is basically per-display; since you are calling 
XInitThreads() after creating the GDK display, no locking 
is being done for the GDK display and the problem doesn't 
occur.

In fact, the fact that most X structures are per-display
may point to the easiest solution to your problem.
If you are using two separate display connections
in two separate threads, you probably can get away
with not locking at all.

(There are a few sections of the X code that do use
 a global lock -- grep for 'global_lock' in the
 xc/lib/X11 directory if you want details - but these
 probably won't be hit if you are just doing 
 screen-drawing type operations)

Regards,
                                        Owen




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