diff options
-rw-r--r-- | src/XlibInt.c | 37 | ||||
-rw-r--r-- | src/Xprivate.h | 1 | ||||
-rw-r--r-- | src/locking.c | 3 | ||||
-rw-r--r-- | src/xcb_io.c | 25 |
4 files changed, 37 insertions, 29 deletions
diff --git a/src/XlibInt.c b/src/XlibInt.c index 3555dd15..8ffea16d 100644 --- a/src/XlibInt.c +++ b/src/XlibInt.c @@ -567,29 +567,43 @@ static int sync_hazard(Display *dpy) } static +void sync_while_locked(Display *dpy) +{ +#ifdef XTHREADS + if (dpy->lock) + (*dpy->lock->user_lock_display)(dpy); +#endif + UnlockDisplay(dpy); + SyncHandle(); + LockDisplay(dpy); +#ifdef XTHREADS + if (dpy->lock) + (*dpy->lock->user_unlock_display)(dpy); +#endif +} + int _XSeqSyncFunction( register Display *dpy) { xGetInputFocusReply rep; register xReq *req; - int sent_sync = 0; - LockDisplay(dpy); if ((dpy->request - dpy->last_request_read) >= (65535 - BUFSIZE/SIZEOF(xReq))) { GetEmptyReq(GetInputFocus, req); (void) _XReply (dpy, (xReply *)&rep, 0, xTrue); - sent_sync = 1; + sync_while_locked(dpy); } else if (sync_hazard(dpy)) _XSetPrivSyncFunction(dpy); - UnlockDisplay(dpy); - if (sent_sync) - SyncHandle(); return 0; } +/* NOTE: only called if !XTHREADS, or when XInitThreads wasn't called. */ static int _XPrivSyncFunction (Display *dpy) { +#if XTHREADS + assert(!dpy->lock_fns); +#endif assert(dpy->synchandler == _XPrivSyncFunction); assert((dpy->flags & XlibDisplayPrivSync) != 0); dpy->synchandler = dpy->savedsynchandler; @@ -604,6 +618,10 @@ _XPrivSyncFunction (Display *dpy) void _XSetPrivSyncFunction(Display *dpy) { +#ifdef XTHREADS + if (dpy->lock_fns) + return; +#endif if (!(dpy->flags & XlibDisplayPrivSync)) { dpy->savedsynchandler = dpy->synchandler; dpy->synchandler = _XPrivSyncFunction; @@ -1544,9 +1562,7 @@ _XIDHandler( { xXCMiscGetXIDRangeReply grep; register xXCMiscGetXIDRangeReq *greq; - int sent_req = 0; - LockDisplay(dpy); if (dpy->resource_max == dpy->resource_mask + 1) { _XGetMiscCode(dpy); if (dpy->xcmisc_opcode > 0) { @@ -1561,12 +1577,9 @@ _XIDHandler( dpy->resource_max += grep.count - 6; dpy->resource_max <<= dpy->resource_shift; } - sent_req = 1; + sync_while_locked(dpy); } } - UnlockDisplay(dpy); - if (sent_req) - SyncHandle(); return 0; } diff --git a/src/Xprivate.h b/src/Xprivate.h index c2c7a074..812721de 100644 --- a/src/Xprivate.h +++ b/src/Xprivate.h @@ -9,6 +9,7 @@ #define XPRIVATE_H extern int _XIDHandler(Display *dpy); +extern int _XSeqSyncFunction(Display *dpy); extern void _XSetPrivSyncFunction(Display *dpy); extern void _XSetSeqSyncFunction(Display *dpy); diff --git a/src/locking.c b/src/locking.c index 3f93d0cd..4f9a40fb 100644 --- a/src/locking.c +++ b/src/locking.c @@ -45,6 +45,7 @@ in this Software without prior written authorization from The Open Group. #include <dlfcn.h> #endif +#include "Xprivate.h" #include "locking.h" #ifdef XTHREADS_WARN #include <stdio.h> /* for warn/debug stuff */ @@ -459,6 +460,8 @@ static void _XLockDisplay( #endif if (dpy->lock->locking_level > 0) _XDisplayLockWait(dpy); + _XIDHandler(dpy); + _XSeqSyncFunction(dpy); } /* diff --git a/src/xcb_io.c b/src/xcb_io.c index 2f305da7..1459ef7f 100644 --- a/src/xcb_io.c +++ b/src/xcb_io.c @@ -382,19 +382,14 @@ static const XID inval_id = ~0UL; int _XIDHandler(Display *dpy) { - XID next; - - if (dpy->xcb->next_xid != inval_id) - return 0; - - next = xcb_generate_id(dpy->xcb->connection); - LockDisplay(dpy); - dpy->xcb->next_xid = next; -#ifdef XTHREADS - if (dpy->lock) - (*dpy->lock->user_unlock_display)(dpy); -#endif - UnlockDisplay(dpy); + if (dpy->xcb->next_xid == inval_id) + { + /* We drop the Display lock to call xcb_generate_id, and + * xcb_generate_id might take the socket back, which will call + * LockDisplay. Avoid recursing. */ + dpy->xcb->next_xid = inval_id - 1; + _XAllocIDs(dpy, &dpy->xcb->next_xid, 1); + } return 0; } @@ -403,10 +398,6 @@ XID _XAllocID(Display *dpy) { XID ret = dpy->xcb->next_xid; assert (ret != inval_id); -#ifdef XTHREADS - if (dpy->lock) - (*dpy->lock->user_lock_display)(dpy); -#endif dpy->xcb->next_xid = inval_id; _XSetPrivSyncFunction(dpy); return ret; |