Hi all, Just a quick reminder about this patch, this had been reviewed initially by ajax, all I did was add the requirement in configure script for the recently released libxcb-1.11.1 which features the new 64bit API required for this patch to work.
Cheers, Olivier ----- Original Message ----- > From: Christian Linhart <ch...@demorecorder.com> > > 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 <ch...@demorecorder.com> > Signed-off-by: Olivier Fourdan <ofour...@redhat.com> > Reviewed-by: Adam Jackson <a...@redhat.com> > --- > v1: Original version sent by Christian Linhart > v2: Updated patch from Olivier Fourdan reviewed by Adam Jackson > http://patchwork.freedesktop.org/patch/46062/ > v3: Updated patch to add dependency on new official release 1.11.1 > of libXCB which contains the required API for 64-bit seq. no. > > configure.ac | 4 +- > include/X11/Xlibint.h | 118 > ++++++++++++++++++++++++++++++++++++++++++++++++++ > src/ClDisplay.c | 2 +- > src/Font.c | 2 +- > src/GetAtomNm.c | 13 +++--- > src/GetWAttrs.c | 13 +++--- > src/IntAtom.c | 14 +++--- > src/OpenDis.c | 4 +- > src/PutImage.c | 2 +- > src/XlibAsync.c | 18 ++++++-- > src/XlibInt.c | 31 +++++++------ > src/Xxcbint.h | 4 +- > src/xcb_io.c | 80 ++++++++++++++++------------------ > 13 files changed, 219 insertions(+), 86 deletions(-) > > 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.1' > +X11_EXTRA_DEPS="xcb >= 1.11.1" > > PKG_PROG_PKG_CONFIG() > > diff --git a/include/X11/Xlibint.h b/include/X11/Xlibint.h > index 4431559..d2563d6 100644 > --- a/include/X11/Xlibint.h > +++ b/include/X11/Xlibint.h > @@ -38,6 +38,7 @@ from The Open Group. > * 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,10 +206,122 @@ struct _XDisplay > 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 > }; > > #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. > @@ -673,6 +786,11 @@ typedef struct _XInternalAsync { > 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; > 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; > -- > 2.4.3 > > _______________________________________________ > 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 _______________________________________________ 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