|
|
6911ea |
diff --git a/include/X11/Xlibint.h b/include/X11/Xlibint.h
|
|
|
6911ea |
index 4431559..d2563d6 100644
|
|
|
6911ea |
--- a/include/X11/Xlibint.h
|
|
|
6911ea |
+++ b/include/X11/Xlibint.h
|
|
|
6911ea |
@@ -38,6 +38,7 @@ from The Open Group.
|
|
|
6911ea |
* Warning, there be dragons here....
|
|
|
6911ea |
*/
|
|
|
6911ea |
|
|
|
6911ea |
+#include <stdint.h>
|
|
|
6911ea |
#include <X11/Xlib.h>
|
|
|
6911ea |
#include <X11/Xproto.h> /* to declare xEvent */
|
|
|
6911ea |
#include <X11/XlibConf.h> /* for configured options like XTHREADS */
|
|
|
6911ea |
@@ -205,10 +206,122 @@ struct _XDisplay
|
|
|
6911ea |
XGenericEventCookie * /* in */,
|
|
|
6911ea |
XGenericEventCookie * /* out*/);
|
|
|
6911ea |
void *cookiejar; /* cookie events returned but not claimed */
|
|
|
6911ea |
+#ifndef LONG64
|
|
|
6911ea |
+ unsigned long last_request_read_upper32bit;
|
|
|
6911ea |
+ unsigned long request_upper32bit;
|
|
|
6911ea |
+#endif
|
|
|
6911ea |
};
|
|
|
6911ea |
|
|
|
6911ea |
#define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n)
|
|
|
6911ea |
|
|
|
6911ea |
+/*
|
|
|
6911ea |
+ * access "last_request_read" and "request" with 64bit
|
|
|
6911ea |
+ * warning: the value argument of the SET-macros must not
|
|
|
6911ea |
+ * have any side-effects because it may get called twice.
|
|
|
6911ea |
+ */
|
|
|
6911ea |
+#ifndef LONG64
|
|
|
6911ea |
+/* accessors for 32-bit unsigned long */
|
|
|
6911ea |
+
|
|
|
6911ea |
+#define X_DPY_GET_REQUEST(dpy) \
|
|
|
6911ea |
+ ( \
|
|
|
6911ea |
+ ((uint64_t)(((struct _XDisplay*)dpy)->request)) \
|
|
|
6911ea |
+ + (((uint64_t)(((struct _XDisplay*)dpy)->request_upper32bit)) << 32) \
|
|
|
6911ea |
+ )
|
|
|
6911ea |
+
|
|
|
6911ea |
+#define X_DPY_SET_REQUEST(dpy, value) \
|
|
|
6911ea |
+ ( \
|
|
|
6911ea |
+ (((struct _XDisplay*)dpy)->request = \
|
|
|
6911ea |
+ (value) & 0xFFFFFFFFUL), \
|
|
|
6911ea |
+ (((struct _XDisplay*)dpy)->request_upper32bit = \
|
|
|
6911ea |
+ ((uint64_t)(value)) >> 32), \
|
|
|
6911ea |
+ (void)0 /* don't use the result */ \
|
|
|
6911ea |
+ )
|
|
|
6911ea |
+
|
|
|
6911ea |
+#define X_DPY_GET_LAST_REQUEST_READ(dpy) \
|
|
|
6911ea |
+ ( \
|
|
|
6911ea |
+ ((uint64_t)(((struct _XDisplay*)dpy)->last_request_read)) \
|
|
|
6911ea |
+ + ( \
|
|
|
6911ea |
+ ((uint64_t)( \
|
|
|
6911ea |
+ ((struct _XDisplay*)dpy)->last_request_read_upper32bit \
|
|
|
6911ea |
+ )) << 32 \
|
|
|
6911ea |
+ ) \
|
|
|
6911ea |
+ )
|
|
|
6911ea |
+
|
|
|
6911ea |
+#define X_DPY_SET_LAST_REQUEST_READ(dpy, value) \
|
|
|
6911ea |
+ ( \
|
|
|
6911ea |
+ (((struct _XDisplay*)dpy)->last_request_read = \
|
|
|
6911ea |
+ (value) & 0xFFFFFFFFUL), \
|
|
|
6911ea |
+ (((struct _XDisplay*)dpy)->last_request_read_upper32bit = \
|
|
|
6911ea |
+ ((uint64_t)(value)) >> 32), \
|
|
|
6911ea |
+ (void)0 /* don't use the result */ \
|
|
|
6911ea |
+ )
|
|
|
6911ea |
+
|
|
|
6911ea |
+/*
|
|
|
6911ea |
+ * widen a 32-bit sequence number to a 64 sequence number.
|
|
|
6911ea |
+ * This macro makes the following assumptions:
|
|
|
6911ea |
+ * - ulseq refers to a sequence that has already been sent
|
|
|
6911ea |
+ * - ulseq means the most recent possible sequence number
|
|
|
6911ea |
+ * with these lower 32 bits.
|
|
|
6911ea |
+ *
|
|
|
6911ea |
+ * The following optimization is used:
|
|
|
6911ea |
+ * The comparison result is taken a 0 or 1 to avoid a branch.
|
|
|
6911ea |
+ */
|
|
|
6911ea |
+#define X_DPY_WIDEN_UNSIGNED_LONG_SEQ(dpy, ulseq) \
|
|
|
6911ea |
+ ( \
|
|
|
6911ea |
+ ((uint64_t)ulseq) \
|
|
|
6911ea |
+ + \
|
|
|
6911ea |
+ (( \
|
|
|
6911ea |
+ ((uint64_t)(((struct _XDisplay*)dpy)->request_upper32bit)) \
|
|
|
6911ea |
+ - (uint64_t)( \
|
|
|
6911ea |
+ (ulseq) > (((struct _XDisplay*)dpy)->request) \
|
|
|
6911ea |
+ ) \
|
|
|
6911ea |
+ ) << 32) \
|
|
|
6911ea |
+ )
|
|
|
6911ea |
+
|
|
|
6911ea |
+#define X_DPY_REQUEST_INCREMENT(dpy) \
|
|
|
6911ea |
+ ( \
|
|
|
6911ea |
+ ((struct _XDisplay*)dpy)->request++, \
|
|
|
6911ea |
+ ( \
|
|
|
6911ea |
+ (((struct _XDisplay*)dpy)->request == 0) ? ( \
|
|
|
6911ea |
+ ((struct _XDisplay*)dpy)->request_upper32bit++ \
|
|
|
6911ea |
+ ) : 0 \
|
|
|
6911ea |
+ ), \
|
|
|
6911ea |
+ (void)0 /* don't use the result */ \
|
|
|
6911ea |
+ )
|
|
|
6911ea |
+
|
|
|
6911ea |
+
|
|
|
6911ea |
+#define X_DPY_REQUEST_DECREMENT(dpy) \
|
|
|
6911ea |
+ ( \
|
|
|
6911ea |
+ ( \
|
|
|
6911ea |
+ (((struct _XDisplay*)dpy)->request == 0) ? (\
|
|
|
6911ea |
+ ((struct _XDisplay*)dpy)->request--, /* wrap */ \
|
|
|
6911ea |
+ ((struct _XDisplay*)dpy)->request_upper32bit-- \
|
|
|
6911ea |
+ ) : ( \
|
|
|
6911ea |
+ ((struct _XDisplay*)dpy)->request-- \
|
|
|
6911ea |
+ ) \
|
|
|
6911ea |
+ ), \
|
|
|
6911ea |
+ (void)0 /* don't use the result */ \
|
|
|
6911ea |
+ )
|
|
|
6911ea |
+
|
|
|
6911ea |
+#else
|
|
|
6911ea |
+/* accessors for 64-bit unsigned long */
|
|
|
6911ea |
+#define X_DPY_GET_REQUEST(dpy) \
|
|
|
6911ea |
+ (((struct _XDisplay*)dpy)->request)
|
|
|
6911ea |
+#define X_DPY_SET_REQUEST(dpy, value) \
|
|
|
6911ea |
+ ((struct _XDisplay*)dpy)->request = (value)
|
|
|
6911ea |
+
|
|
|
6911ea |
+#define X_DPY_GET_LAST_REQUEST_READ(dpy) \
|
|
|
6911ea |
+ (((struct _XDisplay*)dpy)->last_request_read)
|
|
|
6911ea |
+#define X_DPY_SET_LAST_REQUEST_READ(dpy, value) \
|
|
|
6911ea |
+ ((struct _XDisplay*)dpy)->last_request_read = (value)
|
|
|
6911ea |
+
|
|
|
6911ea |
+#define X_DPY_WIDEN_UNSIGNED_LONG_SEQ(dpy, ulseq) ulseq
|
|
|
6911ea |
+
|
|
|
6911ea |
+#define X_DPY_REQUEST_INCREMENT(dpy) ((struct _XDisplay*)dpy)->request++
|
|
|
6911ea |
+#define X_DPY_REQUEST_DECREMENT(dpy) ((struct _XDisplay*)dpy)->request--
|
|
|
6911ea |
+#endif
|
|
|
6911ea |
+
|
|
|
6911ea |
+
|
|
|
6911ea |
#ifndef _XEVENT_
|
|
|
6911ea |
/*
|
|
|
6911ea |
* _QEvent datatype for use in input queueing.
|
|
|
6911ea |
@@ -673,6 +786,11 @@ typedef struct _XInternalAsync {
|
|
|
6911ea |
XPointer data;
|
|
|
6911ea |
} _XAsyncHandler;
|
|
|
6911ea |
|
|
|
6911ea |
+/*
|
|
|
6911ea |
+ * This struct is part of the ABI and is defined by value
|
|
|
6911ea |
+ * in user-code. This means that we cannot make
|
|
|
6911ea |
+ * the sequence-numbers 64bit.
|
|
|
6911ea |
+ */
|
|
|
6911ea |
typedef struct _XAsyncEState {
|
|
|
6911ea |
unsigned long min_sequence_number;
|
|
|
6911ea |
unsigned long max_sequence_number;
|
|
|
6911ea |
diff --git a/src/ClDisplay.c b/src/ClDisplay.c
|
|
|
6911ea |
index bddd773..aa904e5 100644
|
|
|
6911ea |
--- a/src/ClDisplay.c
|
|
|
6911ea |
+++ b/src/ClDisplay.c
|
|
|
6911ea |
@@ -65,7 +65,7 @@ XCloseDisplay (
|
|
|
6911ea |
(*ext->close_display)(dpy, &ext->codes);
|
|
|
6911ea |
}
|
|
|
6911ea |
/* if the closes generated more protocol, sync them up */
|
|
|
6911ea |
- if (dpy->request != dpy->last_request_read)
|
|
|
6911ea |
+ if (X_DPY_GET_REQUEST(dpy) != X_DPY_GET_LAST_REQUEST_READ(dpy))
|
|
|
6911ea |
XSync(dpy, 1);
|
|
|
6911ea |
}
|
|
|
6911ea |
xcb_disconnect(dpy->xcb->connection);
|
|
|
6911ea |
diff --git a/src/Font.c b/src/Font.c
|
|
|
6911ea |
index 650bc6f..a73f9b1 100644
|
|
|
6911ea |
--- a/src/Font.c
|
|
|
6911ea |
+++ b/src/Font.c
|
|
|
6911ea |
@@ -105,7 +105,7 @@ XFontStruct *XLoadQueryFont(
|
|
|
6911ea |
return font_result;
|
|
|
6911ea |
LockDisplay(dpy);
|
|
|
6911ea |
GetReq(OpenFont, req);
|
|
|
6911ea |
- seq = dpy->request;
|
|
|
6911ea |
+ seq = dpy->request; /* Can't use extended sequence number here */
|
|
|
6911ea |
nbytes = req->nbytes = name ? strlen(name) : 0;
|
|
|
6911ea |
req->fid = fid = XAllocID(dpy);
|
|
|
6911ea |
req->length += (nbytes+3)>>2;
|
|
|
6911ea |
diff --git a/src/GetAtomNm.c b/src/GetAtomNm.c
|
|
|
6911ea |
index 32de50d..d7f06e3 100644
|
|
|
6911ea |
--- a/src/GetAtomNm.c
|
|
|
6911ea |
+++ b/src/GetAtomNm.c
|
|
|
6911ea |
@@ -87,8 +87,8 @@ char *XGetAtomName(
|
|
|
6911ea |
}
|
|
|
6911ea |
|
|
|
6911ea |
typedef struct {
|
|
|
6911ea |
- unsigned long start_seq;
|
|
|
6911ea |
- unsigned long stop_seq;
|
|
|
6911ea |
+ uint64_t start_seq;
|
|
|
6911ea |
+ uint64_t stop_seq;
|
|
|
6911ea |
Atom *atoms;
|
|
|
6911ea |
char **names;
|
|
|
6911ea |
int idx;
|
|
|
6911ea |
@@ -107,10 +107,11 @@ Bool _XGetAtomNameHandler(
|
|
|
6911ea |
register _XGetAtomNameState *state;
|
|
|
6911ea |
xGetAtomNameReply replbuf;
|
|
|
6911ea |
register xGetAtomNameReply *repl;
|
|
|
6911ea |
+ uint64_t last_request_read = X_DPY_GET_LAST_REQUEST_READ(dpy);
|
|
|
6911ea |
|
|
|
6911ea |
state = (_XGetAtomNameState *)data;
|
|
|
6911ea |
- if (dpy->last_request_read < state->start_seq ||
|
|
|
6911ea |
- dpy->last_request_read > state->stop_seq)
|
|
|
6911ea |
+ if (last_request_read < state->start_seq ||
|
|
|
6911ea |
+ last_request_read > state->stop_seq)
|
|
|
6911ea |
return False;
|
|
|
6911ea |
while (state->idx < state->count && state->names[state->idx])
|
|
|
6911ea |
state->idx++;
|
|
|
6911ea |
@@ -152,7 +153,7 @@ XGetAtomNames (
|
|
|
6911ea |
int missed = -1;
|
|
|
6911ea |
|
|
|
6911ea |
LockDisplay(dpy);
|
|
|
6911ea |
- async_state.start_seq = dpy->request + 1;
|
|
|
6911ea |
+ async_state.start_seq = X_DPY_GET_REQUEST(dpy) + 1;
|
|
|
6911ea |
async_state.atoms = atoms;
|
|
|
6911ea |
async_state.names = names_return;
|
|
|
6911ea |
async_state.idx = 0;
|
|
|
6911ea |
@@ -165,7 +166,7 @@ XGetAtomNames (
|
|
|
6911ea |
for (i = 0; i < count; i++) {
|
|
|
6911ea |
if (!(names_return[i] = _XGetAtomName(dpy, atoms[i]))) {
|
|
|
6911ea |
missed = i;
|
|
|
6911ea |
- async_state.stop_seq = dpy->request;
|
|
|
6911ea |
+ async_state.stop_seq = X_DPY_GET_REQUEST(dpy);
|
|
|
6911ea |
}
|
|
|
6911ea |
}
|
|
|
6911ea |
if (missed >= 0) {
|
|
|
6911ea |
diff --git a/src/GetWAttrs.c b/src/GetWAttrs.c
|
|
|
6911ea |
index c10824c..0f5f7bb 100644
|
|
|
6911ea |
--- a/src/GetWAttrs.c
|
|
|
6911ea |
+++ b/src/GetWAttrs.c
|
|
|
6911ea |
@@ -30,8 +30,8 @@ in this Software without prior written authorization from The Open Group.
|
|
|
6911ea |
#include "Xlibint.h"
|
|
|
6911ea |
|
|
|
6911ea |
typedef struct _WAttrsState {
|
|
|
6911ea |
- unsigned long attr_seq;
|
|
|
6911ea |
- unsigned long geom_seq;
|
|
|
6911ea |
+ uint64_t attr_seq;
|
|
|
6911ea |
+ uint64_t geom_seq;
|
|
|
6911ea |
XWindowAttributes *attr;
|
|
|
6911ea |
} _XWAttrsState;
|
|
|
6911ea |
|
|
|
6911ea |
@@ -47,10 +47,11 @@ _XWAttrsHandler(
|
|
|
6911ea |
xGetWindowAttributesReply replbuf;
|
|
|
6911ea |
register xGetWindowAttributesReply *repl;
|
|
|
6911ea |
register XWindowAttributes *attr;
|
|
|
6911ea |
+ uint64_t last_request_read = X_DPY_GET_LAST_REQUEST_READ(dpy);
|
|
|
6911ea |
|
|
|
6911ea |
state = (_XWAttrsState *)data;
|
|
|
6911ea |
- if (dpy->last_request_read != state->attr_seq) {
|
|
|
6911ea |
- if (dpy->last_request_read == state->geom_seq &&
|
|
|
6911ea |
+ if (last_request_read != state->attr_seq) {
|
|
|
6911ea |
+ if (last_request_read == state->geom_seq &&
|
|
|
6911ea |
!state->attr &&
|
|
|
6911ea |
rep->generic.type == X_Error &&
|
|
|
6911ea |
rep->error.errorCode == BadDrawable)
|
|
|
6911ea |
@@ -99,7 +100,7 @@ _XGetWindowAttributes(
|
|
|
6911ea |
|
|
|
6911ea |
GetResReq(GetWindowAttributes, w, req);
|
|
|
6911ea |
|
|
|
6911ea |
- async_state.attr_seq = dpy->request;
|
|
|
6911ea |
+ async_state.attr_seq = X_DPY_GET_REQUEST(dpy);
|
|
|
6911ea |
async_state.geom_seq = 0;
|
|
|
6911ea |
async_state.attr = attr;
|
|
|
6911ea |
async.next = dpy->async_handlers;
|
|
|
6911ea |
@@ -109,7 +110,7 @@ _XGetWindowAttributes(
|
|
|
6911ea |
|
|
|
6911ea |
GetResReq(GetGeometry, w, req);
|
|
|
6911ea |
|
|
|
6911ea |
- async_state.geom_seq = dpy->request;
|
|
|
6911ea |
+ async_state.geom_seq = X_DPY_GET_REQUEST(dpy);
|
|
|
6911ea |
|
|
|
6911ea |
if (!_XReply (dpy, (xReply *)&rep, 0, xTrue)) {
|
|
|
6911ea |
DeqAsyncHandler(dpy, &async);
|
|
|
6911ea |
diff --git a/src/IntAtom.c b/src/IntAtom.c
|
|
|
6911ea |
index 3042b65..d9c6c58 100644
|
|
|
6911ea |
--- a/src/IntAtom.c
|
|
|
6911ea |
+++ b/src/IntAtom.c
|
|
|
6911ea |
@@ -188,8 +188,8 @@ XInternAtom (
|
|
|
6911ea |
}
|
|
|
6911ea |
|
|
|
6911ea |
typedef struct {
|
|
|
6911ea |
- unsigned long start_seq;
|
|
|
6911ea |
- unsigned long stop_seq;
|
|
|
6911ea |
+ uint64_t start_seq;
|
|
|
6911ea |
+ uint64_t stop_seq;
|
|
|
6911ea |
char **names;
|
|
|
6911ea |
Atom *atoms;
|
|
|
6911ea |
int count;
|
|
|
6911ea |
@@ -208,10 +208,12 @@ Bool _XIntAtomHandler(
|
|
|
6911ea |
register int i, idx = 0;
|
|
|
6911ea |
xInternAtomReply replbuf;
|
|
|
6911ea |
register xInternAtomReply *repl;
|
|
|
6911ea |
+ uint64_t last_request_read = X_DPY_GET_LAST_REQUEST_READ(dpy);
|
|
|
6911ea |
|
|
|
6911ea |
state = (_XIntAtomState *)data;
|
|
|
6911ea |
- if (dpy->last_request_read < state->start_seq ||
|
|
|
6911ea |
- dpy->last_request_read > state->stop_seq)
|
|
|
6911ea |
+
|
|
|
6911ea |
+ if (last_request_read < state->start_seq ||
|
|
|
6911ea |
+ last_request_read > state->stop_seq)
|
|
|
6911ea |
return False;
|
|
|
6911ea |
for (i = 0; i < state->count; i++) {
|
|
|
6911ea |
if (state->atoms[i] & 0x80000000) {
|
|
|
6911ea |
@@ -252,7 +254,7 @@ XInternAtoms (
|
|
|
6911ea |
xInternAtomReply rep;
|
|
|
6911ea |
|
|
|
6911ea |
LockDisplay(dpy);
|
|
|
6911ea |
- async_state.start_seq = dpy->request + 1;
|
|
|
6911ea |
+ async_state.start_seq = X_DPY_GET_REQUEST(dpy) + 1;
|
|
|
6911ea |
async_state.atoms = atoms_return;
|
|
|
6911ea |
async_state.names = names;
|
|
|
6911ea |
async_state.count = count - 1;
|
|
|
6911ea |
@@ -266,7 +268,7 @@ XInternAtoms (
|
|
|
6911ea |
&sig, &idx, &n))) {
|
|
|
6911ea |
missed = i;
|
|
|
6911ea |
atoms_return[i] = ~((Atom)idx);
|
|
|
6911ea |
- async_state.stop_seq = dpy->request;
|
|
|
6911ea |
+ async_state.stop_seq = X_DPY_GET_REQUEST(dpy);
|
|
|
6911ea |
}
|
|
|
6911ea |
}
|
|
|
6911ea |
if (missed >= 0) {
|
|
|
6911ea |
diff --git a/src/OpenDis.c b/src/OpenDis.c
|
|
|
6911ea |
index 636860e..8272357 100644
|
|
|
6911ea |
--- a/src/OpenDis.c
|
|
|
6911ea |
+++ b/src/OpenDis.c
|
|
|
6911ea |
@@ -197,8 +197,8 @@ XOpenDisplay (
|
|
|
6911ea |
dpy->idlist_alloc = _XAllocIDs;
|
|
|
6911ea |
dpy->synchandler = NULL;
|
|
|
6911ea |
dpy->savedsynchandler = NULL;
|
|
|
6911ea |
- dpy->request = 0;
|
|
|
6911ea |
- dpy->last_request_read = 0;
|
|
|
6911ea |
+ X_DPY_SET_REQUEST(dpy, 0);
|
|
|
6911ea |
+ X_DPY_SET_LAST_REQUEST_READ(dpy, 0);
|
|
|
6911ea |
dpy->default_screen = iscreen; /* Value returned by ConnectDisplay */
|
|
|
6911ea |
dpy->last_req = (char *)&_dummy_request;
|
|
|
6911ea |
|
|
|
6911ea |
diff --git a/src/PutImage.c b/src/PutImage.c
|
|
|
6911ea |
index de085bc..13cbba3 100644
|
|
|
6911ea |
--- a/src/PutImage.c
|
|
|
6911ea |
+++ b/src/PutImage.c
|
|
|
6911ea |
@@ -602,7 +602,7 @@ static int const HalfOrderWord[12] = {
|
|
|
6911ea |
|
|
|
6911ea |
#define UnGetReq(name)\
|
|
|
6911ea |
dpy->bufptr -= SIZEOF(x##name##Req);\
|
|
|
6911ea |
- dpy->request--
|
|
|
6911ea |
+ X_DPY_REQUEST_DECREMENT(dpy)
|
|
|
6911ea |
|
|
|
6911ea |
static void
|
|
|
6911ea |
SendXYImage(
|
|
|
6911ea |
diff --git a/src/XlibAsync.c b/src/XlibAsync.c
|
|
|
6911ea |
index eb2b819..d62000e 100644
|
|
|
6911ea |
--- a/src/XlibAsync.c
|
|
|
6911ea |
+++ b/src/XlibAsync.c
|
|
|
6911ea |
@@ -32,6 +32,18 @@ from The Open Group.
|
|
|
6911ea |
#include <X11/Xlibint.h>
|
|
|
6911ea |
#include <X11/Xos.h>
|
|
|
6911ea |
|
|
|
6911ea |
+/*
|
|
|
6911ea |
+ * Xlib's _XAsyncErrorState sequence number may wrap in 32bit
|
|
|
6911ea |
+ * and we cannot use 64bit as it's public API.
|
|
|
6911ea |
+ */
|
|
|
6911ea |
+#ifdef LONG64
|
|
|
6911ea |
+#define _XLIB_ASYNC_SEQUENCE_CMP(a,op,b) ((a == 0) || (a op b))
|
|
|
6911ea |
+#else /* !LONG64 */
|
|
|
6911ea |
+#define _XLIB_ASYNC_SEQUENCE_CMP(a,op,b) ((a == 0) || \
|
|
|
6911ea |
+ (((a op b) && (b - a op (UINT32_MAX >> 1))) || \
|
|
|
6911ea |
+ ((b op a) && ((UINT32_MAX >> 1) op a - b))))
|
|
|
6911ea |
+#endif /* !LONG64 */
|
|
|
6911ea |
+
|
|
|
6911ea |
/*ARGSUSED*/
|
|
|
6911ea |
Bool
|
|
|
6911ea |
_XAsyncErrorHandler(
|
|
|
6911ea |
@@ -51,10 +63,8 @@ _XAsyncErrorHandler(
|
|
|
6911ea |
rep->error.majorCode == state->major_opcode) &&
|
|
|
6911ea |
(!state->minor_opcode ||
|
|
|
6911ea |
rep->error.minorCode == state->minor_opcode) &&
|
|
|
6911ea |
- (!state->min_sequence_number ||
|
|
|
6911ea |
- (state->min_sequence_number <= dpy->last_request_read)) &&
|
|
|
6911ea |
- (!state->max_sequence_number ||
|
|
|
6911ea |
- (state->max_sequence_number >= dpy->last_request_read))) {
|
|
|
6911ea |
+ (_XLIB_ASYNC_SEQUENCE_CMP(state->min_sequence_number,<=,dpy->last_request_read)) &&
|
|
|
6911ea |
+ (_XLIB_ASYNC_SEQUENCE_CMP(state->max_sequence_number,>=,dpy->last_request_read))) {
|
|
|
6911ea |
state->last_error_received = rep->error.errorCode;
|
|
|
6911ea |
state->error_count++;
|
|
|
6911ea |
return True;
|
|
|
6911ea |
diff --git a/src/XlibInt.c b/src/XlibInt.c
|
|
|
6911ea |
index 80c1298..61ffba3 100644
|
|
|
6911ea |
--- a/src/XlibInt.c
|
|
|
6911ea |
+++ b/src/XlibInt.c
|
|
|
6911ea |
@@ -167,8 +167,12 @@ void _XPollfdCacheDel(
|
|
|
6911ea |
|
|
|
6911ea |
static int sync_hazard(Display *dpy)
|
|
|
6911ea |
{
|
|
|
6911ea |
- unsigned long span = dpy->request - dpy->last_request_read;
|
|
|
6911ea |
- unsigned long hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10);
|
|
|
6911ea |
+ /*
|
|
|
6911ea |
+ * "span" and "hazard" need to be signed such that the ">=" comparision
|
|
|
6911ea |
+ * works correctly in the case that hazard is greater than 65525
|
|
|
6911ea |
+ */
|
|
|
6911ea |
+ int64_t span = X_DPY_GET_REQUEST(dpy) - X_DPY_GET_LAST_REQUEST_READ(dpy);
|
|
|
6911ea |
+ int64_t hazard = min((dpy->bufmax - dpy->buffer) / SIZEOF(xReq), 65535 - 10);
|
|
|
6911ea |
return span >= 65535 - hazard - 10;
|
|
|
6911ea |
}
|
|
|
6911ea |
|
|
|
6911ea |
@@ -194,7 +198,7 @@ void _XSeqSyncFunction(
|
|
|
6911ea |
xGetInputFocusReply rep;
|
|
|
6911ea |
register xReq *req;
|
|
|
6911ea |
|
|
|
6911ea |
- if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) {
|
|
|
6911ea |
+ if ((X_DPY_GET_REQUEST(dpy) - X_DPY_GET_LAST_REQUEST_READ(dpy)) >= (65535 - BUFSIZE/SIZEOF(xReq))) {
|
|
|
6911ea |
GetEmptyReq(GetInputFocus, req);
|
|
|
6911ea |
(void) _XReply (dpy, (xReply *)&rep, 0, xTrue);
|
|
|
6911ea |
sync_while_locked(dpy);
|
|
|
6911ea |
@@ -276,9 +280,9 @@ _XSetLastRequestRead(
|
|
|
6911ea |
register Display *dpy,
|
|
|
6911ea |
register xGenericReply *rep)
|
|
|
6911ea |
{
|
|
|
6911ea |
- register unsigned long newseq, lastseq;
|
|
|
6911ea |
+ register uint64_t newseq, lastseq;
|
|
|
6911ea |
|
|
|
6911ea |
- lastseq = dpy->last_request_read;
|
|
|
6911ea |
+ lastseq = X_DPY_GET_LAST_REQUEST_READ(dpy);
|
|
|
6911ea |
/*
|
|
|
6911ea |
* KeymapNotify has no sequence number, but is always guaranteed
|
|
|
6911ea |
* to immediately follow another event, except when generated via
|
|
|
6911ea |
@@ -287,20 +291,21 @@ _XSetLastRequestRead(
|
|
|
6911ea |
if ((rep->type & 0x7f) == KeymapNotify)
|
|
|
6911ea |
return(lastseq);
|
|
|
6911ea |
|
|
|
6911ea |
- newseq = (lastseq & ~((unsigned long)0xffff)) | rep->sequenceNumber;
|
|
|
6911ea |
+ newseq = (lastseq & ~((uint64_t)0xffff)) | rep->sequenceNumber;
|
|
|
6911ea |
|
|
|
6911ea |
if (newseq < lastseq) {
|
|
|
6911ea |
newseq += 0x10000;
|
|
|
6911ea |
- if (newseq > dpy->request) {
|
|
|
6911ea |
+ if (newseq > X_DPY_GET_REQUEST(dpy)) {
|
|
|
6911ea |
(void) fprintf (stderr,
|
|
|
6911ea |
- "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
|
|
|
6911ea |
- newseq, dpy->request,
|
|
|
6911ea |
+ "Xlib: sequence lost (0x%llx > 0x%llx) in reply type 0x%x!\n",
|
|
|
6911ea |
+ (unsigned long long)newseq,
|
|
|
6911ea |
+ (unsigned long long)(X_DPY_GET_REQUEST(dpy)),
|
|
|
6911ea |
(unsigned int) rep->type);
|
|
|
6911ea |
newseq -= 0x10000;
|
|
|
6911ea |
}
|
|
|
6911ea |
}
|
|
|
6911ea |
|
|
|
6911ea |
- dpy->last_request_read = newseq;
|
|
|
6911ea |
+ X_DPY_SET_LAST_REQUEST_READ(dpy, newseq);
|
|
|
6911ea |
return(newseq);
|
|
|
6911ea |
}
|
|
|
6911ea |
|
|
|
6911ea |
@@ -1363,10 +1368,10 @@ static int _XPrintDefaultError(
|
|
|
6911ea |
mesg, BUFSIZ);
|
|
|
6911ea |
fputs(" ", fp);
|
|
|
6911ea |
(void) fprintf(fp, mesg, event->serial);
|
|
|
6911ea |
- XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
|
|
|
6911ea |
+ XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%lld",
|
|
|
6911ea |
mesg, BUFSIZ);
|
|
|
6911ea |
fputs("\n ", fp);
|
|
|
6911ea |
- (void) fprintf(fp, mesg, dpy->request);
|
|
|
6911ea |
+ (void) fprintf(fp, mesg, (unsigned long long)(X_DPY_GET_REQUEST(dpy)));
|
|
|
6911ea |
fputs("\n", fp);
|
|
|
6911ea |
if (event->error_code == BadImplementation) return 0;
|
|
|
6911ea |
return 1;
|
|
|
6911ea |
@@ -1720,7 +1725,7 @@ void *_XGetRequest(Display *dpy, CARD8 type, size_t len)
|
|
|
6911ea |
req->reqType = type;
|
|
|
6911ea |
req->length = len / 4;
|
|
|
6911ea |
dpy->bufptr += len;
|
|
|
6911ea |
- dpy->request++;
|
|
|
6911ea |
+ X_DPY_REQUEST_INCREMENT(dpy);
|
|
|
6911ea |
return req;
|
|
|
6911ea |
}
|
|
|
6911ea |
|
|
|
6911ea |
diff --git a/src/Xxcbint.h b/src/Xxcbint.h
|
|
|
6911ea |
index bf41c23..20a6386 100644
|
|
|
6911ea |
--- a/src/Xxcbint.h
|
|
|
6911ea |
+++ b/src/Xxcbint.h
|
|
|
6911ea |
@@ -13,12 +13,12 @@
|
|
|
6911ea |
#include <X11/Xlib-xcb.h>
|
|
|
6911ea |
#include "locking.h"
|
|
|
6911ea |
|
|
|
6911ea |
-#define XLIB_SEQUENCE_COMPARE(a,op,b) (((long) (a) - (long) (b)) op 0)
|
|
|
6911ea |
+#define XLIB_SEQUENCE_COMPARE(a,op,b) (((int64_t) (a) - (int64_t) (b)) op 0)
|
|
|
6911ea |
|
|
|
6911ea |
typedef struct PendingRequest PendingRequest;
|
|
|
6911ea |
struct PendingRequest {
|
|
|
6911ea |
PendingRequest *next;
|
|
|
6911ea |
- unsigned long sequence;
|
|
|
6911ea |
+ uint64_t sequence;
|
|
|
6911ea |
unsigned reply_waiter;
|
|
|
6911ea |
};
|
|
|
6911ea |
|
|
|
6911ea |
diff --git a/src/xcb_io.c b/src/xcb_io.c
|
|
|
6911ea |
index 5987329..bd26a62 100644
|
|
|
6911ea |
--- a/src/xcb_io.c
|
|
|
6911ea |
+++ b/src/xcb_io.c
|
|
|
6911ea |
@@ -68,22 +68,8 @@ static void require_socket(Display *dpy)
|
|
|
6911ea |
if(!xcb_take_socket(dpy->xcb->connection, return_socket, dpy,
|
|
|
6911ea |
flags, &sent))
|
|
|
6911ea |
_XIOError(dpy);
|
|
|
6911ea |
- /* Xlib uses unsigned long for sequence numbers. XCB
|
|
|
6911ea |
- * uses 64-bit internally, but currently exposes an
|
|
|
6911ea |
- * unsigned int API. If these differ, Xlib cannot track
|
|
|
6911ea |
- * the full 64-bit sequence number if 32-bit wrap
|
|
|
6911ea |
- * happens while Xlib does not own the socket. A
|
|
|
6911ea |
- * complete fix would be to make XCB's public API use
|
|
|
6911ea |
- * 64-bit sequence numbers. */
|
|
|
6911ea |
- if (sizeof(unsigned long) > sizeof(unsigned int) &&
|
|
|
6911ea |
- dpy->xcb->event_owner == XlibOwnsEventQueue &&
|
|
|
6911ea |
- (sent - dpy->last_request_read >= (UINT64_C(1) << 32))) {
|
|
|
6911ea |
- throw_thread_fail_assert("Sequence number wrapped "
|
|
|
6911ea |
- "beyond 32 bits while Xlib "
|
|
|
6911ea |
- "did not own the socket",
|
|
|
6911ea |
- xcb_xlib_seq_number_wrapped);
|
|
|
6911ea |
- }
|
|
|
6911ea |
- dpy->xcb->last_flushed = dpy->request = sent;
|
|
|
6911ea |
+ dpy->xcb->last_flushed = sent;
|
|
|
6911ea |
+ X_DPY_SET_REQUEST(dpy, sent);
|
|
|
6911ea |
dpy->bufmax = dpy->xcb->real_bufmax;
|
|
|
6911ea |
}
|
|
|
6911ea |
}
|
|
|
6911ea |
@@ -145,7 +131,7 @@ static void check_internal_connections(Display *dpy)
|
|
|
6911ea |
}
|
|
|
6911ea |
}
|
|
|
6911ea |
|
|
|
6911ea |
-static PendingRequest *append_pending_request(Display *dpy, unsigned long sequence)
|
|
|
6911ea |
+static PendingRequest *append_pending_request(Display *dpy, uint64_t sequence)
|
|
|
6911ea |
{
|
|
|
6911ea |
PendingRequest *node = malloc(sizeof(PendingRequest));
|
|
|
6911ea |
assert(node);
|
|
|
6911ea |
@@ -214,14 +200,13 @@ static int handle_error(Display *dpy, xError *err, Bool in_XReply)
|
|
|
6911ea |
return 0;
|
|
|
6911ea |
}
|
|
|
6911ea |
|
|
|
6911ea |
-/* Widen a 32-bit sequence number into a native-word-size (unsigned long)
|
|
|
6911ea |
- * sequence number. Treating the comparison as a 1 and shifting it avoids a
|
|
|
6911ea |
- * conditional branch, and shifting by 16 twice avoids a compiler warning when
|
|
|
6911ea |
- * sizeof(unsigned long) == 4. */
|
|
|
6911ea |
-static void widen(unsigned long *wide, unsigned int narrow)
|
|
|
6911ea |
+/* Widen a 32-bit sequence number into a 64bit (uint64_t) sequence number.
|
|
|
6911ea |
+ * Treating the comparison as a 1 and shifting it avoids a conditional branch.
|
|
|
6911ea |
+ */
|
|
|
6911ea |
+static void widen(uint64_t *wide, unsigned int narrow)
|
|
|
6911ea |
{
|
|
|
6911ea |
- unsigned long new = (*wide & ~0xFFFFFFFFUL) | narrow;
|
|
|
6911ea |
- *wide = new + ((unsigned long) (new < *wide) << 16 << 16);
|
|
|
6911ea |
+ uint64_t new = (*wide & ~((uint64_t)0xFFFFFFFFUL)) | narrow;
|
|
|
6911ea |
+ *wide = new + (((uint64_t)(new < *wide)) << 32);
|
|
|
6911ea |
}
|
|
|
6911ea |
|
|
|
6911ea |
/* Thread-safety rules:
|
|
|
6911ea |
@@ -260,20 +245,20 @@ static xcb_generic_reply_t *poll_for_event(Display *dpy)
|
|
|
6911ea |
{
|
|
|
6911ea |
PendingRequest *req = dpy->xcb->pending_requests;
|
|
|
6911ea |
xcb_generic_event_t *event = dpy->xcb->next_event;
|
|
|
6911ea |
- unsigned long event_sequence = dpy->last_request_read;
|
|
|
6911ea |
+ uint64_t event_sequence = X_DPY_GET_LAST_REQUEST_READ(dpy);
|
|
|
6911ea |
widen(&event_sequence, event->full_sequence);
|
|
|
6911ea |
if(!req || XLIB_SEQUENCE_COMPARE(event_sequence, <, req->sequence)
|
|
|
6911ea |
|| (event->response_type != X_Error && event_sequence == req->sequence))
|
|
|
6911ea |
{
|
|
|
6911ea |
- if (XLIB_SEQUENCE_COMPARE(event_sequence, >,
|
|
|
6911ea |
- dpy->request))
|
|
|
6911ea |
+ uint64_t request = X_DPY_GET_REQUEST(dpy);
|
|
|
6911ea |
+ if (XLIB_SEQUENCE_COMPARE(event_sequence, >, request))
|
|
|
6911ea |
{
|
|
|
6911ea |
throw_thread_fail_assert("Unknown sequence "
|
|
|
6911ea |
"number while "
|
|
|
6911ea |
"processing queue",
|
|
|
6911ea |
xcb_xlib_threads_sequence_lost);
|
|
|
6911ea |
}
|
|
|
6911ea |
- dpy->last_request_read = event_sequence;
|
|
|
6911ea |
+ X_DPY_SET_LAST_REQUEST_READ(dpy, event_sequence);
|
|
|
6911ea |
dpy->xcb->next_event = NULL;
|
|
|
6911ea |
return (xcb_generic_reply_t *) event;
|
|
|
6911ea |
}
|
|
|
6911ea |
@@ -289,15 +274,16 @@ static xcb_generic_reply_t *poll_for_response(Display *dpy)
|
|
|
6911ea |
while(!(response = poll_for_event(dpy)) &&
|
|
|
6911ea |
(req = dpy->xcb->pending_requests) &&
|
|
|
6911ea |
!req->reply_waiter &&
|
|
|
6911ea |
- xcb_poll_for_reply(dpy->xcb->connection, req->sequence, &response, &error))
|
|
|
6911ea |
+ xcb_poll_for_reply64(dpy->xcb->connection, req->sequence, &response, &error))
|
|
|
6911ea |
{
|
|
|
6911ea |
- if(XLIB_SEQUENCE_COMPARE(req->sequence, >, dpy->request))
|
|
|
6911ea |
+ uint64_t request = X_DPY_GET_REQUEST(dpy);
|
|
|
6911ea |
+ if(XLIB_SEQUENCE_COMPARE(req->sequence, >, request))
|
|
|
6911ea |
{
|
|
|
6911ea |
throw_thread_fail_assert("Unknown sequence number "
|
|
|
6911ea |
"while awaiting reply",
|
|
|
6911ea |
xcb_xlib_threads_sequence_lost);
|
|
|
6911ea |
}
|
|
|
6911ea |
- dpy->last_request_read = req->sequence;
|
|
|
6911ea |
+ X_DPY_SET_LAST_REQUEST_READ(dpy, req->sequence);
|
|
|
6911ea |
if(response)
|
|
|
6911ea |
break;
|
|
|
6911ea |
dequeue_pending_request(dpy, req);
|
|
|
6911ea |
@@ -456,6 +442,7 @@ void _XSend(Display *dpy, const char *data, long size)
|
|
|
6911ea |
static char const pad[3];
|
|
|
6911ea |
struct iovec vec[3];
|
|
|
6911ea |
uint64_t requests;
|
|
|
6911ea |
+ uint64_t dpy_request;
|
|
|
6911ea |
_XExtension *ext;
|
|
|
6911ea |
xcb_connection_t *c = dpy->xcb->connection;
|
|
|
6911ea |
if(dpy->flags & XlibDisplayIOError)
|
|
|
6911ea |
@@ -464,6 +451,10 @@ void _XSend(Display *dpy, const char *data, long size)
|
|
|
6911ea |
if(dpy->bufptr == dpy->buffer && !size)
|
|
|
6911ea |
return;
|
|
|
6911ea |
|
|
|
6911ea |
+ /* append_pending_request does not alter the dpy request number
|
|
|
6911ea |
+ * therefore we can get it outside of the loop and the if
|
|
|
6911ea |
+ */
|
|
|
6911ea |
+ dpy_request = X_DPY_GET_REQUEST(dpy);
|
|
|
6911ea |
/* iff we asked XCB to set aside errors, we must pick those up
|
|
|
6911ea |
* eventually. iff there are async handlers, we may have just
|
|
|
6911ea |
* issued requests that will generate replies. in either case,
|
|
|
6911ea |
@@ -471,11 +462,11 @@ void _XSend(Display *dpy, const char *data, long size)
|
|
|
6911ea |
if(dpy->xcb->event_owner != XlibOwnsEventQueue || dpy->async_handlers)
|
|
|
6911ea |
{
|
|
|
6911ea |
uint64_t sequence;
|
|
|
6911ea |
- for(sequence = dpy->xcb->last_flushed + 1; sequence <= dpy->request; ++sequence)
|
|
|
6911ea |
+ for(sequence = dpy->xcb->last_flushed + 1; sequence <= dpy_request; ++sequence)
|
|
|
6911ea |
append_pending_request(dpy, sequence);
|
|
|
6911ea |
}
|
|
|
6911ea |
- requests = dpy->request - dpy->xcb->last_flushed;
|
|
|
6911ea |
- dpy->xcb->last_flushed = dpy->request;
|
|
|
6911ea |
+ requests = dpy_request - dpy->xcb->last_flushed;
|
|
|
6911ea |
+ dpy->xcb->last_flushed = dpy_request;
|
|
|
6911ea |
|
|
|
6911ea |
vec[0].iov_base = dpy->buffer;
|
|
|
6911ea |
vec[0].iov_len = dpy->bufptr - dpy->buffer;
|
|
|
6911ea |
@@ -570,6 +561,7 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard)
|
|
|
6911ea |
xcb_connection_t *c = dpy->xcb->connection;
|
|
|
6911ea |
char *reply;
|
|
|
6911ea |
PendingRequest *current;
|
|
|
6911ea |
+ uint64_t dpy_request;
|
|
|
6911ea |
|
|
|
6911ea |
if (dpy->xcb->reply_data)
|
|
|
6911ea |
throw_extlib_fail_assert("Extra reply data still left in queue",
|
|
|
6911ea |
@@ -579,10 +571,12 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard)
|
|
|
6911ea |
return 0;
|
|
|
6911ea |
|
|
|
6911ea |
_XSend(dpy, NULL, 0);
|
|
|
6911ea |
- if(dpy->xcb->pending_requests_tail && dpy->xcb->pending_requests_tail->sequence == dpy->request)
|
|
|
6911ea |
+ dpy_request = X_DPY_GET_REQUEST(dpy);
|
|
|
6911ea |
+ if(dpy->xcb->pending_requests_tail
|
|
|
6911ea |
+ && dpy->xcb->pending_requests_tail->sequence == dpy_request)
|
|
|
6911ea |
current = dpy->xcb->pending_requests_tail;
|
|
|
6911ea |
else
|
|
|
6911ea |
- current = append_pending_request(dpy, dpy->request);
|
|
|
6911ea |
+ current = append_pending_request(dpy, dpy_request);
|
|
|
6911ea |
/* Don't let any other thread get this reply. */
|
|
|
6911ea |
current->reply_waiter = 1;
|
|
|
6911ea |
|
|
|
6911ea |
@@ -599,9 +593,9 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard)
|
|
|
6911ea |
}
|
|
|
6911ea |
req->reply_waiter = 1;
|
|
|
6911ea |
UnlockDisplay(dpy);
|
|
|
6911ea |
- response = xcb_wait_for_reply(c, req->sequence, &error);
|
|
|
6911ea |
+ response = xcb_wait_for_reply64(c, req->sequence, &error);
|
|
|
6911ea |
/* Any user locks on another thread must have been taken
|
|
|
6911ea |
- * while we slept in xcb_wait_for_reply. Classic Xlib
|
|
|
6911ea |
+ * while we slept in xcb_wait_for_reply64. Classic Xlib
|
|
|
6911ea |
* ignored those user locks in this case, so we do too. */
|
|
|
6911ea |
InternalLockDisplay(dpy, /* ignore user locks */ 1);
|
|
|
6911ea |
|
|
|
6911ea |
@@ -629,12 +623,13 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard)
|
|
|
6911ea |
|
|
|
6911ea |
req->reply_waiter = 0;
|
|
|
6911ea |
ConditionBroadcast(dpy, dpy->xcb->reply_notify);
|
|
|
6911ea |
- if(XLIB_SEQUENCE_COMPARE(req->sequence, >, dpy->request)) {
|
|
|
6911ea |
+ dpy_request = X_DPY_GET_REQUEST(dpy);
|
|
|
6911ea |
+ if(XLIB_SEQUENCE_COMPARE(req->sequence, >, dpy_request)) {
|
|
|
6911ea |
throw_thread_fail_assert("Unknown sequence number "
|
|
|
6911ea |
"while processing reply",
|
|
|
6911ea |
xcb_xlib_threads_sequence_lost);
|
|
|
6911ea |
}
|
|
|
6911ea |
- dpy->last_request_read = req->sequence;
|
|
|
6911ea |
+ X_DPY_SET_LAST_REQUEST_READ(dpy, req->sequence);
|
|
|
6911ea |
if(!response)
|
|
|
6911ea |
dequeue_pending_request(dpy, req);
|
|
|
6911ea |
|
|
|
6911ea |
@@ -654,9 +649,10 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard)
|
|
|
6911ea |
if(dpy->xcb->next_event && dpy->xcb->next_event->response_type == X_Error)
|
|
|
6911ea |
{
|
|
|
6911ea |
xcb_generic_event_t *event = dpy->xcb->next_event;
|
|
|
6911ea |
- unsigned long event_sequence = dpy->last_request_read;
|
|
|
6911ea |
+ uint64_t last_request_read = X_DPY_GET_LAST_REQUEST_READ(dpy);
|
|
|
6911ea |
+ uint64_t event_sequence = last_request_read;
|
|
|
6911ea |
widen(&event_sequence, event->full_sequence);
|
|
|
6911ea |
- if(event_sequence == dpy->last_request_read)
|
|
|
6911ea |
+ if(event_sequence == last_request_read)
|
|
|
6911ea |
{
|
|
|
6911ea |
error = (xcb_generic_error_t *) event;
|
|
|
6911ea |
dpy->xcb->next_event = NULL;
|