By design the Xlib 32-bit internal request sequence numbers may wrap. There is two locations within xcb_io.c that are not wrap-safe. The value of last_flushed relies on the request to be sequential all the time. This is not given when the sequence has just wrapped. Applications may then crash with a "Fatal IO error 11 (Resource temporarily unavailable)".
This patch fixes this by unwrapping the sequence number when needed to retain the sequence relative to last_flushed. Signed-off-by: Jonas Petersen <jnsptr...@gmail.com> --- src/xcb_io.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/xcb_io.c b/src/xcb_io.c index 727c6c7..f2978d0 100644 --- a/src/xcb_io.c +++ b/src/xcb_io.c @@ -455,7 +455,7 @@ void _XSend(Display *dpy, const char *data, long size) static const xReq dummy_request; static char const pad[3]; struct iovec vec[3]; - uint64_t requests; + uint64_t requests, unwrapped_request; _XExtension *ext; xcb_connection_t *c = dpy->xcb->connection; if(dpy->flags & XlibDisplayIOError) @@ -464,6 +464,10 @@ void _XSend(Display *dpy, const char *data, long size) if(dpy->bufptr == dpy->buffer && !size) return; + /* Set bit 8 of 'request' when a 32-bit wrap has just happened + * so the sequence stays correct relatively to 'last_flushed'. */ + unwrapped_request = ((uint64_t)(dpy->request < dpy->xcb->last_flushed) << 32) + dpy->request; + /* iff we asked XCB to set aside errors, we must pick those up * eventually. iff there are async handlers, we may have just * issued requests that will generate replies. in either case, @@ -471,10 +475,10 @@ void _XSend(Display *dpy, const char *data, long size) if(dpy->xcb->event_owner != XlibOwnsEventQueue || dpy->async_handlers) { uint64_t sequence; - for(sequence = dpy->xcb->last_flushed + 1; sequence <= dpy->request; ++sequence) + for(sequence = dpy->xcb->last_flushed + 1; sequence <= unwrapped_request; ++sequence) append_pending_request(dpy, sequence); } - requests = dpy->request - dpy->xcb->last_flushed; + requests = unwrapped_request - dpy->xcb->last_flushed; dpy->xcb->last_flushed = dpy->request; vec[0].iov_base = dpy->buffer; -- 1.7.10.4 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel