Bug 41870 - XSync never return , when XNextEvent runs in separate thread
Summary: XSync never return , when XNextEvent runs in separate thread
Status: RESOLVED INVALID
Alias: None
Product: xorg
Classification: Unclassified
Component: Lib/Xlib (show other bugs)
Version: unspecified
Hardware: x86-64 (AMD64) Linux (All)
: medium critical
Assignee: Xorg Project Team
QA Contact: Xorg Project Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-10-17 04:35 UTC by Arvind Umrao
Modified: 2018-07-05 18:01 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments

Description Arvind Umrao 2011-10-17 04:35:05 UTC
With libx11-xcb, XSync never returns, when XnextEvent run in separate thread, causing Java application crash.  With legacy libX11 XSync never hang, it should be the same case with libX11-xcb. To reproduce the problem, please compile code with cc sample.c -lX11, then run it. You will not see any print messages.  



#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
#include<X11/Xlib.h>
#include<X11/Xutil.h>

Display *dsp;
Window win;
int screen;
XEvent evt;

void * mythread(void *arg) {

    XSelectInput(dsp, win, ExposureMask | ButtonPressMask);
    while (1) {
        XNextEvent(dsp, &evt); /* Lock Display in S11 */
        switch (evt.type) {
            case Expose:
                break;
                ;
            case ButtonPress:
                fprintf(stderr, "Button pressed in thread\n");
        }
    }
}

int main(int ac, char *av[]) {

    pthread_t tid_a;
    int arg_thread = 100;

    XEvent ev;

    XInitThreads();
    if ((dsp = XOpenDisplay("")) == NULL) {
        fprintf(stderr, "Can not open Display\n");
        return (-1);
    }

    screen = DefaultScreen(dsp);
    win = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp), 10, 10, 200, 100,
            5, WhitePixel(dsp, screen), BlackPixel(dsp, screen));
    XMapRaised(dsp, win);

    int status = pthread_create(&tid_a, NULL, mythread, &arg_thread);

    /* do some long task */
    sleep(1);

    XSync(dsp, True); /* <= hung here */

    /* Execution never comes here */

    fprintf(stderr, "\nWith legacy libX11 you can see this messsage \n");
    fprintf(stderr, "But with libX11-xcb you will never see this message.\n");

    /* wait threads */
    status = pthread_join(tid_a, NULL);
    return (0);
}
Comment 1 Uli Schlachter 2012-01-30 08:53:11 UTC
Reassigning to xorg/Library since it's Xlib which hangs.

For where it hangs:
xcb_io.c, line 615, function _XReply() contains:

			/* If some thread is already waiting for events,
			 * it will get the first one. That thread must
			 * process that event before we can continue. */
			/* FIXME: That event might be after this reply,
			 * and might never even come--or there might be
			 * multiple threads trying to get events. */
			while(dpy->xcb->event_waiter)
			{ /* need braces around ConditionWait */
				ConditionWait(dpy, dpy->xcb->event_notify);
			}

This comment is correct. The event waiter really is waiting for an event but none is coming in.
Comment 2 Adam Jackson 2018-06-12 19:06:22 UTC
Mass closure: This bug has been untouched for more than six years, and is not
obviously still valid. Please reopen this bug or file a new report if you continue to experience issues with current releases.
Comment 3 gilado 2018-07-05 17:48:59 UTC
Still happening. I use feh as part of a screensaver program. The program send signal 15 to remove feh. It works most of the time, but every so often it freezes and the only way to get it off the screen is killall -9 feh.

I attached a debugger to one such frozen instance

(gdb) bt
#0  0x00007fdc75f737c5 in _XReply () from /usr/lib64/libX11.so.6
#1  0x00007fdc75f6f4cd in XSync () from /usr/lib64/libX11.so.6
#2  0x00007fdc75f5122e in XCloseDisplay () from /usr/lib64/libX11.so.6
#3  0x000000000041249f in feh_clean_exit () at main.c:223
#4  0x00007fdc7592bc38 in ?? () from /lib64/libc.so.6
#5  0x00007fdc7592bc8a in exit () from /lib64/libc.so.6
#6  0x0000000000417987 in feh_handle_signal (signo=15) at signals.c:89
#7  <signal handler called>
#8  0x00007fdc759eadb4 in poll () from /lib64/libc.so.6
#9  0x00007fdc740d5902 in ?? () from /usr/lib64/libxcb.so.1
#10 0x00007fdc740d737f in ?? () from /usr/lib64/libxcb.so.1
#11 0x00007fdc740d74f1 in xcb_wait_for_reply64 () from /usr/lib64/libxcb.so.1
#12 0x00007fdc75f737f8 in _XReply () from /usr/lib64/libX11.so.6
#13 0x00007fdc75f6f4cd in XSync () from /usr/lib64/libX11.so.6
#14 0x0000000000412645 in feh_main_iteration (block=block@entry=1)
    at main.c:168
#15 0x00000000004059fa in feh_main_iteration (block=1) at main.c:61
#16 main (argc=16, argv=0x7ffc65d95e58) at main.c:86

BTW at the time this happens feh/x11 thread is spinning taking 100% of one core's cpu.

$ xdpyinfo | grep -i version
version number:    11.0
X.Org version: 1.19.6
Comment 4 Alan Coopersmith 2018-07-05 18:01:13 UTC
(In reply to gilado from comment #3)
> Still happening. I use feh as part of a screensaver program. The program
> send signal 15 to remove feh. It works most of the time, but every so often
> it freezes and the only way to get it off the screen is killall -9 feh.

That's not a seperate thread, that's a signal handler that interrupted the
same thread and made non-signal-safe calls.  That can never work and feh
has to rewrite their signal handler not to do that.


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.