summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Dørum <martid0311@gmail.com>2019-05-19 16:05:08 +0200
committerMartin Dørum <martid0311@gmail.com>2019-05-19 16:05:08 +0200
commit21324989b7e121c008a2c4fdf98547541cbf7b83 (patch)
treebfb1c34c30e9294e12e225fcd4e411f00df687c1
parent656c08c5429a3cf53e7abd7fc56cd3c3a79c0f64 (diff)
downloadxcb-libxcb-21324989b7e121c008a2c4fdf98547541cbf7b83.tar.gz
Handle EINTR from recvmsg in _xcb_in_read
I have a GTK application which occasionally crashes with an "interrupted system call" g_message from gdk. After a lot of debugging, I've found that the call to recvmsg in _xcb_in_read occasionally fails with EINTR, and instead of retrying the system call, xcb would just shut down the connection. This change makes _xcb_in_read treat EINTR the same as it would treat EAGAIN; it returns 1 and libX11 ends up calling xcb_poll_for_event again (from what I have understood). I have spoken with a few people who think recvmsg failing with EINTR in this case shouldn't ever happen, and I don't know enough to agree or disagree with that. In case anyone wants to dig further and try to figure out why the recvmsg call sometimes fails with EINTR, here's the backtrace from inside of _xcb_in_read where that happened: Thread 1 "beanbar" hit Breakpoint 1, _xcb_in_read (c=c@entry=0x55ecbe4aba80) at xcb_in.c:1059 1059 fprintf(stderr, "Hello World am %s:%i, errno is %s\n", __FILE__, __LINE__, strerror(errno)); (gdb) bt 0 0x00007fa48fa48639 in _xcb_in_read (c=c@entry=0x55ecbe4aba80) at xcb_in.c:1059 1 0x00007fa48fa489d8 in poll_for_next_event (c=0x55ecbe4aba80, queued=queued@entry=0) at xcb_in.c:352 2 0x00007fa48fa48a3d in poll_for_next_event (queued=0, c=<optimized out>) at xcb_in.c:722 3 0x00007fa48fa48a3d in xcb_poll_for_event (c=<optimized out>) at xcb_in.c:722 4 0x00007fa4908d1b7e in poll_for_event (dpy=dpy@entry=0x55ecbe4a9730, queued_only=queued_only@entry=0) at xcb_io.c:245 5 0x00007fa4908d1cf0 in poll_for_response (dpy=dpy@entry=0x55ecbe4a9730) at xcb_io.c:303 6 0x00007fa4908d1fed in _XEventsQueued (mode=2, dpy=0x55ecbe4a9730) at xcb_io.c:363 7 0x00007fa4908d1fed in _XEventsQueued (dpy=dpy@entry=0x55ecbe4a9730, mode=mode@entry=2) at xcb_io.c:344 8 0x00007fa4908c3d47 in XPending (dpy=0x55ecbe4a9730) at Pending.c:55 9 0x00007fa493cadbc7 in () at /usr/lib/libgdk-3.so.0 10 0x00007fa49234d08a in g_main_context_prepare () at /usr/lib/libglib-2.0.so.0 11 0x00007fa49234d6e6 in () at /usr/lib/libglib-2.0.so.0 12 0x00007fa49234d8ae in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0 13 0x00007fa4938b920e in g_application_run () at /usr/lib/libgio-2.0.so.0 14 0x000055ecbc820af4 in main (argc=1, argv=0x7ffd06238098) at src/main.c:190 Signed-off-by: Martin Dørum <martid0311@gmail.com>
-rw-r--r--src/xcb_in.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/xcb_in.c b/src/xcb_in.c
index 58fe896..733d749 100644
--- a/src/xcb_in.c
+++ b/src/xcb_in.c
@@ -1051,7 +1051,7 @@ int _xcb_in_read(xcb_connection_t *c)
}
#endif
#ifndef _WIN32
- if((n > 0) || (n < 0 && errno == EAGAIN))
+ if((n > 0) || (n < 0 && (errno == EAGAIN || errno == EINTR)))
#else
if((n > 0) || (n < 0 && WSAGetLastError() == WSAEWOULDBLOCK))
#endif /* !_WIN32 */