19154747 X application crashed with Assertion failed: xcb_xlib_threads_sequence_lost
authorravi kumar <ravi.n.kumar@oracle.com>
Wed, 12 Apr 2017 06:57:07 +0000
changeset 1705 76aff95e6534
parent 1704 4c67bc06f3ac
child 1706 f2af07bcb48f
19154747 X application crashed with Assertion failed: xcb_xlib_threads_sequence_lost
open-src/lib/libX11/19154747.patch
open-src/lib/libX11/Makefile
open-src/lib/libxcb/19154747.patch
open-src/lib/libxcb/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/lib/libX11/19154747.patch	Wed Apr 12 06:57:07 2017 +0000
@@ -0,0 +1,722 @@
+From a72d2d06c002b644b7040a0a9936c8525e092ba8 Mon Sep 17 00:00:00 2001
+From: Christian Linhart <[email protected]>
+Date: Mon, 7 Sep 2015 17:17:32 +0200
+Subject: fix for Xlib 32-bit request number issues
+
+Make use of the new 64-bit sequence number API in XCB 1.11.1 to avoid
+the 32-bit sequence number wrap in libX11.
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71338
+Signed-off-by: Christian Linhart <[email protected]>
+Signed-off-by: Olivier Fourdan <[email protected]>
+Reviewed-by: Adam Jackson <[email protected]>
+
+diff --git a/configure.ac b/configure.ac
+index 92b791c..14ad543 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -68,8 +68,8 @@ AC_SUBST(LDFLAGS_FOR_BUILD)
+ # Checks for pkg-config packages
+ 
+ # Always required
+-X11_REQUIRES='xproto >= 7.0.17 xextproto xtrans xcb >= 1.1.92'
+-X11_EXTRA_DEPS="xcb >= 1.1.92"
++X11_REQUIRES='xproto >= 7.0.17 xextproto xtrans xcb >= 1.11'
++X11_EXTRA_DEPS="xcb >= 1.11"
+ 
+ PKG_PROG_PKG_CONFIG()
+ 
+diff --git a/src/ClDisplay.c b/src/ClDisplay.c
+index bddd773..aa904e5 100644
+--- a/src/ClDisplay.c
++++ b/src/ClDisplay.c
+@@ -65,7 +65,7 @@ XCloseDisplay (
+ 		    (*ext->close_display)(dpy, &ext->codes);
+ 	    }
+ 	    /* if the closes generated more protocol, sync them up */
+-	    if (dpy->request != dpy->last_request_read)
++	    if (X_DPY_GET_REQUEST(dpy) != X_DPY_GET_LAST_REQUEST_READ(dpy))
+ 		XSync(dpy, 1);
+ 	}
+ 	xcb_disconnect(dpy->xcb->connection);
+diff --git a/src/Font.c b/src/Font.c
+index 650bc6f..a73f9b1 100644
+--- a/src/Font.c
++++ b/src/Font.c
+@@ -105,7 +105,7 @@ XFontStruct *XLoadQueryFont(
+       return font_result;
+     LockDisplay(dpy);
+     GetReq(OpenFont, req);
+-    seq = dpy->request;
++    seq = dpy->request; /* Can't use extended sequence number here */
+     nbytes = req->nbytes  = name ? strlen(name) : 0;
+     req->fid = fid = XAllocID(dpy);
+     req->length += (nbytes+3)>>2;
+diff --git a/src/GetAtomNm.c b/src/GetAtomNm.c
+index 32de50d..d7f06e3 100644
+--- a/src/GetAtomNm.c
++++ b/src/GetAtomNm.c
+@@ -87,8 +87,8 @@ char *XGetAtomName(
+ }
+ 
+ typedef struct {
+-    unsigned long start_seq;
+-    unsigned long stop_seq;
++    uint64_t start_seq;
++    uint64_t stop_seq;
+     Atom *atoms;
+     char **names;
+     int idx;
+@@ -107,10 +107,11 @@ Bool _XGetAtomNameHandler(
+     register _XGetAtomNameState *state;
+     xGetAtomNameReply replbuf;
+     register xGetAtomNameReply *repl;
++    uint64_t last_request_read = X_DPY_GET_LAST_REQUEST_READ(dpy);
+ 
+     state = (_XGetAtomNameState *)data;
+-    if (dpy->last_request_read < state->start_seq ||
+-	dpy->last_request_read > state->stop_seq)
++    if (last_request_read < state->start_seq ||
++	last_request_read > state->stop_seq)
+ 	return False;
+     while (state->idx < state->count && state->names[state->idx])
+ 	state->idx++;
+@@ -152,7 +153,7 @@ XGetAtomNames (
+     int missed = -1;
+ 
+     LockDisplay(dpy);
+-    async_state.start_seq = dpy->request + 1;
++    async_state.start_seq = X_DPY_GET_REQUEST(dpy) + 1;
+     async_state.atoms = atoms;
+     async_state.names = names_return;
+     async_state.idx = 0;
+@@ -165,7 +166,7 @@ XGetAtomNames (
+     for (i = 0; i < count; i++) {
+ 	if (!(names_return[i] = _XGetAtomName(dpy, atoms[i]))) {
+ 	    missed = i;
+-	    async_state.stop_seq = dpy->request;
++	    async_state.stop_seq = X_DPY_GET_REQUEST(dpy);
+ 	}
+     }
+     if (missed >= 0) {
+diff --git a/src/GetWAttrs.c b/src/GetWAttrs.c
+index c10824c..0f5f7bb 100644
+--- a/src/GetWAttrs.c
++++ b/src/GetWAttrs.c
+@@ -30,8 +30,8 @@ in this Software without prior written authorization from The Open Group.
+ #include "Xlibint.h"
+ 
+ typedef struct _WAttrsState {
+-    unsigned long attr_seq;
+-    unsigned long geom_seq;
++    uint64_t attr_seq;
++    uint64_t geom_seq;
+     XWindowAttributes *attr;
+ } _XWAttrsState;
+ 
+@@ -47,10 +47,11 @@ _XWAttrsHandler(
+     xGetWindowAttributesReply replbuf;
+     register xGetWindowAttributesReply *repl;
+     register XWindowAttributes *attr;
++    uint64_t last_request_read = X_DPY_GET_LAST_REQUEST_READ(dpy);
+ 
+     state = (_XWAttrsState *)data;
+-    if (dpy->last_request_read != state->attr_seq) {
+-	if (dpy->last_request_read == state->geom_seq &&
++    if (last_request_read != state->attr_seq) {
++	if (last_request_read == state->geom_seq &&
+ 	    !state->attr &&
+ 	    rep->generic.type == X_Error &&
+ 	    rep->error.errorCode == BadDrawable)
+@@ -99,7 +100,7 @@ _XGetWindowAttributes(
+ 
+     GetResReq(GetWindowAttributes, w, req);
+ 
+-    async_state.attr_seq = dpy->request;
++    async_state.attr_seq = X_DPY_GET_REQUEST(dpy);
+     async_state.geom_seq = 0;
+     async_state.attr = attr;
+     async.next = dpy->async_handlers;
+@@ -109,7 +110,7 @@ _XGetWindowAttributes(
+ 
+     GetResReq(GetGeometry, w, req);
+ 
+-    async_state.geom_seq = dpy->request;
++    async_state.geom_seq = X_DPY_GET_REQUEST(dpy);
+ 
+     if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) {
+ 	DeqAsyncHandler(dpy, &async);
+diff --git a/src/IntAtom.c b/src/IntAtom.c
+index 3042b65..d9c6c58 100644
+--- a/src/IntAtom.c
++++ b/src/IntAtom.c
+@@ -188,8 +188,8 @@ XInternAtom (
+ }
+ 
+ typedef struct {
+-    unsigned long start_seq;
+-    unsigned long stop_seq;
++    uint64_t start_seq;
++    uint64_t stop_seq;
+     char **names;
+     Atom *atoms;
+     int count;
+@@ -208,10 +208,12 @@ Bool _XIntAtomHandler(
+     register int i, idx = 0;
+     xInternAtomReply replbuf;
+     register xInternAtomReply *repl;
++    uint64_t last_request_read = X_DPY_GET_LAST_REQUEST_READ(dpy);
+ 
+     state = (_XIntAtomState *)data;
+-    if (dpy->last_request_read < state->start_seq ||
+-	dpy->last_request_read > state->stop_seq)
++
++    if (last_request_read < state->start_seq ||
++	last_request_read > state->stop_seq)
+ 	return False;
+     for (i = 0; i < state->count; i++) {
+ 	if (state->atoms[i] & 0x80000000) {
+@@ -252,7 +254,7 @@ XInternAtoms (
+     xInternAtomReply rep;
+ 
+     LockDisplay(dpy);
+-    async_state.start_seq = dpy->request + 1;
++    async_state.start_seq = X_DPY_GET_REQUEST(dpy) + 1;
+     async_state.atoms = atoms_return;
+     async_state.names = names;
+     async_state.count = count - 1;
+@@ -266,7 +268,7 @@ XInternAtoms (
+ 					     &sig, &idx, &n))) {
+ 	    missed = i;
+ 	    atoms_return[i] = ~((Atom)idx);
+-	    async_state.stop_seq = dpy->request;
++	    async_state.stop_seq = X_DPY_GET_REQUEST(dpy);
+ 	}
+     }
+     if (missed >= 0) {
+diff --git a/src/OpenDis.c b/src/OpenDis.c
+index 636860e..8272357 100644
+--- a/src/OpenDis.c
++++ b/src/OpenDis.c
+@@ -197,8 +197,8 @@ XOpenDisplay (
+ 	dpy->idlist_alloc = _XAllocIDs;
+ 	dpy->synchandler = NULL;
+ 	dpy->savedsynchandler = NULL;
+-	dpy->request = 0;
+-	dpy->last_request_read = 0;
++	X_DPY_SET_REQUEST(dpy, 0);
++	X_DPY_SET_LAST_REQUEST_READ(dpy, 0);
+ 	dpy->default_screen = iscreen;  /* Value returned by ConnectDisplay */
+ 	dpy->last_req = (char *)&_dummy_request;
+ 
+diff --git a/src/PutImage.c b/src/PutImage.c
+index de085bc..13cbba3 100644
+--- a/src/PutImage.c
++++ b/src/PutImage.c
+@@ -602,7 +602,7 @@ static int const HalfOrderWord[12] = {
+ 
+ #define UnGetReq(name)\
+     dpy->bufptr -= SIZEOF(x##name##Req);\
+-    dpy->request--
++    X_DPY_REQUEST_DECREMENT(dpy)
+ 
+ static void
+ SendXYImage(
+diff --git a/src/XlibAsync.c b/src/XlibAsync.c
+index eb2b819..d62000e 100644
+--- a/src/XlibAsync.c
++++ b/src/XlibAsync.c
+@@ -32,6 +32,18 @@ from The Open Group.
+ #include <X11/Xlibint.h>
+ #include <X11/Xos.h>
+ 
++/*
++ * Xlib's _XAsyncErrorState sequence number may wrap in 32bit
++ * and we cannot use 64bit as it's public API.
++ */
++#ifdef LONG64
++#define _XLIB_ASYNC_SEQUENCE_CMP(a,op,b)     ((a == 0) || (a op b))
++#else /* !LONG64 */
++#define _XLIB_ASYNC_SEQUENCE_CMP(a,op,b)     ((a == 0) || \
++                                              (((a op b) && (b - a op (UINT32_MAX >> 1))) || \
++                                               ((b op a) && ((UINT32_MAX >> 1) op a - b))))
++#endif /* !LONG64 */
++
+ /*ARGSUSED*/
+ Bool
+ _XAsyncErrorHandler(
+@@ -51,10 +63,8 @@ _XAsyncErrorHandler(
+ 	 rep->error.majorCode == state->major_opcode) &&
+ 	(!state->minor_opcode ||
+ 	 rep->error.minorCode == state->minor_opcode) &&
+-	(!state->min_sequence_number ||
+-	 (state->min_sequence_number <= dpy->last_request_read)) &&
+-	(!state->max_sequence_number ||
+-	 (state->max_sequence_number >= dpy->last_request_read))) {
++	(_XLIB_ASYNC_SEQUENCE_CMP(state->min_sequence_number,<=,dpy->last_request_read)) &&
++	(_XLIB_ASYNC_SEQUENCE_CMP(state->max_sequence_number,>=,dpy->last_request_read))) {
+ 	state->last_error_received = rep->error.errorCode;
+ 	state->error_count++;
+ 	return True;
+diff --git a/src/XlibInt.c b/src/XlibInt.c
+index bbc5c82..7296948 100644
+--- a/src/XlibInt.c
++++ b/src/XlibInt.c
+@@ -167,8 +167,12 @@ void _XPollfdCacheDel(
+ 
+ static int sync_hazard(Display *dpy)
+ {
+-    unsigned long span = dpy->request - dpy->last_request_read;
+-    unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10);
++    /*
++     * "span" and "hazard" need to be signed such that the ">=" comparision
++     * works correctly in the case that hazard is greater than 65525
++     */
++    int64_t span = X_DPY_GET_REQUEST(dpy) - X_DPY_GET_LAST_REQUEST_READ(dpy);
++    int64_t hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10);
+     return span >= 65535 - hazard - 10;
+ }
+ 
+@@ -194,7 +198,7 @@ void _XSeqSyncFunction(
+     xGetInputFocusReply rep;
+     register xReq *req;
+ 
+-    if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) {
++    if ((X_DPY_GET_REQUEST(dpy) - X_DPY_GET_LAST_REQUEST_READ(dpy)) >= (65535 - BUFSIZE/SIZEOF(xReq))) {
+ 	GetEmptyReq(GetInputFocus, req);
+ 	(void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
+ 	sync_while_locked(dpy);
+@@ -276,9 +280,9 @@ _XSetLastRequestRead(
+     register Display *dpy,
+     register xGenericReply *rep)
+ {
+-    register unsigned long	newseq, lastseq;
++    register uint64_t	newseq, lastseq;
+ 
+-    lastseq = dpy->last_request_read;
++    lastseq = X_DPY_GET_LAST_REQUEST_READ(dpy);
+     /*
+      * KeymapNotify has no sequence number, but is always guaranteed
+      * to immediately follow another event, except when generated via
+@@ -287,20 +291,21 @@ _XSetLastRequestRead(
+     if ((rep->type & 0x7f) == KeymapNotify)
+ 	return(lastseq);
+ 
+-    newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber;
++    newseq = (lastseq & ~((uint64_t)0xffff)) | rep->sequenceNumber;
+ 
+     if (newseq < lastseq) {
+ 	newseq += 0x10000;
+-	if (newseq > dpy->request) {
++	if (newseq > X_DPY_GET_REQUEST(dpy)) {
+ 	    (void) fprintf (stderr,
+-	    "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
+-			    newseq, dpy->request,
++	    "Xlib: sequence lost (0x%llx > 0x%llx) in reply type 0x%x!\n",
++			    (unsigned long long)newseq,
++			    (unsigned long long)(X_DPY_GET_REQUEST(dpy)),
+ 			    (unsigned int) rep->type);
+ 	    newseq -= 0x10000;
+ 	}
+     }
+ 
+-    dpy->last_request_read = newseq;
++    X_DPY_SET_LAST_REQUEST_READ(dpy, newseq);
+     return(newseq);
+ }
+ 
+@@ -1363,10 +1368,10 @@ static int _XPrintDefaultError(
+ 			  mesg, BUFSIZ);
+     fputs("  ", fp);
+     (void) fprintf(fp, mesg, event->serial);
+-    XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
++    XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%lld",
+ 			  mesg, BUFSIZ);
+     fputs("\n  ", fp);
+-    (void) fprintf(fp, mesg, dpy->request);
++    (void) fprintf(fp, mesg, (unsigned long long)(X_DPY_GET_REQUEST(dpy)));
+     fputs("\n", fp);
+     if (event->error_code == BadImplementation) return 0;
+     return 1;
+@@ -1720,7 +1725,7 @@ void *_XGetRequest(Display *dpy, CARD8 type, size_t len)
+     req->reqType = type;
+     req->length = len / 4;
+     dpy->bufptr += len;
+-    dpy->request++;
++    X_DPY_REQUEST_INCREMENT(dpy);
+     return req;
+ }
+ 
+diff --git a/src/Xxcbint.h b/src/Xxcbint.h
+index bf41c23..20a6386 100644
+--- a/src/Xxcbint.h
++++ b/src/Xxcbint.h
+@@ -13,12 +13,12 @@
+ #include <X11/Xlib-xcb.h>
+ #include "locking.h"
+ 
+-#define XLIB_SEQUENCE_COMPARE(a,op,b)	(((long) (a) - (long) (b)) op 0)
++#define XLIB_SEQUENCE_COMPARE(a,op,b)	(((int64_t) (a) - (int64_t) (b)) op 0)
+ 
+ typedef struct PendingRequest PendingRequest;
+ struct PendingRequest {
+ 	PendingRequest *next;
+-	unsigned long sequence;
++	uint64_t sequence;
+ 	unsigned reply_waiter;
+ };
+ 
+diff --git a/src/xcb_io.c b/src/xcb_io.c
+index 5987329..bd26a62 100644
+--- a/src/xcb_io.c
++++ b/src/xcb_io.c
+@@ -68,22 +68,8 @@ static void require_socket(Display *dpy)
+ 		if(!xcb_take_socket(dpy->xcb->connection, return_socket, dpy,
+ 		                    flags, &sent))
+ 			_XIOError(dpy);
+-		/* Xlib uses unsigned long for sequence numbers.  XCB
+-		 * uses 64-bit internally, but currently exposes an
+-		 * unsigned int API.  If these differ, Xlib cannot track
+-		 * the full 64-bit sequence number if 32-bit wrap
+-		 * happens while Xlib does not own the socket.  A
+-		 * complete fix would be to make XCB's public API use
+-		 * 64-bit sequence numbers. */
+-		if (sizeof(unsigned long) > sizeof(unsigned int) &&
+-		    dpy->xcb->event_owner == XlibOwnsEventQueue &&
+-		    (sent - dpy->last_request_read >= (UINT64_C(1) << 32))) {
+-			throw_thread_fail_assert("Sequence number wrapped "
+-			                         "beyond 32 bits while Xlib "
+-						 "did not own the socket",
+-			                         xcb_xlib_seq_number_wrapped);
+-		}
+-		dpy->xcb->last_flushed = dpy->request = sent;
++		dpy->xcb->last_flushed = sent;
++		X_DPY_SET_REQUEST(dpy, sent);
+ 		dpy->bufmax = dpy->xcb->real_bufmax;
+ 	}
+ }
+@@ -145,7 +131,7 @@ static void check_internal_connections(Display *dpy)
+ 		}
+ }
+ 
+-static PendingRequest *append_pending_request(Display *dpy, unsigned long sequence)
++static PendingRequest *append_pending_request(Display *dpy, uint64_t sequence)
+ {
+ 	PendingRequest *node = malloc(sizeof(PendingRequest));
+ 	assert(node);
+@@ -214,14 +200,13 @@ static int handle_error(Display *dpy, xError *err, Bool in_XReply)
+ 	return 0;
+ }
+ 
+-/* Widen a 32-bit sequence number into a native-word-size (unsigned long)
+- * sequence number.  Treating the comparison as a 1 and shifting it avoids a
+- * conditional branch, and shifting by 16 twice avoids a compiler warning when
+- * sizeof(unsigned long) == 4. */
+-static void widen(unsigned long *wide, unsigned int narrow)
++/* Widen a 32-bit sequence number into a 64bit (uint64_t) sequence number.
++ * Treating the comparison as a 1 and shifting it avoids a conditional branch.
++ */
++static void widen(uint64_t *wide, unsigned int narrow)
+ {
+-	unsigned long new = (*wide & ~0xFFFFFFFFUL) | narrow;
+-	*wide = new + ((unsigned long) (new < *wide) << 16 << 16);
++	uint64_t new = (*wide & ~((uint64_t)0xFFFFFFFFUL)) | narrow;
++	*wide = new + (((uint64_t)(new < *wide)) << 32);
+ }
+ 
+ /* Thread-safety rules:
+@@ -260,20 +245,20 @@ static xcb_generic_reply_t *poll_for_event(Display *dpy)
+ 	{
+ 		PendingRequest *req = dpy->xcb->pending_requests;
+ 		xcb_generic_event_t *event = dpy->xcb->next_event;
+-		unsigned long event_sequence = dpy->last_request_read;
++		uint64_t event_sequence = X_DPY_GET_LAST_REQUEST_READ(dpy);
+ 		widen(&event_sequence, event->full_sequence);
+ 		if(!req || XLIB_SEQUENCE_COMPARE(event_sequence, <, req->sequence)
+ 		        || (event->response_type != X_Error && event_sequence == req->sequence))
+ 		{
+-			if (XLIB_SEQUENCE_COMPARE(event_sequence, >,
+-			                          dpy->request))
++			uint64_t request = X_DPY_GET_REQUEST(dpy);
++			if (XLIB_SEQUENCE_COMPARE(event_sequence, >, request))
+ 			{
+ 				throw_thread_fail_assert("Unknown sequence "
+ 				                         "number while "
+ 							 "processing queue",
+ 				                xcb_xlib_threads_sequence_lost);
+ 			}
+-			dpy->last_request_read = event_sequence;
++			X_DPY_SET_LAST_REQUEST_READ(dpy, event_sequence);
+ 			dpy->xcb->next_event = NULL;
+ 			return (xcb_generic_reply_t *) event;
+ 		}
+@@ -289,15 +274,16 @@ static xcb_generic_reply_t *poll_for_response(Display *dpy)
+ 	while(!(response = poll_for_event(dpy)) &&
+ 	      (req = dpy->xcb->pending_requests) &&
+ 	      !req->reply_waiter &&
+-	      xcb_poll_for_reply(dpy->xcb->connection, req->sequence, &response, &error))
++	      xcb_poll_for_reply64(dpy->xcb->connection, req->sequence, &response, &error))
+ 	{
+-		if(XLIB_SEQUENCE_COMPARE(req->sequence, >, dpy->request))
++		uint64_t request = X_DPY_GET_REQUEST(dpy);
++		if(XLIB_SEQUENCE_COMPARE(req->sequence, >, request))
+ 		{
+ 			throw_thread_fail_assert("Unknown sequence number "
+ 			                         "while awaiting reply",
+ 			                        xcb_xlib_threads_sequence_lost);
+ 		}
+-		dpy->last_request_read = req->sequence;
++		X_DPY_SET_LAST_REQUEST_READ(dpy, req->sequence);
+ 		if(response)
+ 			break;
+ 		dequeue_pending_request(dpy, req);
+@@ -456,6 +442,7 @@ void _XSend(Display *dpy, const char *data, long size)
+ 	static char const pad[3];
+ 	struct iovec vec[3];
+ 	uint64_t requests;
++	uint64_t dpy_request;
+ 	_XExtension *ext;
+ 	xcb_connection_t *c = dpy->xcb->connection;
+ 	if(dpy->flags & XlibDisplayIOError)
+@@ -464,6 +451,10 @@ void _XSend(Display *dpy, const char *data, long size)
+ 	if(dpy->bufptr == dpy->buffer && !size)
+ 		return;
+ 
++	/* append_pending_request does not alter the dpy request number
++	 * therefore we can get it outside of the loop and the if
++	 */
++	dpy_request = X_DPY_GET_REQUEST(dpy);
+ 	/* 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,11 +462,11 @@ 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 <= dpy_request; ++sequence)
+ 			append_pending_request(dpy, sequence);
+ 	}
+-	requests = dpy->request - dpy->xcb->last_flushed;
+-	dpy->xcb->last_flushed = dpy->request;
++	requests = dpy_request - dpy->xcb->last_flushed;
++	dpy->xcb->last_flushed = dpy_request;
+ 
+ 	vec[0].iov_base = dpy->buffer;
+ 	vec[0].iov_len = dpy->bufptr - dpy->buffer;
+@@ -570,6 +561,7 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard)
+ 	xcb_connection_t *c = dpy->xcb->connection;
+ 	char *reply;
+ 	PendingRequest *current;
++	uint64_t dpy_request;
+ 
+ 	if (dpy->xcb->reply_data)
+ 		throw_extlib_fail_assert("Extra reply data still left in queue",
+@@ -579,10 +571,12 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard)
+ 		return 0;
+ 
+ 	_XSend(dpy, NULL, 0);
+-	if(dpy->xcb->pending_requests_tail && dpy->xcb->pending_requests_tail->sequence == dpy->request)
++	dpy_request = X_DPY_GET_REQUEST(dpy);
++	if(dpy->xcb->pending_requests_tail
++	   && dpy->xcb->pending_requests_tail->sequence == dpy_request)
+ 		current = dpy->xcb->pending_requests_tail;
+ 	else
+-		current = append_pending_request(dpy, dpy->request);
++		current = append_pending_request(dpy, dpy_request);
+ 	/* Don't let any other thread get this reply. */
+ 	current->reply_waiter = 1;
+ 
+@@ -599,9 +593,9 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard)
+ 		}
+ 		req->reply_waiter = 1;
+ 		UnlockDisplay(dpy);
+-		response = xcb_wait_for_reply(c, req->sequence, &error);
++		response = xcb_wait_for_reply64(c, req->sequence, &error);
+ 		/* Any user locks on another thread must have been taken
+-		 * while we slept in xcb_wait_for_reply. Classic Xlib
++		 * while we slept in xcb_wait_for_reply64. Classic Xlib
+ 		 * ignored those user locks in this case, so we do too. */
+ 		InternalLockDisplay(dpy, /* ignore user locks */ 1);
+ 
+@@ -629,12 +623,13 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard)
+ 
+ 		req->reply_waiter = 0;
+ 		ConditionBroadcast(dpy, dpy->xcb->reply_notify);
+-		if(XLIB_SEQUENCE_COMPARE(req->sequence, >, dpy->request)) {
++		dpy_request = X_DPY_GET_REQUEST(dpy);
++		if(XLIB_SEQUENCE_COMPARE(req->sequence, >, dpy_request)) {
+ 			throw_thread_fail_assert("Unknown sequence number "
+ 			                         "while processing reply",
+ 			                        xcb_xlib_threads_sequence_lost);
+ 		}
+-		dpy->last_request_read = req->sequence;
++		X_DPY_SET_LAST_REQUEST_READ(dpy, req->sequence);
+ 		if(!response)
+ 			dequeue_pending_request(dpy, req);
+ 
+@@ -654,9 +649,10 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard)
+ 	if(dpy->xcb->next_event && dpy->xcb->next_event->response_type == X_Error)
+ 	{
+ 		xcb_generic_event_t *event = dpy->xcb->next_event;
+-		unsigned long event_sequence = dpy->last_request_read;
++		uint64_t last_request_read = X_DPY_GET_LAST_REQUEST_READ(dpy);
++		uint64_t event_sequence = last_request_read;
+ 		widen(&event_sequence, event->full_sequence);
+-		if(event_sequence == dpy->last_request_read)
++		if(event_sequence == last_request_read)
+ 		{
+ 			error = (xcb_generic_error_t *) event;
+ 			dpy->xcb->next_event = NULL;
+-- 
+cgit v0.10.2
+
+--- a/include/X11/Xlibint.h.orig2	2017-03-11 09:35:16.131106050 -0800
++++ b/include/X11/Xlibint.h	2017-03-11 09:34:10.010324406 -0800
+@@ -38,6 +38,7 @@
+  *	Warning, there be dragons here....
+  */
+ 
++#include <stdint.h>
+ #include <X11/Xlib.h>
+ #include <X11/Xproto.h>		/* to declare xEvent */
+ #include <X11/XlibConf.h>	/* for configured options like XTHREADS */
+@@ -205,6 +206,10 @@
+ 		XGenericEventCookie *	/* in */,
+ 		XGenericEventCookie *   /* out*/);
+ 	void *cookiejar;  /* cookie events returned but not claimed */
++#ifndef LONG64
++	unsigned long last_request_read_upper32bit;
++	unsigned long request_upper32bit;
++#endif
+ };
+ 
+ #if defined(XTHREADS) && defined(SUNSOFT)
+@@ -212,7 +217,115 @@
+ #endif /* XTHREADS && SUNSOFT */
+ 
+ #define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n)
++/*
++ * access "last_request_read" and "request" with 64bit
++ * warning: the value argument of the SET-macros must not
++ * have any side-effects because it may get called twice.
++ */
++#ifndef LONG64
++/* accessors for 32-bit unsigned long */
+ 
++#define X_DPY_GET_REQUEST(dpy) \
++    ( \
++        ((uint64_t)(((struct _XDisplay*)dpy)->request)) \
++	+ (((uint64_t)(((struct _XDisplay*)dpy)->request_upper32bit)) << 32) \
++    )
++
++#define X_DPY_SET_REQUEST(dpy, value) \
++    ( \
++        (((struct _XDisplay*)dpy)->request = \
++            (value) & 0xFFFFFFFFUL), \
++        (((struct _XDisplay*)dpy)->request_upper32bit = \
++            ((uint64_t)(value)) >> 32), \
++	(void)0 /* don't use the result */ \
++    )
++
++#define X_DPY_GET_LAST_REQUEST_READ(dpy) \
++    ( \
++        ((uint64_t)(((struct _XDisplay*)dpy)->last_request_read)) \
++        + ( \
++            ((uint64_t)( \
++                ((struct _XDisplay*)dpy)->last_request_read_upper32bit \
++            )) << 32 \
++        ) \
++    )
++
++#define X_DPY_SET_LAST_REQUEST_READ(dpy, value) \
++    ( \
++        (((struct _XDisplay*)dpy)->last_request_read = \
++            (value) & 0xFFFFFFFFUL), \
++        (((struct _XDisplay*)dpy)->last_request_read_upper32bit = \
++            ((uint64_t)(value)) >> 32), \
++	(void)0 /* don't use the result */ \
++    )
++
++/*
++ * widen a 32-bit sequence number to a 64 sequence number.
++ * This macro makes the following assumptions:
++ * - ulseq refers to a sequence that has already been sent
++ * - ulseq means the most recent possible sequence number
++ *   with these lower 32 bits.
++ *
++ * The following optimization is used:
++ * The comparison result is taken a 0 or 1 to avoid a branch.
++ */
++#define X_DPY_WIDEN_UNSIGNED_LONG_SEQ(dpy, ulseq) \
++    ( \
++        ((uint64_t)ulseq) \
++        + \
++        (( \
++            ((uint64_t)(((struct _XDisplay*)dpy)->request_upper32bit)) \
++            - (uint64_t)( \
++                (ulseq) > (((struct _XDisplay*)dpy)->request) \
++	    ) \
++        ) << 32) \
++    )
++
++#define X_DPY_REQUEST_INCREMENT(dpy) \
++    ( \
++        ((struct _XDisplay*)dpy)->request++, \
++        ( \
++            (((struct _XDisplay*)dpy)->request == 0) ? ( \
++                ((struct _XDisplay*)dpy)->request_upper32bit++ \
++	    ) : 0 \
++        ), \
++	(void)0 /* don't use the result */ \
++    )
++
++
++#define X_DPY_REQUEST_DECREMENT(dpy) \
++    ( \
++	( \
++            (((struct _XDisplay*)dpy)->request == 0) ? (\
++                ((struct _XDisplay*)dpy)->request--, /* wrap */ \
++                ((struct _XDisplay*)dpy)->request_upper32bit-- \
++            ) : ( \
++                ((struct _XDisplay*)dpy)->request-- \
++            ) \
++	), \
++	(void)0 /* don't use the result */ \
++    )
++
++#else
++/* accessors for 64-bit unsigned long */
++#define X_DPY_GET_REQUEST(dpy) \
++    (((struct _XDisplay*)dpy)->request)
++#define X_DPY_SET_REQUEST(dpy, value) \
++    ((struct _XDisplay*)dpy)->request = (value)
++
++#define X_DPY_GET_LAST_REQUEST_READ(dpy) \
++    (((struct _XDisplay*)dpy)->last_request_read)
++#define X_DPY_SET_LAST_REQUEST_READ(dpy, value) \
++    ((struct _XDisplay*)dpy)->last_request_read = (value)
++
++#define X_DPY_WIDEN_UNSIGNED_LONG_SEQ(dpy, ulseq) ulseq
++
++#define X_DPY_REQUEST_INCREMENT(dpy) ((struct _XDisplay*)dpy)->request++
++#define X_DPY_REQUEST_DECREMENT(dpy) ((struct _XDisplay*)dpy)->request--
++#endif
++
++
++
+ #ifndef _XEVENT_
+ /*
+  * _QEvent datatype for use in input queueing.
+@@ -677,6 +790,11 @@
+     XPointer data;
+ } _XAsyncHandler;
+ 
++/*
++ * This struct is part of the ABI and is defined by value
++ * in user-code. This means that we cannot make
++ * the sequence-numbers 64bit.
++ */
+ typedef struct _XAsyncEState {
+     unsigned long min_sequence_number;
+     unsigned long max_sequence_number;
--- a/open-src/lib/libX11/Makefile	Fri Apr 07 15:26:24 2017 -0700
+++ b/open-src/lib/libX11/Makefile	Wed Apr 12 06:57:07 2017 +0000
@@ -1,6 +1,6 @@
 ###############################################################################
 #
-# Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the "Software"),
@@ -67,7 +67,8 @@
 	locale-zh_CN.gb18030.patch,-p1 \
 	locale-zh_HK.UTF-8.patch,-p1 \
 	locale-zh_TW.UTF-8.patch,-p1 \
-	locale-zh_TW.patch,-p1
+	locale-zh_TW.patch,-p1 \
+	19154747.patch,-p1
 
 # Library name (used for specfiles/mapfiles)
 LIBNAME=X11
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/lib/libxcb/19154747.patch	Wed Apr 12 06:57:07 2017 +0000
@@ -0,0 +1,235 @@
+From 0ba6fe9b4eaa70383cd2ee066dfb3f1e67efeb83 Mon Sep 17 00:00:00 2001
+From: Christian Linhart <[email protected]>
+Date: Wed, 29 Apr 2015 09:11:37 +0200
+Subject: expose 64-bit sequence numbers for XLib
+
+While XCB uses 64-bit sequence number internally, it only exposes
+"unsigned int" so that, on 32-bit architecture, Xlib based applications
+may see their sequence number wrap which causes the connection to the X
+server to be lost.
+
+Expose 64-bit sequence number from XCB API so that Xlib and others can
+use it even on 32-bit environment.
+
+This implies the following API addition:
+
+  xcb_send_request64()
+  xcb_discard_reply64()
+  xcb_wait_for_reply64()
+  xcb_poll_for_reply64()
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=71338
+
+Reviewed-by: Uli Schlachter <[email protected]>
+Signed-off-by: Christian Linhart <[email protected]>
+Signed-off-by: Olivier Fourdan <[email protected]>
+
+diff --git a/src/xcb.h b/src/xcb.h
+index 23fe74e..86eb1bc 100644
+--- a/src/xcb.h
++++ b/src/xcb.h
+@@ -378,6 +378,26 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co
+  */
+ void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence);
+ 
++/**
++ * @brief Discards the reply for a request, given by a 64bit sequence number
++ * @param c: The connection to the X server.
++ * @param sequence: 64-bit sequence number as returned by xcb_send_request64().
++ *
++ * Discards the reply for a request. Additionally, any error generated
++ * by the request is also discarded (unless it was an _unchecked request
++ * and the error has already arrived).
++ *
++ * This function will not block even if the reply is not yet available.
++ *
++ * Note that the sequence really does have to come from xcb_send_request64();
++ * the cookie sequence number is defined as "unsigned" int and therefore
++ * not 64-bit on all platforms.
++ * This function is not designed to operate on socket-handoff replies.
++ *
++ * Unlike its xcb_discard_reply() counterpart, the given sequence number is not
++ * automatically "widened" to 64-bit.
++ */
++void xcb_discard_reply64(xcb_connection_t *c, uint64_t sequence);
+ 
+ /* xcb_ext.c */
+ 
+diff --git a/src/xcb_in.c b/src/xcb_in.c
+index ad870c1..623a0a8 100644
+--- a/src/xcb_in.c
++++ b/src/xcb_in.c
+@@ -523,6 +523,20 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_
+     return ret;
+ }
+ 
++void *xcb_wait_for_reply64(xcb_connection_t *c, uint64_t request, xcb_generic_error_t **e)
++{
++    void *ret;
++    if(e)
++        *e = 0;
++    if(c->has_error)
++        return 0;
++
++    pthread_mutex_lock(&c->iolock);
++    ret = wait_for_reply(c, request, e);
++    pthread_mutex_unlock(&c->iolock);
++    return ret;
++}
++
+ int *xcb_get_reply_fds(xcb_connection_t *c, void *reply, size_t reply_size)
+ {
+     return (int *) (&((char *) reply)[reply_size]);
+@@ -595,6 +609,20 @@ void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence)
+     pthread_mutex_unlock(&c->iolock);
+ }
+ 
++void xcb_discard_reply64(xcb_connection_t *c, uint64_t sequence)
++{
++    if(c->has_error)
++        return;
++
++    /* If an error occurred when issuing the request, fail immediately. */
++    if(!sequence)
++        return;
++
++    pthread_mutex_lock(&c->iolock);
++    discard_reply(c, sequence);
++    pthread_mutex_unlock(&c->iolock);
++}
++
+ int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply, xcb_generic_error_t **error)
+ {
+     int ret;
+@@ -612,6 +640,23 @@ int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply,
+     return ret;
+ }
+ 
++int xcb_poll_for_reply64(xcb_connection_t *c, uint64_t request, void **reply, xcb_generic_error_t **error)
++{
++    int ret;
++    if(c->has_error)
++    {
++        *reply = 0;
++        if(error)
++            *error = 0;
++        return 1; /* would not block */
++    }
++    assert(reply != 0);
++    pthread_mutex_lock(&c->iolock);
++    ret = poll_for_reply(c, request, reply, error);
++    pthread_mutex_unlock(&c->iolock);
++    return ret;
++}
++
+ xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c)
+ {
+     xcb_generic_event_t *ret;
+diff --git a/src/xcb_out.c b/src/xcb_out.c
+index dc42954..8cc5be8 100644
+--- a/src/xcb_out.c
++++ b/src/xcb_out.c
+@@ -177,7 +177,7 @@ uint32_t xcb_get_maximum_request_length(xcb_connection_t *c)
+     return c->out.maximum_request_length.value;
+ }
+ 
+-unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
++uint64_t xcb_send_request64(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
+ {
+     uint64_t request;
+     uint32_t prefix[2];
+@@ -286,6 +286,12 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
+     return request;
+ }
+ 
++/* request number are actually uint64_t internally but keep API compat with unsigned int */
++unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
++{
++    return xcb_send_request64(c, flags, vector, req);
++}
++
+ void
+ xcb_send_fd(xcb_connection_t *c, int fd)
+ {
+diff --git a/src/xcbext.h b/src/xcbext.h
+index 7587513..b2575f7 100644
+--- a/src/xcbext.h
++++ b/src/xcbext.h
+@@ -83,6 +83,30 @@ enum xcb_send_request_flags_t {
+ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request);
+ 
+ /**
++ * @brief Send a request to the server, with 64-bit sequence number returned.
++ * @param c: The connection to the X server.
++ * @param flags: A combination of flags from the xcb_send_request_flags_t enumeration.
++ * @param vector: Data to send; must have two iovecs before start for internal use.
++ * @param request: Information about the request to be sent.
++ * @return The request's sequence number on success, 0 otherwise.
++ *
++ * This function sends a new request to the X server. The data of the request is
++ * given as an array of @c iovecs in the @p vector argument. The length of that
++ * array and the neccessary management information are given in the @p request
++ * argument.
++ *
++ * When this function returns, the request might or might not be sent already.
++ * Use xcb_flush() to make sure that it really was sent.
++ *
++ * Please note that this function is not the prefered way for sending requests.
++ * It's better to use the generated wrapper functions.
++ *
++ * Please note that xcb might use index -1 and -2 of the @p vector array internally,
++ * so they must be valid!
++ */
++uint64_t xcb_send_request64(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request);
++
++/**
+  * @brief Send a file descriptor to the server in the next call to xcb_send_request.
+  * @param c: The connection to the X server.
+  * @param fd: The file descriptor to send.
+@@ -162,6 +186,21 @@ int xcb_writev(xcb_connection_t *c, struct iovec *vector, int count, uint64_t re
+ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e);
+ 
+ /**
++ * @brief Wait for the reply of a given request, with 64-bit sequence number
++ * @param c: The connection to the X server.
++ * @param request: 64-bit sequence number of the request as returned by xcb_send_request64().
++ * @param e: Location to store errors in, or NULL. Ignored for unchecked requests.
++ *
++ * Returns the reply to the given request or returns null in the event of
++ * errors. Blocks until the reply or error for the request arrives, or an I/O
++ * error occurs.
++ *
++ * Unlike its xcb_wait_for_reply() counterpart, the given sequence number is not
++ * automatically "widened" to 64-bit.
++ */
++void *xcb_wait_for_reply64(xcb_connection_t *c, uint64_t request, xcb_generic_error_t **e);
++
++/**
+  * @brief Poll for the reply of a given request.
+  * @param c: The connection to the X server.
+  * @param request: Sequence number of the request as returned by xcb_send_request().
+@@ -174,6 +213,21 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_
+ int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply, xcb_generic_error_t **error);
+ 
+ /**
++ * @brief Poll for the reply of a given request, with 64-bit sequence number.
++ * @param c: The connection to the X server.
++ * @param request: 64-bit sequence number of the request as returned by xcb_send_request().
++ * @param reply: Location to store the reply in, must not be NULL.
++ * @param e: Location to store errors in, or NULL. Ignored for unchecked requests.
++ * @return 1 when the reply to the request was returned, else 0.
++ *
++ * Checks if the reply to the given request already received. Does not block.
++ *
++ * Unlike its xcb_poll_for_reply() counterpart, the given sequence number is not
++ * automatically "widened" to 64-bit.
++ */
++int xcb_poll_for_reply64(xcb_connection_t *c, uint64_t request, void **reply, xcb_generic_error_t **error);
++
++/**
+  * @brief Don't use this, only needed by the generated code.
+  * @param c: The connection to the X server.
+  * @param reply: A reply that was received from the server
+-- 
+cgit v0.10.2
+
--- a/open-src/lib/libxcb/Makefile	Fri Apr 07 15:26:24 2017 -0700
+++ b/open-src/lib/libxcb/Makefile	Wed Apr 12 06:57:07 2017 +0000
@@ -2,7 +2,7 @@
 #
 # xcb - Lighter weight X11 client libraries
 #
-# Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the "Software"),
@@ -46,6 +46,7 @@
 # Patches to apply to source after unpacking, in order
 SOURCE_PATCHES  = Makefile.am.0.patch,-p1
 SOURCE_PATCHES += manpage.patch
+SOURCE_PATCHES += 19154747.patch,-p1
 
 # Regenerate Makefile.in's from Makefile.am's after patching them
 AUTORECONF=yes