I see the following strange behaviour in a multi-threaded Xt-application, using the OSF/Motif 2.x widget set (but I do not think the bug is related to Motif): in a callback procedure, I change the pixmaps of some pushbuttons and their sensitivity state. Sometimes, not all of these modifications are shown on the screen. I tracked this down to the fact, that XtNextEvent/XtWaitForSomething block at a time, when some more Expose events should be in the queue. In fact they are, because as soon as some further action is done, which generates another event, e.g pressing a key or moving the pointer so that a LeaveNotify event is generated, the Expose events are read from the event queue, processed, and everything looks fine. My guess is that the XEventsQueued() called in Xt/NextEvent.c:XtAppNextEvent() do not properly work. Note: XFlush() does not help, using "-sync" makes it worse. Note: I tested this on Red Hat Linux 7.2 with XFree86 4.1.0 and on Tru64 Unix 4.0F with X11R6(?) and on Sun Solaris 8. All show this problem. I don't run R6.7 yet, but I'm afraid this has not been fixed yet.
Created attachment 430 [details] test program (requires Motif/OpenMotif) How to reproduce problem: - unpack test program, "xmkmf; make" - run ./mgtest - it displays 5 control buttons (start, stop, pause, fastforward and step) and a status line; some buttons are insensitive - press the "start"-button (leftmost), then the "pause"-button (3rd). - observe, that sometimes some of the buttons as well as the status line is not redrawn. This can be "fixed" by pressing a key or moving the pointer outside the button. - If you can not see the effect immediately, try the "step"-button multiple times. If this does not help, kill and restart the program. - The problem appears more often if run with the "-sync" command line option.
Does it help if you use the libraries (X11/Xt/et al) from fd.o's xlibs module? That has a lot of threading-related fixes.
I retried with the latest (released) libs from freedesktop.org, in particular: pascal:~/test/Xt/mgrps(267)> ldd ./mgtest libXmu.so.6 => /usr/local/freedesktop/lib/libXmu.so.6 (6.2.3) libXm.so.2 => /usr/X11R6/lib/libXm.so.2 () libXt.so.6 => /usr/local/freedesktop/lib/libXt.so.6 (0.1.5) libSM.so.6 => /usr/local/freedesktop/lib/libSM.so.6 (6.0.3) libICE.so.6 => /usr/local/freedesktop/lib/libICE.so.6 (6.3.3) libXp.so.6 => /usr/X11R6/lib/libXp.so.6 () libXext.so.6 => /usr/local/freedesktop/lib/libXext.so.6 (6.4.3) libX11.so.6 => /usr/local/freedesktop/lib/libX11.so.6 (6.2.1) libpthread.so.0 => /lib/i686/libpthread.so.0 (0x40332000) libc.so.6 => /lib/i686/libc.so.6 (0x40347000) libdl.so.2 => /lib/libdl.so.2 (0x40482000) libXau.so.0 => /usr/local/freedesktop/lib/libXau.so.0 (0.1.1) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) I see the same problem with these libraries. It seemed to be more difficult to reproduce, but with "-sync", it still happens all the time, and sometimes I also see the problem without "-sync". I hope it's not a bug in Motif ;-)
OK, I spend some further time analyzing what's going on here. Two threads are involved, one (lets call it the "Xt loop" thread) does an XtAppMainLoop(), the other one ("playback") occasionally does some Xlib calls (via XtSetValues/ XtManageChild etc, but I think this does not matter). When the problems shows up, the following has happened: The Xt loop thread sits in select(), called from _XtWaitForSomething(), waiting for input from the X display connection. The playback thread at the same time is processing Xlib calls, and reads replies from the X server (_XReply), and also calls _XWaitForReadable multiple times. The select() system call called from _XWaitForReadable returns, because some data from the X server is available. While processing the replies, also some events are read and put into the display's event list. Unfortunately, the select() call of the Xt loop thread does NOT return while the playback thread reads replies and events from the connection. (I've verified that the two select() calls use the same file descriptor in the read-mask and the max-fd parameter.) So, finally some events are queued on the dpy's event list, but the Xt loop thread still waits via select(), and won't process these, until _XtWaitForSomething will eventually return, for example, if another event (like key/button press) occurs. (Of course, the playback thread never tries to process X events.) Now, I'm stuck. I'm afraid it is undefined whether select() called from multiple threads will return in one, several or all threads if input becomes available. Correct? And then it seems to be difficult to fix this synchronization problem between Xlib and Xt's XtWaitForSomething ... Any (helpful ;-) comments? - Andreas
Sorry about the phenomenal bug spam, guys. Adding xorg-team@ to the QA contact so bugs don't get lost in future.
indeed, the behaviour of select in this (rather nasty) case is not guaranteed. you're going to have to pull all the events out in one thread only and pass them along via ipc.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.