17 files changed, 2247 insertions, 7 deletions
diff --git a/x11-libs/libX11/Manifest b/x11-libs/libX11/Manifest index b571732..e0486d2 100644 --- a/x11-libs/libX11/Manifest +++ b/x11-libs/libX11/Manifest @@ -1 +1,5 @@ -EBUILD libX11-9999.ebuild 924 RMD160 c1d2087fb6c521c3745ebba23f1aa1f4a29b0871 SHA1 de57c2aa1a76ab595276d6269e29ebccbb3ef69e SHA256 cdf981d024f0b0d1bb815cf58c64abd7689a9f8007f515fb203475d33696e655 +AUX xlib-0001-Use-XCB-s-new-socket-handoff-mechanism-rather-than-t.patch 25297 RMD160 1129779af77f552090559b009fe03c2625abd3bd SHA1 74820193a00e0c9c0f3d5d016535bcf2d7f3aa70 SHA256 81d33def627a6aea4bdf6d52f6d46e685f5e1803e4c393baa098a50bb0a9f10c +AUX xlib-0002-Fix-XAllocID-race-hold-the-user-display-lock-until.patch 1322 RMD160 c0d141b8bedc95bd0ea17b4f1dc22e89337a31fd SHA1 53fecb881ae3198ca739a07cd3a87c59b0a8fb61 SHA256 954285da20bfaab3e03e766852a68549034d44f9d28bdf72e1aebf2284f3f9e7 +AUX xlib-0003-Permit-only-one-Xlib-thread-to-block-waiting-for-eve.patch 3118 RMD160 9472410a4ed9cd16cd6b4cb5d1e2beef509836b5 SHA1 0350f6429c0a22a05e9d5e1e7e52bde1106c9d42 SHA256 67407d74fd1263030775b988d51b5c5e9b04cbf93fd0cba26d977db833d7ae88 +AUX xlib-0004-Ensure-that-_XReadEvents-always-leaves-an-event-in-t.patch 1042 RMD160 4c622ffd1ac7a2e6d797db5a77beb292e33390f7 SHA1 94c4c628fbb7ef2a71e9127f776b897fec7dfc5e SHA256 25700d5d441e891a4f23991b5ec8a440f2e76bd0cb43a42036c8032f51f83227 +EBUILD libX11-9999.ebuild 901 RMD160 24824ec1eb169b240d6663f91b8e0386f6031433 SHA1 778a31238a818a5c0b55f24640436af685c5355d SHA256 7ceef42410cf4d6406e01a7d2d490c58166c5a1efd11882e026a0facad421f8b diff --git a/x11-libs/libX11/files/xlib-0001-Use-XCB-s-new-socket-handoff-mechanism-rather-than-t.patch b/x11-libs/libX11/files/xlib-0001-Use-XCB-s-new-socket-handoff-mechanism-rather-than-t.patch new file mode 100644 index 0000000..e500492 --- a/dev/null +++ b/x11-libs/libX11/files/xlib-0001-Use-XCB-s-new-socket-handoff-mechanism-rather-than-t.patch @@ -0,0 +1,774 @@ +From 50d5c8363da0cd10217d4f24e8561ed9a1e1881e Mon Sep 17 00:00:00 2001 +From: Josh Triplett <josh@freedesktop.org> +Date: Sat, 15 Mar 2008 17:22:00 -0700 +Subject: [PATCH 1/4] Use XCB's new socket handoff mechanism rather than the old XCB Xlib lock. + +Previously, Xlib/XCB used XCB's Xlib lock to prevent XCB from sending +requests between calls to Xlib's LockDisplay and UnlockDisplay macros. +Xlib/XCB then sent all of its requests using XCB's xcb_send_request, and +had to flush its requests when unlocking the display. + +XCB 1.2 adds a new socket handoff mechanism, xcb_take_socket. Replace +much of the existing Xlib/XCB implementation with the use of +xcb_take_socket to take ownership of the write side of the X connection +socket, and a return_socket callback which writes any outstanding requests +with xcb_writev. This approach allows Xlib/XCB to use the same buffering +as traditional Xlib did. In particular, programs which use Xlib/XCB and +never make XCB calls will never need to hand the socket back to XCB, and +vice versa. + +This allows us to discard large quantities of synchronization code from +Xlib/XCB, together with the synchronization bugs present in that code. +Several test cases which previously failed now work perfectly, including +multi-threaded ico. In addition, the infamous locking correctness +assertions, triggered when double-locking or when unlocking without a +previous lock, no longer exist, because Xlib/XCB no longer has any reason +to care more about application locking than traditional Xlib does. + +Furthermore, the handoff approach provides great improvements to +performance. Results from x11perf's XNoOp test, which represented the +worst case for the lock-based Xlib/XCB: + +Traditional Xlib: average 19100000/sec +Lock-based Xlib/XCB: average 3350000/sec +Handoff-based Xlib/XCB: average 17400000/sec + +Thus, for no-ops, the handoff mechanism provides more than a 4x speedup to +Xlib/XCB, bringing Xlib/XCB within 9% of traditional Xlib no-op +performance. Of course, real-world workloads do not use no-op, so your +mileage may vary. In particular, since no-ops represent the worst case, +we expect real workloads to more closely match the performance of +traditional Xlib. + +While removing synchronization code, we changed _XReply to not drop +any locks when calling xcb_wait_for_reply; previously, we had to carefully +avoid a deadlock between the Display lock and the XCB Xlib lock. Holding +the locks reduces implementation complexity and should not impact applications. + +Commit by Jamey Sharp and Josh Triplett. +XCB's handoff mechanism inspired by Keith Packard. +--- + configure.ac | 4 +- + src/Makefile.am | 1 - + src/OpenDis.c | 27 +++---- + src/Xxcbint.h | 27 +----- + src/xcb_io.c | 194 +++++++++++++++++++++++++++++----------------- + src/xcb_lock.c | 235 ------------------------------------------------------- + 6 files changed, 140 insertions(+), 348 deletions(-) + delete mode 100644 src/xcb_lock.c + +diff --git a/configure.ac b/configure.ac +index 5febfb3..6141fa4 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -52,8 +52,8 @@ no) + AC_DEFINE(USE_XCB, 0, [Use XCB for low-level protocol implementation]) + ;; + *) +- X11_REQUIRES="xcb-xlib >= 1.1.90" +- X11_EXTRA_DEPS="xcb-xlib" ++ X11_REQUIRES="xcb >= 1.2" ++ X11_EXTRA_DEPS="xcb >= 1.2" + xdmauth="no" # XCB handles all auth + AC_DEFINE(USE_XCB, 1, [Use XCB for low-level protocol implementation]) + ;; +diff --git a/src/Makefile.am b/src/Makefile.am +index 564e03f..3380f81 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -342,7 +342,6 @@ EXTRA_DIST = \ + + if XCB + libX11_la_SOURCES += \ +- xcb_lock.c \ + xcb_disp.c \ + xcb_io.c \ + Xxcbint.h +diff --git a/src/OpenDis.c b/src/OpenDis.c +index d5089e8..aa2541f 100644 +--- a/src/OpenDis.c ++++ b/src/OpenDis.c +@@ -261,13 +261,6 @@ XOpenDisplay ( + return(NULL); + } + +-#if USE_XCB +- if (!_XCBInitDisplayLock(dpy)) { +- OutOfMemory (dpy, setup); +- return(NULL); +- } +-#endif +- + if (!_XPollfdCacheInit(dpy)) { + OutOfMemory (dpy, setup); + return(NULL); +@@ -292,6 +285,10 @@ XOpenDisplay ( + return(NULL); + } + dpy->bufmax = dpy->buffer + conn_buf_size; ++#if USE_XCB ++ dpy->xcb->real_bufmax = dpy->bufmax; ++ dpy->bufmax = dpy->buffer; ++#endif + + /* Set up the input event queue and input event queue parameters. */ + dpy->head = dpy->tail = NULL; +@@ -652,6 +649,12 @@ XOpenDisplay ( + UnlockDisplay(dpy); + #endif /* !USE_XCB */ + ++#if USE_XCB ++ dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection); ++ if(dpy->bigreq_size <= dpy->max_request_size) ++ dpy->bigreq_size = 0; ++#endif /* USE_XCB */ ++ + /* + * Set up other stuff clients are always going to use. + */ +@@ -673,12 +676,6 @@ XOpenDisplay ( + */ + (void) XSynchronize(dpy, _Xdebug); + +-#if USE_XCB +- dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection); +- if(dpy->bigreq_size <= dpy->max_request_size) +- dpy->bigreq_size = 0; +-#endif /* USE_XCB */ +- + /* + * get availability of large requests, and + * get the resource manager database off the root window. +@@ -883,10 +880,6 @@ void _XFreeDisplayStructure(dpy) + Xfree (dpy->scratch_buffer); + FreeDisplayLock(dpy); + +-#if USE_XCB +- _XCBShutdownDisplayLock(dpy); +-#endif /* USE_XCB */ +- + if (dpy->qfree) { + register _XQEvent *qelt = dpy->qfree; + +diff --git a/src/Xxcbint.h b/src/Xxcbint.h +index cc73749..1b3137b 100644 +--- a/src/Xxcbint.h ++++ b/src/Xxcbint.h +@@ -5,34 +5,28 @@ + #define XXCBINT_H + + #include <assert.h> ++#include <stdint.h> + #include <X11/Xlibint.h> + #include <X11/Xlib-xcb.h> +-#include "locking.h" /* really just want X11/Xthreads.h but can't have it. */ + +-#define XCB_SEQUENCE_COMPARE(a,op,b) ((int) ((a) - (b)) op 0) +-#define assert_sequence_less(a,b) assert(XCB_SEQUENCE_COMPARE((a), <=, (b))) ++#define XLIB_SEQUENCE_COMPARE(a,op,b) (((long) (a) - (long) (b)) op 0) + + typedef struct PendingRequest PendingRequest; + struct PendingRequest { + PendingRequest *next; +- xcondition_rec condition; +- int waiters; /* Number of threads waiting; -1 if no wait needed */ +- unsigned int sequence; ++ unsigned long sequence; + }; + + typedef struct _X11XCBPrivate { +- struct _XLockPtrs lock_fns; + xcb_connection_t *connection; + PendingRequest *pending_requests; + PendingRequest **pending_requests_tail; + xcb_generic_event_t *next_event; +- const char *request_extra; +- int request_extra_size; +- char *partial_request; +- int partial_request_offset; ++ char *real_bufmax; + char *reply_data; + int reply_length; + int reply_consumed; ++ uint64_t last_flushed; + enum XEventQueueOwner event_owner; + XID next_xid; + } _X11XCBPrivate; +@@ -42,15 +36,4 @@ typedef struct _X11XCBPrivate { + int _XConnectXCB(Display *dpy, _Xconst char *display, char **fullnamep, int *screenp); + void _XFreeX11XCBStructure(Display *dpy); + +-/* xcb_lock.c */ +- +-int _XCBInitDisplayLock(Display *dpy); +-void _XCBShutdownDisplayLock(Display *dpy); +- +-/* _XGetXCBBuffer and _XPutXCBBuffer calls must be paired and must not +- * be nested. */ +- +-void _XGetXCBBuffer(Display *dpy); +-void _XPutXCBBuffer(Display *dpy); +- + #endif /* XXCBINT_H */ +diff --git a/src/xcb_io.c b/src/xcb_io.c +index dcbe5a8..830ddb9 100644 +--- a/src/xcb_io.c ++++ b/src/xcb_io.c +@@ -5,12 +5,50 @@ + #include "locking.h" + #include "Xxcbint.h" + #include <xcb/xcbext.h> +-#include <xcb/xcbxlib.h> + + #include <assert.h> ++#include <inttypes.h> ++#include <stdint.h> + #include <stdlib.h> + #include <string.h> + ++static void return_socket(void *closure) ++{ ++ Display *dpy = closure; ++ LockDisplay(dpy); ++ _XSend(dpy, 0, 0); ++ dpy->bufmax = dpy->buffer; ++ UnlockDisplay(dpy); ++} ++ ++static void require_socket(Display *dpy) ++{ ++ if(dpy->bufmax == dpy->buffer) ++ { ++ uint64_t sent; ++ int flags = 0; ++ /* if we don't own the event queue, we have to ask XCB ++ * to set our errors aside for us. */ ++ if(dpy->xcb->event_owner != XlibOwnsEventQueue) ++ flags = XCB_REQUEST_CHECKED; ++ 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. */ ++ assert(!(sizeof(unsigned long) > sizeof(unsigned int) ++ && dpy->xcb->event_owner == XlibOwnsEventQueue ++ && (sent - dpy->last_request_read >= (UINT64_C(1) << 32)))); ++ dpy->xcb->last_flushed = dpy->request = sent; ++ dpy->bufmax = dpy->xcb->real_bufmax; ++ } ++} ++ + /* Call internal connection callbacks for any fds that are currently + * ready to read. This function will not block unless one of the + * callbacks blocks. +@@ -68,15 +106,6 @@ static void check_internal_connections(Display *dpy) + } + } + +-static void condition_wait(Display *dpy, xcondition_t cv) +-{ +- _XPutXCBBuffer(dpy); +- xcb_xlib_unlock(dpy->xcb->connection); +- ConditionWait(dpy, cv); +- xcb_xlib_lock(dpy->xcb->connection); +- _XGetXCBBuffer(dpy); +-} +- + static void call_handlers(Display *dpy, xcb_generic_reply_t *buf) + { + _XAsyncHandler *async, *next; +@@ -105,7 +134,17 @@ static xcb_generic_event_t * wait_or_poll_for_event(Display *dpy, int wait) + return event; + } + +-static void process_responses(Display *dpy, int wait_for_first_event, xcb_generic_error_t **current_error, unsigned int current_request) ++/* 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) ++{ ++ unsigned long new = (*wide & ~0xFFFFFFFFUL) | narrow; ++ *wide = new + ((unsigned long) (new < *wide) << 16 << 16); ++} ++ ++static void process_responses(Display *dpy, int wait_for_first_event, xcb_generic_error_t **current_error, unsigned long current_request) + { + void *reply; + xcb_generic_event_t *event = dpy->xcb->next_event; +@@ -114,13 +153,18 @@ static void process_responses(Display *dpy, int wait_for_first_event, xcb_generi + if(!event && dpy->xcb->event_owner == XlibOwnsEventQueue) + event = wait_or_poll_for_event(dpy, wait_for_first_event); + ++ require_socket(dpy); ++ + while(1) + { + PendingRequest *req = dpy->xcb->pending_requests; +- assert(!(req && current_request && !XCB_SEQUENCE_COMPARE(req->sequence, <=, current_request))); +- if(event && (!req || XCB_SEQUENCE_COMPARE(event->full_sequence, <=, req->sequence))) ++ unsigned long event_sequence = dpy->last_request_read; ++ if(event) ++ widen(&event_sequence, event->full_sequence); ++ assert(!(req && current_request && !XLIB_SEQUENCE_COMPARE(req->sequence, <=, current_request))); ++ if(event && (!req || XLIB_SEQUENCE_COMPARE(event_sequence, <=, req->sequence))) + { +- dpy->last_request_read = event->full_sequence; ++ dpy->last_request_read = event_sequence; + if(event->response_type != X_Error) + { + /* GenericEvents may be > 32 bytes. In this +@@ -139,7 +183,7 @@ static void process_responses(Display *dpy, int wait_for_first_event, xcb_generi + _XEnq(dpy, (xEvent *) event); + wait_for_first_event = 0; + } +- else if(current_error && event->full_sequence == current_request) ++ else if(current_error && event_sequence == current_request) + { + /* This can only occur when called from + * _XReply, which doesn't need a new event. */ +@@ -152,18 +196,9 @@ static void process_responses(Display *dpy, int wait_for_first_event, xcb_generi + free(event); + event = wait_or_poll_for_event(dpy, wait_for_first_event); + } +- else if(req && req->waiters != -1) ++ else if(req && req->sequence == current_request) + { +- if(req->sequence == current_request) +- break; +- if(!current_request && !wait_for_first_event) +- break; +- dpy->xcb->next_event = event; +- req->waiters++; +- assert(req->waiters > 0); +- condition_wait(dpy, &req->condition); +- --req->waiters; +- event = dpy->xcb->next_event; ++ break; + } + else if(req && xcb_poll_for_reply(dpy->xcb->connection, req->sequence, &reply, &error)) + { +@@ -192,7 +227,7 @@ static void process_responses(Display *dpy, int wait_for_first_event, xcb_generi + if(xcb_connection_has_error(c)) + _XIOError(dpy); + +- assert_sequence_less(dpy->last_request_read, dpy->request); ++ assert(XLIB_SEQUENCE_COMPARE(dpy->last_request_read, <=, dpy->request)); + assert(!wait_for_first_event); + } + +@@ -234,32 +269,61 @@ void _XReadEvents(Display *dpy) + */ + void _XSend(Display *dpy, const char *data, long size) + { ++ static const xReq dummy_request; ++ static char const pad[3]; ++ struct iovec vec[3]; ++ uint64_t requests; ++ _XExtension *ext; + xcb_connection_t *c = dpy->xcb->connection; + if(dpy->flags & XlibDisplayIOError) + return; + +- assert(!dpy->xcb->request_extra); +- dpy->xcb->request_extra = data; +- dpy->xcb->request_extra_size = size; ++ if(dpy->bufptr == dpy->buffer && !size) ++ return; ++ ++ /* 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, ++ * we need to remember to check later. */ ++ if(dpy->xcb->event_owner != XlibOwnsEventQueue || dpy->async_handlers) ++ { ++ unsigned int sequence; ++ for(sequence = dpy->xcb->last_flushed; sequence < dpy->request; ++sequence) ++ { ++ PendingRequest *req = malloc(sizeof(PendingRequest)); ++ assert(req); ++ req->next = 0; ++ req->sequence = sequence; ++ *dpy->xcb->pending_requests_tail = req; ++ dpy->xcb->pending_requests_tail = &req->next; ++ } ++ } ++ requests = dpy->request - dpy->xcb->last_flushed; ++ dpy->xcb->last_flushed = dpy->request; + +- /* give dpy->buffer to XCB */ +- _XPutXCBBuffer(dpy); ++ vec[0].iov_base = dpy->buffer; ++ vec[0].iov_len = dpy->bufptr - dpy->buffer; ++ vec[1].iov_base = (caddr_t) data; ++ vec[1].iov_len = size; ++ vec[2].iov_base = (caddr_t) pad; ++ vec[2].iov_len = -size & 3; + +- if(xcb_flush(c) <= 0) +- _XIOError(dpy); ++ for(ext = dpy->flushes; ext; ext = ext->next_flush) ++ { ++ int i; ++ for(i = 0; i < 3; ++i) ++ if(vec[i].iov_len) ++ ext->before_flush(dpy, &ext->codes, vec[i].iov_base, vec[i].iov_len); ++ } + +- /* get a new dpy->buffer */ +- _XGetXCBBuffer(dpy); ++ if(xcb_writev(c, vec, 3, requests) < 0) ++ _XIOError(dpy); ++ dpy->bufptr = dpy->buffer; ++ dpy->last_req = (char *) &dummy_request; + + check_internal_connections(dpy); + +- /* A straight port of XlibInt.c would call _XSetSeqSyncFunction +- * here. However that does no good: unlike traditional Xlib, +- * Xlib/XCB almost never calls _XFlush because _XPutXCBBuffer +- * automatically pushes requests down into XCB, so Xlib's buffer +- * is empty most of the time. Since setting a synchandler has no +- * effect until after UnlockDisplay returns, we may as well do +- * the check in _XUnlockDisplay. */ ++ _XSetSeqSyncFunction(dpy); + } + + /* +@@ -268,6 +332,7 @@ void _XSend(Display *dpy, const char *data, long size) + */ + void _XFlush(Display *dpy) + { ++ require_socket(dpy); + _XSend(dpy, 0, 0); + + _XEventsQueued(dpy, QueuedAfterReading); +@@ -308,10 +373,18 @@ XID _XAllocID(Display *dpy) + void _XAllocIDs(Display *dpy, XID *ids, int count) + { + int i; +- _XPutXCBBuffer(dpy); ++#ifdef XTHREADS ++ if (dpy->lock) ++ (*dpy->lock->user_lock_display)(dpy); ++ UnlockDisplay(dpy); ++#endif + for (i = 0; i < count; i++) + ids[i] = xcb_generate_id(dpy->xcb->connection); +- _XGetXCBBuffer(dpy); ++#ifdef XTHREADS ++ LockDisplay(dpy); ++ if (dpy->lock) ++ (*dpy->lock->user_unlock_display)(dpy); ++#endif + } + + static void _XFreeReplyData(Display *dpy, Bool force) +@@ -325,16 +398,9 @@ static void _XFreeReplyData(Display *dpy, Bool force) + static PendingRequest * insert_pending_request(Display *dpy) + { + PendingRequest **cur = &dpy->xcb->pending_requests; +- while(*cur && XCB_SEQUENCE_COMPARE((*cur)->sequence, <, dpy->request)) ++ while(*cur && XLIB_SEQUENCE_COMPARE((*cur)->sequence, <, dpy->request)) + cur = &((*cur)->next); +- if(*cur && (*cur)->sequence == dpy->request) +- { +- /* Replacing an existing PendingRequest should only happen once, +- when calling _XReply, and the replaced PendingRequest must +- not have a condition set. */ +- assert((*cur)->waiters == -1); +- } +- else ++ if(!*cur || (*cur)->sequence != dpy->request) + { + PendingRequest *node = malloc(sizeof(PendingRequest)); + assert(node); +@@ -344,8 +410,6 @@ static PendingRequest * insert_pending_request(Display *dpy) + dpy->xcb->pending_requests_tail = &(node->next); + *cur = node; + } +- (*cur)->waiters = 0; +- xcondition_init(&((*cur)->condition)); + return *cur; + } + +@@ -367,27 +431,15 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard) + if(dpy->flags & XlibDisplayIOError) + return 0; + +- /* Internals of UnlockDisplay done by hand here, so that we can +- insert_pending_request *after* we _XPutXCBBuffer, but before we +- unlock the display. */ +- _XPutXCBBuffer(dpy); ++ _XSend(dpy, 0, 0); + current = insert_pending_request(dpy); +- if(!dpy->lock || dpy->lock->locking_level == 0) +- xcb_xlib_unlock(dpy->xcb->connection); +- if(dpy->xcb->lock_fns.unlock_display) +- dpy->xcb->lock_fns.unlock_display(dpy); ++ /* FIXME: drop the Display lock while waiting? ++ * Complicates process_responses. */ + reply = xcb_wait_for_reply(c, current->sequence, &error); +- LockDisplay(dpy); + + check_internal_connections(dpy); + process_responses(dpy, 0, &error, current->sequence); + +- if(current->waiters) +- { /* The ConditionBroadcast macro contains an if; braces needed here. */ +- ConditionBroadcast(dpy, ¤t->condition); +- } +- --current->waiters; +- + if(error) + { + _XExtension *ext; +diff --git a/src/xcb_lock.c b/src/xcb_lock.c +deleted file mode 100644 +index 71b2383..0000000 +--- a/src/xcb_lock.c ++++ /dev/null +@@ -1,235 +0,0 @@ +-/* Copyright (C) 2003-2006 Jamey Sharp, Josh Triplett +- * This file is licensed under the MIT license. See the file COPYING. */ +- +-#ifdef HAVE_CONFIG_H +-#include <config.h> +-#endif +- +-#include "Xlibint.h" +-#include "locking.h" +-#include "Xxcbint.h" +-#include <xcb/xcbext.h> +-#include <xcb/xcbxlib.h> +- +-#include <pthread.h> +- +-static void _XCBLockDisplay(Display *dpy) +-{ +- if(dpy->xcb->lock_fns.lock_display) +- dpy->xcb->lock_fns.lock_display(dpy); +- if(!dpy->lock || dpy->lock->locking_level == 0) +- xcb_xlib_lock(dpy->xcb->connection); +- if(!(dpy->flags & XlibDisplayIOError)) +- _XGetXCBBuffer(dpy); +-} +- +-/* XXX: If you change this function, update _XReply's copy of its guts! */ +-static void _XCBUnlockDisplay(Display *dpy) +-{ +- if(!(dpy->flags & XlibDisplayIOError)) +- { +- _XPutXCBBuffer(dpy); +- assert(dpy->xcb->partial_request == 0); +- assert(xcb_get_request_sent(dpy->xcb->connection) == dpy->request); +- +- /* Traditional Xlib does this in _XSend; see the Xlib/XCB version +- * of that function for why we do it here instead. */ +- _XSetSeqSyncFunction(dpy); +- } +- +- if(!dpy->lock || dpy->lock->locking_level == 0) +- xcb_xlib_unlock(dpy->xcb->connection); +- if(dpy->xcb->lock_fns.unlock_display) +- dpy->xcb->lock_fns.unlock_display(dpy); +-} +- +-int _XCBInitDisplayLock(Display *dpy) +-{ +- if(!dpy->lock_fns && !(dpy->lock_fns = Xcalloc(1, sizeof(*dpy->lock_fns)))) +- return 0; +- dpy->xcb->lock_fns.lock_display = dpy->lock_fns->lock_display; +- dpy->lock_fns->lock_display = _XCBLockDisplay; +- dpy->xcb->lock_fns.unlock_display = dpy->lock_fns->unlock_display; +- dpy->lock_fns->unlock_display = _XCBUnlockDisplay; +- return 1; +-} +- +-void _XCBShutdownDisplayLock(Display *dpy) +-{ +- if(dpy->lock_fns) { +- Xfree((char *)dpy->lock_fns); +- dpy->lock_fns = NULL; +- } +-} +- +-void _XGetXCBBuffer(Display *dpy) +-{ +- static const xReq dummy_request; +- unsigned int xcb_req = xcb_get_request_sent(dpy->xcb->connection); +- if(xcb_connection_has_error(dpy->xcb->connection)) +- _XIOError(dpy); +- +- /* if Xlib has a partial request pending then XCB doesn't know about +- * the current request yet */ +- if(dpy->xcb->partial_request) +- ++xcb_req; +- +- assert(XCB_SEQUENCE_COMPARE(xcb_req, >=, dpy->request)); +- dpy->request = xcb_req; +- +- dpy->last_req = (char *) &dummy_request; +-} +- +-static size_t request_length(struct iovec *vec) +-{ +- /* we have at least part of a request. dig out the length field. +- * note that length fields are always in vec[0]: Xlib doesn't split +- * fixed-length request parts. */ +- size_t len; +- assert(vec[0].iov_len >= 4); +- len = ((uint16_t *) vec[0].iov_base)[1]; +- if(len == 0) +- { +- /* it's a bigrequest. dig out the *real* length field. */ +- assert(vec[0].iov_len >= 8); +- len = ((uint32_t *) vec[0].iov_base)[1]; +- } +- return len << 2; +-} +- +-static inline int issue_complete_request(Display *dpy, int veclen, struct iovec *vec) +-{ +- xcb_protocol_request_t xcb_req = { 0 }; +- unsigned int sequence; +- int flags = XCB_REQUEST_RAW; +- int i; +- size_t len; +- +- /* skip empty iovecs. if no iovecs remain, we're done. */ +- assert(veclen >= 0); +- while(veclen > 0 && vec[0].iov_len == 0) +- --veclen, ++vec; +- if(!veclen) +- return 0; +- +- len = request_length(vec); +- +- /* do we have enough data for a complete request? how many iovec +- * elements does it span? */ +- for(i = 0; i < veclen; ++i) +- { +- size_t oldlen = len; +- len -= vec[i].iov_len; +- /* if len is now 0 or has wrapped, we have enough data. */ +- if((len - 1) > oldlen) +- break; +- } +- if(i == veclen) +- return 0; +- +- /* we have enough data to issue one complete request. the remaining +- * code can't fail. */ +- +- /* len says how far we overshot our data needs. (it's "negative" if +- * we actually overshot, or 0 if we're right on.) */ +- vec[i].iov_len += len; +- xcb_req.count = i + 1; +- xcb_req.opcode = ((uint8_t *) vec[0].iov_base)[0]; +- +- /* if we don't own the event queue, we have to ask XCB to set our +- * errors aside for us. */ +- if(dpy->xcb->event_owner != XlibOwnsEventQueue) +- flags |= XCB_REQUEST_CHECKED; +- +- /* XCB will always skip request 0; account for that in the Xlib count */ +- if (xcb_get_request_sent(dpy->xcb->connection) == 0xffffffff) +- dpy->request++; +- /* send the accumulated request. */ +- sequence = xcb_send_request(dpy->xcb->connection, flags, vec, &xcb_req); +- if(!sequence) +- _XIOError(dpy); +- +- /* update the iovecs to refer only to data not yet sent. */ +- vec[i].iov_len = -len; +- +- /* 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, +- * we need to remember to check later. */ +- if(flags & XCB_REQUEST_CHECKED || dpy->async_handlers) +- { +- PendingRequest *req = malloc(sizeof(PendingRequest)); +- assert(req); +- req->next = 0; +- req->waiters = -1; +- req->sequence = sequence; +- *dpy->xcb->pending_requests_tail = req; +- dpy->xcb->pending_requests_tail = &req->next; +- } +- return 1; +-} +- +-void _XPutXCBBuffer(Display *dpy) +-{ +- static char const pad[3]; +- const int padsize = -dpy->xcb->request_extra_size & 3; +- xcb_connection_t *c = dpy->xcb->connection; +- _XExtension *ext; +- struct iovec iov[6]; +- +- assert_sequence_less(dpy->last_request_read, dpy->request); +- assert_sequence_less(xcb_get_request_sent(c), dpy->request); +- +- for(ext = dpy->flushes; ext; ext = ext->next_flush) +- { +- ext->before_flush(dpy, &ext->codes, dpy->buffer, dpy->bufptr - dpy->buffer); +- if(dpy->xcb->request_extra) +- { +- ext->before_flush(dpy, &ext->codes, dpy->xcb->request_extra, dpy->xcb->request_extra_size); +- if(padsize) +- ext->before_flush(dpy, &ext->codes, pad, padsize); +- } +- } +- +- iov[2].iov_base = dpy->xcb->partial_request; +- iov[2].iov_len = dpy->xcb->partial_request_offset; +- iov[3].iov_base = dpy->buffer; +- iov[3].iov_len = dpy->bufptr - dpy->buffer; +- iov[4].iov_base = (caddr_t) dpy->xcb->request_extra; +- iov[4].iov_len = dpy->xcb->request_extra_size; +- iov[5].iov_base = (caddr_t) pad; +- iov[5].iov_len = padsize; +- +- while(issue_complete_request(dpy, 4, iov + 2)) +- /* empty */; +- +- /* first discard any completed partial_request. */ +- if(iov[2].iov_len == 0 && dpy->xcb->partial_request) +- { +- free(dpy->xcb->partial_request); +- dpy->xcb->partial_request = 0; +- dpy->xcb->partial_request_offset = 0; +- } +- +- /* is there anything to copy into partial_request? */ +- if(iov[3].iov_len != 0 || iov[4].iov_len != 0 || iov[5].iov_len != 0) +- { +- int i; +- if(!dpy->xcb->partial_request) +- { +- size_t len = request_length(iov + 3); +- assert(!dpy->xcb->partial_request_offset); +- dpy->xcb->partial_request = malloc(len); +- assert(dpy->xcb->partial_request); +- } +- for(i = 3; i < sizeof(iov) / sizeof(*iov); ++i) +- { +- memcpy(dpy->xcb->partial_request + dpy->xcb->partial_request_offset, iov[i].iov_base, iov[i].iov_len); +- dpy->xcb->partial_request_offset += iov[i].iov_len; +- } +- } +- +- dpy->xcb->request_extra = 0; +- dpy->xcb->request_extra_size = 0; +- dpy->bufptr = dpy->buffer; +-} +-- +1.6.0.2.307.gc427.dirty + diff --git a/x11-libs/libX11/files/xlib-0002-Fix-XAllocID-race-hold-the-user-display-lock-until.patch b/x11-libs/libX11/files/xlib-0002-Fix-XAllocID-race-hold-the-user-display-lock-until.patch new file mode 100644 index 0000000..8d094d3 --- a/dev/null +++ b/x11-libs/libX11/files/xlib-0002-Fix-XAllocID-race-hold-the-user-display-lock-until.patch @@ -0,0 +1,47 @@ +From d4e77ee5023cda7cb04afdce9be81eaf72785c2a Mon Sep 17 00:00:00 2001 +From: Jamey Sharp <jamey@minilop.net> +Date: Sun, 23 Mar 2008 16:33:27 -0700 +Subject: [PATCH 2/4] Fix XAllocID race: hold the user display lock until we have a new XID. + +Xlib built --without-xcb is also vulnerable to this race, and a similar +fix might work there too. + +Also, use an XID that's truly invalid while waiting for the next XID to be +requested. +--- + src/xcb_io.c | 11 ++++++++++- + 1 files changed, 10 insertions(+), 1 deletions(-) + +diff --git a/src/xcb_io.c b/src/xcb_io.c +index 830ddb9..d0abf4c 100644 +--- a/src/xcb_io.c ++++ b/src/xcb_io.c +@@ -343,6 +343,10 @@ _XIDHandler(Display *dpy) + { + XID next = xcb_generate_id(dpy->xcb->connection); + LockDisplay(dpy); ++#ifdef XTHREADS ++ if (dpy->lock) ++ (*dpy->lock->user_unlock_display)(dpy); ++#endif + dpy->xcb->next_xid = next; + if(dpy->flags & XlibDisplayPrivSync) + { +@@ -357,8 +361,13 @@ _XIDHandler(Display *dpy) + /* _XAllocID - resource ID allocation routine. */ + XID _XAllocID(Display *dpy) + { ++ const XID inval = ~0UL; + XID ret = dpy->xcb->next_xid; +- dpy->xcb->next_xid = 0; ++#ifdef XTHREADS ++ if (ret != inval && dpy->lock) ++ (*dpy->lock->user_lock_display)(dpy); ++#endif ++ dpy->xcb->next_xid = inval; + + if(!(dpy->flags & XlibDisplayPrivSync)) + { +-- +1.6.0.2.307.gc427.dirty + diff --git a/x11-libs/libX11/files/xlib-0003-Permit-only-one-Xlib-thread-to-block-waiting-for-eve.patch b/x11-libs/libX11/files/xlib-0003-Permit-only-one-Xlib-thread-to-block-waiting-for-eve.patch new file mode 100644 index 0000000..5762f30 --- a/dev/null +++ b/x11-libs/libX11/files/xlib-0003-Permit-only-one-Xlib-thread-to-block-waiting-for-eve.patch @@ -0,0 +1,103 @@ +From 1cfce69bf65d9631a72f8b20d637bf158c0afd20 Mon Sep 17 00:00:00 2001 +From: Keith Packard <keithp@keithp.com> +Date: Sat, 11 Oct 2008 21:10:00 -0700 +Subject: [PATCH 3/4] Permit only one Xlib thread to block waiting for events + +As Xlib queues events internally, we must prevent multiple Xlib threads from +entering XCB to wait for an event in case the queued event is to be +delivered to the thread which didn't manage to read it. In other words, let +only one Xlib thread into xcb_wait_for_event at a time. + +Jamey Sharp looked over my shoulder while making this fix and, while hating +my whitespace conventions, appears happy enough with the actual code. + +Signed-off-by: Keith Packard <keithp@keithp.com> +--- + src/Xxcbint.h | 7 +++++++ + src/xcb_disp.c | 2 ++ + src/xcb_io.c | 18 ++++++++++++++---- + 3 files changed, 23 insertions(+), 4 deletions(-) + +diff --git a/src/Xxcbint.h b/src/Xxcbint.h +index 1b3137b..f4af324 100644 +--- a/src/Xxcbint.h ++++ b/src/Xxcbint.h +@@ -8,6 +8,7 @@ + #include <stdint.h> + #include <X11/Xlibint.h> + #include <X11/Xlib-xcb.h> ++#include "locking.h" + + #define XLIB_SEQUENCE_COMPARE(a,op,b) (((long) (a) - (long) (b)) op 0) + +@@ -29,6 +30,12 @@ typedef struct _X11XCBPrivate { + uint64_t last_flushed; + enum XEventQueueOwner event_owner; + XID next_xid; ++ ++ /* handle simultaneous threads waiting for events, ++ * used in wait_or_poll_for_event ++ */ ++ xcondition_t event_notify; ++ int event_waiter; + } _X11XCBPrivate; + + /* xcb_disp.c */ +diff --git a/src/xcb_disp.c b/src/xcb_disp.c +index dfd6803..628c654 100644 +--- a/src/xcb_disp.c ++++ b/src/xcb_disp.c +@@ -93,6 +93,7 @@ int _XConnectXCB(Display *dpy, _Xconst char *display, char **fullnamep, int *scr + dpy->xcb->pending_requests_tail = &dpy->xcb->pending_requests; + dpy->xcb->next_xid = xcb_generate_id(dpy->xcb->connection); + ++ dpy->xcb->event_notify = xcondition_malloc(); + return !xcb_connection_has_error(c); + } + +@@ -106,5 +107,6 @@ void _XFreeX11XCBStructure(Display *dpy) + dpy->xcb->pending_requests = tmp->next; + free(tmp); + } ++ xcondition_free(dpy->xcb->event_notify); + Xfree(dpy->xcb); + } +diff --git a/src/xcb_io.c b/src/xcb_io.c +index d0abf4c..fc8e53f 100644 +--- a/src/xcb_io.c ++++ b/src/xcb_io.c +@@ -125,9 +125,20 @@ static xcb_generic_event_t * wait_or_poll_for_event(Display *dpy, int wait) + xcb_generic_event_t *event; + if(wait) + { +- UnlockDisplay(dpy); +- event = xcb_wait_for_event(c); +- LockDisplay(dpy); ++ if(dpy->xcb->event_waiter) ++ { ++ ConditionWait(dpy, dpy->xcb->event_notify); ++ event = xcb_poll_for_event(c); ++ } ++ else ++ { ++ dpy->xcb->event_waiter = 1; ++ UnlockDisplay(dpy); ++ event = xcb_wait_for_event(c); ++ LockDisplay(dpy); ++ dpy->xcb->event_waiter = 0; ++ ConditionBroadcast(dpy, dpy->xcb->event_notify); ++ } + } + else + event = xcb_poll_for_event(c); +@@ -228,7 +239,6 @@ static void process_responses(Display *dpy, int wait_for_first_event, xcb_generi + _XIOError(dpy); + + assert(XLIB_SEQUENCE_COMPARE(dpy->last_request_read, <=, dpy->request)); +- assert(!wait_for_first_event); + } + + int _XEventsQueued(Display *dpy, int mode) +-- +1.6.0.2.307.gc427.dirty + diff --git a/x11-libs/libX11/files/xlib-0004-Ensure-that-_XReadEvents-always-leaves-an-event-in-t.patch b/x11-libs/libX11/files/xlib-0004-Ensure-that-_XReadEvents-always-leaves-an-event-in-t.patch new file mode 100644 index 0000000..3087efc --- a/dev/null +++ b/x11-libs/libX11/files/xlib-0004-Ensure-that-_XReadEvents-always-leaves-an-event-in-t.patch @@ -0,0 +1,33 @@ +From bbeafc850181cc0bf9724c71f1aa0015acdb7480 Mon Sep 17 00:00:00 2001 +From: Keith Packard <keithp@keithp.com> +Date: Sat, 11 Oct 2008 21:43:58 -0700 +Subject: [PATCH 4/4] Ensure that _XReadEvents always leaves an event in the queue on return + +XNextEvent assumes that the event queue will be non-empty on return from +_XReadEvents, but with multiple event readers running, the previous change +could leave the queue empty on return from process_responses. Re-invoke +process_responses until the queue is non-empty. + +Signed-off-by: Keith Packard <keithp@keithp.com> +--- + src/xcb_io.c | 4 +++- + 1 files changed, 3 insertions(+), 1 deletions(-) + +diff --git a/src/xcb_io.c b/src/xcb_io.c +index fc8e53f..2256a3f 100644 +--- a/src/xcb_io.c ++++ b/src/xcb_io.c +@@ -267,7 +267,9 @@ void _XReadEvents(Display *dpy) + if(dpy->xcb->event_owner != XlibOwnsEventQueue) + return; + check_internal_connections(dpy); +- process_responses(dpy, 1, 0, 0); ++ do { ++ process_responses(dpy, 1, 0, 0); ++ } while (dpy->qlen == 0); + } + + /* +-- +1.6.0.2.307.gc427.dirty + diff --git a/x11-libs/libX11/libX11-9999.ebuild b/x11-libs/libX11/libX11-9999.ebuild index fc552b7..dd2d36b 100644 --- a/x11-libs/libX11/libX11-9999.ebuild +++ b/x11-libs/libX11/libX11-9999.ebuild @@ -1,8 +1,6 @@ # Copyright 1999-2007 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -EGIT_BRANCH="handoff" - inherit x-modular DESCRIPTION="X.Org X11 library" diff --git a/x11-libs/libxcb/Manifest b/x11-libs/libxcb/Manifest index fc77a2f..cddce81 100644 --- a/x11-libs/libxcb/Manifest +++ b/x11-libs/libxcb/Manifest @@ -1 +1,10 @@ -EBUILD libxcb-9999.ebuild 513 RMD160 6e29a77a90882154c3aa761089ee872ec1f7fda2 SHA1 241c050a4966960cb3f5ea1219b63374eb2fead9 SHA256 6b952228b8eecb2941269cbda20b8d63dde79fcfdb7acc844204abc166d22ed7 +AUX xcb-0001-Receive-selected-replies-in-event-queue.patch 1656 RMD160 3e277074b725be7f7df358427b43a795b81803cf SHA1 f7e026aeb67d429184700facc10a161fe10d60fc SHA256 54b82f190833f57bd6980a84e0d6bd99f1bc351261b22ee595e5c05447fb5db2 +AUX xcb-0002-Remove-libxcb-xlib-and-xcbxlib.h.patch 11458 RMD160 109250bb704724cab974fdad5c87aa91ac77795c SHA1 be3d5c5b846db98f05d0b900278bb392fec274e8 SHA256 a551e66852b063963453d1110f4bbb09fee65623fb3128571d15596dcd479dbf +AUX xcb-0003-Inline-_xcb_lock_io-_xcb_unlock_io-and-_xcb_wait_i.patch 6531 RMD160 5747911d8076a81ebc4081f2c49ee0dc214f44ee SHA1 d57928b18c4f951e33461b499679f4a4fa7d9a19 SHA256 9f13be703b74ee6690a021d69a33936fc140fb10b5f13b6b64e63d1044c45b6b +AUX xcb-0004-Use-sequence-number-ranges-in-pending-replies.patch 2086 RMD160 cf911baf61c57de69de1d4b2f58077b51e6feb94 SHA1 929a34f47b179ef90c8e57ab3458e070103b6f4f SHA256 d03cc99aa85d110eb7f4d96e86d2bafe88790831899973ff1f198a9ca2b2eab1 +AUX xcb-0005-Track-64-bit-sequence-numbers-internally.patch 8893 RMD160 bcb865a1ea13b1df994de9cf072bd818b74528c7 SHA1 54ca1ef1c0559822d1af18e6ab6aa676e68a3f5c SHA256 07b9465c6f756c36a3a21d0b410867ed7a196186900d3b7aa88684dc65f756ad +AUX xcb-0006-Support-handing-off-socket-write-permission-to-exter.patch 9558 RMD160 46d52da6f3d62f6d118b0e8c8a3293b5e17017be SHA1 b28bbb73c414067a8b8c7af5ebb33983e444f703 SHA256 4c445a3ceb74fe6fd526d1cf1b6fe6f142f255b98fbb407dd1b84fbf3c89449c +AUX xcb-0007-Bump-version-number-to-1.2.patch 610 RMD160 79d60b28c9f746b6b3e5420d3abb85e431f566b5 SHA1 649b8ea99d5b4f3f64d76bc0c83abaee3c6a7472 SHA256 2839419e70158c4dbfe6d8498a10ee318ad84e6e363f5fc25346c5f4d80e6120 +AUX xcb-0008-Use-XCB_QUEUE_BUFFER_SIZE-for-added-queue-declaration.patch 651 RMD160 5d89c5f538329a337a7276542d31b497935c98a9 SHA1 11cbc0184504f37a607d6d2d97fc9528afda5078 SHA256 678560113fa3229f7e83ca64a0d6a20c897a735fe1aa0df80e871a1f10d70c11 +AUX xcb-0009-mv-closure-block.patch 644 RMD160 29fef31e7432f0600aefa2fbc9021d27ffd6d14c SHA1 58001458d872fa39737cd38087b57d3c0cd1ffd5 SHA256 757d30144cfa28202823551394c2b7704c7801d03882f5f8c2e6a56fa5b4f98b +EBUILD libxcb-9999.ebuild 526 RMD160 b6277a1922870068e403fca71c2fb73b6a17eb18 SHA1 b9ba4ad87d79ab71b357145075ab7d50ca9d7a8d SHA256 ec3cc0b7984bf6612b78222e8c3d19dbcfd3f894cd011b6859d7886b390a4199 diff --git a/x11-libs/libxcb/files/xcb-0001-Receive-selected-replies-in-event-queue.patch b/x11-libs/libxcb/files/xcb-0001-Receive-selected-replies-in-event-queue.patch new file mode 100644 index 0000000..5d6c034 --- a/dev/null +++ b/x11-libs/libxcb/files/xcb-0001-Receive-selected-replies-in-event-queue.patch @@ -0,0 +1,44 @@ +From 5e9cdc3321f6f273ae1844e7bee2e6ba6072243f Mon Sep 17 00:00:00 2001 +From: Jamey Sharp <jamey@minilop.net> +Date: Thu, 18 Sep 2008 16:47:04 -0700 +Subject: [PATCH] Receive selected replies in event queue. + +Commit by Josh Triplett and Jamey Sharp. +--- + src/xcb_in.c | 5 +++-- + src/xcbext.h | 3 ++- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/xcb_in.c b/src/xcb_in.c +index f613772..2e32719 100644 +--- a/src/xcb_in.c ++++ b/src/xcb_in.c +@@ -183,8 +183,9 @@ static int read_packet(xcb_connection_t *c) + ((xcb_generic_event_t *) buf)->full_sequence = c->in.request_read; + + /* reply, or checked error */ +- if( genrep.response_type == XCB_REPLY || +- (genrep.response_type == XCB_ERROR && pend && (pend->flags & XCB_REQUEST_CHECKED))) ++ if(!(pend && (pend->flags & XCB_REQUEST_QUEUE_RESPONSE)) && ++ ((pend && (pend->flags & XCB_REQUEST_CHECKED) && genrep.response_type == XCB_ERROR) || ++ genrep.response_type == XCB_REPLY)) + { + reader_list *reader; + struct reply_list *cur = malloc(sizeof(struct reply_list)); +diff --git a/src/xcbext.h b/src/xcbext.h +index 01dd590..856ad3d 100644 +--- a/src/xcbext.h ++++ b/src/xcbext.h +@@ -54,7 +54,8 @@ typedef struct { + enum xcb_send_request_flags_t { + XCB_REQUEST_CHECKED = 1 << 0, + XCB_REQUEST_RAW = 1 << 1, +- XCB_REQUEST_DISCARD_REPLY = 1 << 2 ++ XCB_REQUEST_DISCARD_REPLY = 1 << 2, ++ XCB_REQUEST_QUEUE_RESPONSE = 1 << 3 /* Put the response in the event queue */ + }; + + unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request); +-- +1.6.0.2.307.gc427.dirty + diff --git a/x11-libs/libxcb/files/xcb-0002-Remove-libxcb-xlib-and-xcbxlib.h.patch b/x11-libs/libxcb/files/xcb-0002-Remove-libxcb-xlib-and-xcbxlib.h.patch new file mode 100644 index 0000000..f271a67 --- a/dev/null +++ b/x11-libs/libxcb/files/xcb-0002-Remove-libxcb-xlib-and-xcbxlib.h.patch @@ -0,0 +1,396 @@ +From c8282883b7d7360e554412357e4b20a00f6fe2eb Mon Sep 17 00:00:00 2001 +From: Jamey Sharp <jamey@minilop.net> +Date: Fri, 14 Mar 2008 12:08:09 -0700 +Subject: [PATCH] Remove libxcb-xlib and xcbxlib.h. + +--- + Makefile.am | 4 +-- + configure.ac | 1 - + src/Makefile.am | 9 +---- + src/xcb_conn.c | 49 +------------------------------ + src/xcb_xlib.c | 87 ------------------------------------------------------- + src/xcbint.h | 19 +----------- + src/xcbxlib.h | 44 ---------------------------- + xcb-xlib.pc.in | 11 ------- + 8 files changed, 6 insertions(+), 218 deletions(-) + delete mode 100644 src/xcb_xlib.c + delete mode 100644 src/xcbxlib.h + delete mode 100644 xcb-xlib.pc.in + +diff --git a/Makefile.am b/Makefile.am +index ee97180..3a2f6f5 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -2,9 +2,7 @@ SUBDIRS=src tests doc + + pkgconfigdir = $(libdir)/pkgconfig + +-pkgconfig_DATA = \ +-xcb.pc \ +-xcb-xlib.pc ++pkgconfig_DATA = xcb.pc + + if BUILD_COMPOSITE + pkgconfig_DATA += xcb-composite.pc +diff --git a/configure.ac b/configure.ac +index c3d3595..e9d9412 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -142,7 +142,6 @@ tests/Makefile + + AC_CONFIG_FILES([ + xcb.pc +-xcb-xlib.pc + xcb-composite.pc + xcb-damage.pc + xcb-dpms.pc +diff --git a/src/Makefile.am b/src/Makefile.am +index aa8b755..bf6e991 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1,5 +1,4 @@ +-lib_LTLIBRARIES = libxcb.la \ +- libxcb-xlib.la ++lib_LTLIBRARIES = libxcb.la + + EXTHEADERS = xproto.h \ + bigreq.h \ +@@ -29,10 +28,6 @@ libxcb_la_LDFLAGS = -version-info 1:0:0 + + XCB_LIBS = libxcb.la + +-libxcb_xlib_la_LDFLAGS = -version-info 0:0:0 +-libxcb_xlib_la_LIBADD = $(XCB_LIBS) +-libxcb_xlib_la_SOURCES = xcb_xlib.c +- + # FIXME: find a way to autogenerate this from the XML files. + + EXTHEADERS += composite.h +@@ -257,7 +252,7 @@ endif + + + +-xcbinclude_HEADERS = xcb.h xcbext.h xcbxlib.h $(EXTHEADERS) ++xcbinclude_HEADERS = xcb.h xcbext.h $(EXTHEADERS) + noinst_HEADERS = xcbint.h + + BUILT_SOURCES = $(EXTSOURCES) $(EXTHEADERS) +diff --git a/src/xcb_conn.c b/src/xcb_conn.c +index 02f60bd..2bb8661 100644 +--- a/src/xcb_conn.c ++++ b/src/xcb_conn.c +@@ -59,21 +59,6 @@ static int set_fd_flags(const int fd) + return 1; + } + +-static int _xcb_xlib_init(_xcb_xlib *xlib) +-{ +- xlib->lock = 0; +-#ifndef NDEBUG +- xlib->sloppy_lock = (getenv("LIBXCB_ALLOW_SLOPPY_LOCK") != 0); +-#endif +- pthread_cond_init(&xlib->cond, 0); +- return 1; +-} +- +-static void _xcb_xlib_destroy(_xcb_xlib *xlib) +-{ +- pthread_cond_destroy(&xlib->cond); +-} +- + static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info) + { + static const char pad[3]; +@@ -230,7 +215,6 @@ xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info) + if(!( + set_fd_flags(fd) && + pthread_mutex_init(&c->iolock, 0) == 0 && +- _xcb_xlib_init(&c->xlib) && + _xcb_in_init(&c->in) && + _xcb_out_init(&c->out) && + write_setup(c, auth_info) && +@@ -255,7 +239,6 @@ void xcb_disconnect(xcb_connection_t *c) + close(c->fd); + + pthread_mutex_destroy(&c->iolock); +- _xcb_xlib_destroy(&c->xlib); + _xcb_in_destroy(&c->in); + _xcb_out_destroy(&c->out); + +@@ -275,12 +258,6 @@ void _xcb_conn_shutdown(xcb_connection_t *c) + void _xcb_lock_io(xcb_connection_t *c) + { + pthread_mutex_lock(&c->iolock); +- while(c->xlib.lock) +- { +- if(pthread_equal(c->xlib.thread, pthread_self())) +- break; +- pthread_cond_wait(&c->xlib.cond, &c->iolock); +- } + } + + void _xcb_unlock_io(xcb_connection_t *c) +@@ -290,25 +267,12 @@ void _xcb_unlock_io(xcb_connection_t *c) + + void _xcb_wait_io(xcb_connection_t *c, pthread_cond_t *cond) + { +- int xlib_locked = c->xlib.lock; +- if(xlib_locked) +- { +- c->xlib.lock = 0; +- pthread_cond_broadcast(&c->xlib.cond); +- } + pthread_cond_wait(cond, &c->iolock); +- if(xlib_locked) +- { +- while(c->xlib.lock) +- pthread_cond_wait(&c->xlib.cond, &c->iolock); +- c->xlib.lock = 1; +- c->xlib.thread = pthread_self(); +- } + } + + int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count) + { +- int ret, xlib_locked; ++ int ret; + fd_set rfds, wfds; + + /* If the thing I should be doing is already being done, wait for it. */ +@@ -329,12 +293,6 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec + ++c->out.writing; + } + +- xlib_locked = c->xlib.lock; +- if(xlib_locked) +- { +- c->xlib.lock = 0; +- pthread_cond_broadcast(&c->xlib.cond); +- } + _xcb_unlock_io(c); + do { + ret = select(c->fd + 1, &rfds, &wfds, 0, 0); +@@ -345,11 +303,6 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec + ret = 0; + } + _xcb_lock_io(c); +- if(xlib_locked) +- { +- c->xlib.lock = 1; +- c->xlib.thread = pthread_self(); +- } + + if(ret) + { +diff --git a/src/xcb_xlib.c b/src/xcb_xlib.c +deleted file mode 100644 +index 1b573e8..0000000 +--- a/src/xcb_xlib.c ++++ /dev/null +@@ -1,87 +0,0 @@ +-/* Copyright (C) 2005 Bart Massey and Jamey Sharp. +- * +- * Permission is hereby granted, free of charge, to any person obtaining a +- * copy of this software and associated documentation files (the "Software"), +- * to deal in the Software without restriction, including without limitation +- * the rights to use, copy, modify, merge, publish, distribute, sublicense, +- * and/or sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice shall be included in +- * all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +- * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- * +- * Except as contained in this notice, the names of the authors or their +- * institutions shall not be used in advertising or otherwise to promote the +- * sale, use or other dealings in this Software without prior written +- * authorization from the authors. +- */ +- +-#include "xcbxlib.h" +-#include "xcbint.h" +- +-#include <assert.h> +- +-#ifdef HAVE_BACKTRACE +-#include <execinfo.h> +-#include <stdio.h> +-#include <stdlib.h> +-#endif +- +-static void xcb_xlib_printbt(void) +-{ +-#ifdef HAVE_BACKTRACE +- void *array[20]; +- int size; +- char **strings; +- int i; +- +- size = backtrace(array, 20); +- strings = backtrace_symbols(array, size); +- +- fprintf(stderr, "Locking assertion failure. Backtrace:\n"); +- +- for (i = 0; i < size; ++i) +- fprintf(stderr, "#%i %s\n", i, strings[i]); +- +- free(strings); +-#endif +-} +- +-#ifndef NDEBUG +-#define xcb_assert(c,x) do { if (!(x)) { xcb_xlib_printbt(); if (!(c)->xlib.sloppy_lock) assert(x); } } while(0) +-#else +-#define xcb_assert(c,x) +-#endif +- +-unsigned int xcb_get_request_sent(xcb_connection_t *c) +-{ +- if(c->has_error) +- return 0; +- return c->out.request; +-} +- +-void xcb_xlib_lock(xcb_connection_t *c) +-{ +- _xcb_lock_io(c); +- xcb_assert(c, !c->xlib.lock); +- c->xlib.lock = 1; +- c->xlib.thread = pthread_self(); +- _xcb_unlock_io(c); +-} +- +-void xcb_xlib_unlock(xcb_connection_t *c) +-{ +- _xcb_lock_io(c); +- xcb_assert(c, c->xlib.lock); +- xcb_assert(c, pthread_equal(c->xlib.thread, pthread_self())); +- c->xlib.lock = 0; +- pthread_cond_broadcast(&c->xlib.cond); +- _xcb_unlock_io(c); +-} +diff --git a/src/xcbint.h b/src/xcbint.h +index ab0264f..86e00a4 100644 +--- a/src/xcbint.h ++++ b/src/xcbint.h +@@ -126,16 +126,6 @@ int _xcb_in_read(xcb_connection_t *c); + int _xcb_in_read_block(xcb_connection_t *c, void *buf, int nread); + + +-/* xcb_xlib.c */ +- +-typedef struct _xcb_xlib { +- int lock; +- int sloppy_lock; +- pthread_t thread; +- pthread_cond_t cond; +-} _xcb_xlib; +- +- + /* xcb_xid.c */ + + typedef struct _xcb_xid { +@@ -173,7 +163,6 @@ struct xcb_connection_t { + + /* I/O data */ + pthread_mutex_t iolock; +- _xcb_xlib xlib; + _xcb_in in; + _xcb_out out; + +@@ -183,6 +172,8 @@ struct xcb_connection_t { + }; + + void _xcb_conn_shutdown(xcb_connection_t *c); ++void _xcb_lock_io(xcb_connection_t *c); ++void _xcb_unlock_io(xcb_connection_t *c); + void _xcb_wait_io(xcb_connection_t *c, pthread_cond_t *cond); + int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count); + +@@ -195,10 +186,4 @@ int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display); + #pragma GCC visibility pop + #endif + +- +-/* xcb_conn.c symbols visible to xcb-xlib */ +- +-void _xcb_lock_io(xcb_connection_t *c); +-void _xcb_unlock_io(xcb_connection_t *c); +- + #endif +diff --git a/src/xcbxlib.h b/src/xcbxlib.h +deleted file mode 100644 +index 4cb5cd4..0000000 +--- a/src/xcbxlib.h ++++ /dev/null +@@ -1,44 +0,0 @@ +-/* +- * Copyright (C) 2005 Bart Massey and Jamey Sharp. +- * 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"), +- * to deal in the Software without restriction, including without limitation +- * the rights to use, copy, modify, merge, publish, distribute, sublicense, +- * and/or sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following conditions: +- * +- * The above copyright notice and this permission notice shall be included in +- * all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +- * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +- * +- * Except as contained in this notice, the names of the authors or their +- * institutions shall not be used in advertising or otherwise to promote the +- * sale, use or other dealings in this Software without prior written +- * authorization from the authors. +- */ +- +-/* This include file declares functions used by Xlib/XCB, but nothing else +- * should ever use these functions or link to libxcb-xlib. */ +- +-#ifndef __XCBXLIB_H +-#define __XCBXLIB_H +- +-#include <pthread.h> +-#include "xcb.h" +- +-/* The caller of this function must hold the xlib lock, using the lock +- * functions below. */ +-unsigned int xcb_get_request_sent(xcb_connection_t *c); +- +-void xcb_xlib_lock(xcb_connection_t *c); +-void xcb_xlib_unlock(xcb_connection_t *c); +- +-#endif +diff --git a/xcb-xlib.pc.in b/xcb-xlib.pc.in +deleted file mode 100644 +index f28b529..0000000 +--- a/xcb-xlib.pc.in ++++ /dev/null +@@ -1,11 +0,0 @@ +-prefix=@prefix@ +-exec_prefix=@exec_prefix@ +-libdir=@libdir@ +-includedir=@includedir@ +- +-Name: XCB Xlib +-Description: XCB Xlib support functions +-Version: @PACKAGE_VERSION@ +-Requires: xcb +-Libs: -L${libdir} -lxcb-xlib +-Cflags: -I${includedir} +-- +1.6.0.2.307.gc427.dirty + diff --git a/x11-libs/libxcb/files/xcb-0003-Inline-_xcb_lock_io-_xcb_unlock_io-and-_xcb_wait_i.patch b/x11-libs/libxcb/files/xcb-0003-Inline-_xcb_lock_io-_xcb_unlock_io-and-_xcb_wait_i.patch new file mode 100644 index 0000000..9cd3266 --- a/dev/null +++ b/x11-libs/libxcb/files/xcb-0003-Inline-_xcb_lock_io-_xcb_unlock_io-and-_xcb_wait_i.patch @@ -0,0 +1,212 @@ +From 19cf1afecb67abfa9834fc1428f0b7cf8763f3a5 Mon Sep 17 00:00:00 2001 +From: Jamey Sharp <jamey@minilop.net> +Date: Fri, 14 Mar 2008 12:08:35 -0700 +Subject: [PATCH] Inline _xcb_lock_io, _xcb_unlock_io, and _xcb_wait_io. + +These functions are once again a single pthread call, so just make that +call directly. +--- + src/xcb_conn.c | 25 +++++-------------------- + src/xcb_in.c | 16 ++++++++-------- + src/xcb_out.c | 12 ++++++------ + src/xcbint.h | 3 --- + 4 files changed, 19 insertions(+), 37 deletions(-) + +diff --git a/src/xcb_conn.c b/src/xcb_conn.c +index 2bb8661..5b097f7 100644 +--- a/src/xcb_conn.c ++++ b/src/xcb_conn.c +@@ -97,12 +97,12 @@ static int write_setup(xcb_connection_t *c, xcb_auth_info_t *auth_info) + } + assert(count <= (int) (sizeof(parts) / sizeof(*parts))); + +- _xcb_lock_io(c); ++ pthread_mutex_lock(&c->iolock); + { + struct iovec *parts_ptr = parts; + ret = _xcb_out_send(c, &parts_ptr, &count); + } +- _xcb_unlock_io(c); ++ pthread_mutex_unlock(&c->iolock); + return ret; + } + +@@ -255,21 +255,6 @@ void _xcb_conn_shutdown(xcb_connection_t *c) + c->has_error = 1; + } + +-void _xcb_lock_io(xcb_connection_t *c) +-{ +- pthread_mutex_lock(&c->iolock); +-} +- +-void _xcb_unlock_io(xcb_connection_t *c) +-{ +- pthread_mutex_unlock(&c->iolock); +-} +- +-void _xcb_wait_io(xcb_connection_t *c, pthread_cond_t *cond) +-{ +- pthread_cond_wait(cond, &c->iolock); +-} +- + int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count) + { + int ret; +@@ -278,7 +263,7 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec + /* If the thing I should be doing is already being done, wait for it. */ + if(count ? c->out.writing : c->in.reading) + { +- _xcb_wait_io(c, cond); ++ pthread_cond_wait(cond, &c->iolock); + return 1; + } + +@@ -293,7 +278,7 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec + ++c->out.writing; + } + +- _xcb_unlock_io(c); ++ pthread_mutex_unlock(&c->iolock); + do { + ret = select(c->fd + 1, &rfds, &wfds, 0, 0); + } while (ret == -1 && errno == EINTR); +@@ -302,7 +287,7 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec + _xcb_conn_shutdown(c); + ret = 0; + } +- _xcb_lock_io(c); ++ pthread_mutex_lock(&c->iolock); + + if(ret) + { +diff --git a/src/xcb_in.c b/src/xcb_in.c +index 2e32719..0c04621 100644 +--- a/src/xcb_in.c ++++ b/src/xcb_in.c +@@ -342,7 +342,7 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_ + if(c->has_error) + return 0; + +- _xcb_lock_io(c); ++ pthread_mutex_lock(&c->iolock); + + /* If this request has not been written yet, write it. */ + if(_xcb_out_flush_to(c, request)) +@@ -382,7 +382,7 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_ + } + + wake_up_next_reader(c); +- _xcb_unlock_io(c); ++ pthread_mutex_unlock(&c->iolock); + return ret; + } + +@@ -397,9 +397,9 @@ int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply, + return 1; /* would not block */ + } + assert(reply != 0); +- _xcb_lock_io(c); ++ pthread_mutex_lock(&c->iolock); + ret = poll_for_reply(c, request, reply, error); +- _xcb_unlock_io(c); ++ pthread_mutex_unlock(&c->iolock); + return ret; + } + +@@ -408,14 +408,14 @@ xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c) + xcb_generic_event_t *ret; + if(c->has_error) + return 0; +- _xcb_lock_io(c); ++ pthread_mutex_lock(&c->iolock); + /* get_event returns 0 on empty list. */ + while(!(ret = get_event(c))) + if(!_xcb_conn_wait(c, &c->in.event_cond, 0, 0)) + break; + + wake_up_next_reader(c); +- _xcb_unlock_io(c); ++ pthread_mutex_unlock(&c->iolock); + return ret; + } + +@@ -424,12 +424,12 @@ xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c) + xcb_generic_event_t *ret = 0; + if(!c->has_error) + { +- _xcb_lock_io(c); ++ pthread_mutex_lock(&c->iolock); + /* FIXME: follow X meets Z architecture changes. */ + ret = get_event(c); + if(!ret && _xcb_in_read(c)) /* _xcb_in_read shuts down the connection on error */ + ret = get_event(c); +- _xcb_unlock_io(c); ++ pthread_mutex_unlock(&c->iolock); + } + return ret; + } +diff --git a/src/xcb_out.c b/src/xcb_out.c +index 000b121..ad4240a 100644 +--- a/src/xcb_out.c ++++ b/src/xcb_out.c +@@ -187,10 +187,10 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect + workaround = WORKAROUND_GLX_GET_FB_CONFIGS_BUG; + + /* get a sequence number and arrange for delivery. */ +- _xcb_lock_io(c); ++ pthread_mutex_lock(&c->iolock); + /* wait for other writing threads to get out of my way. */ + while(c->out.writing) +- _xcb_wait_io(c, &c->out.cond); ++ pthread_cond_wait(&c->out.cond, &c->iolock); + + request = ++c->out.request; + /* send GetInputFocus (sync_req) when 64k-2 requests have been sent without +@@ -231,7 +231,7 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect + _xcb_conn_shutdown(c); + request = 0; + } +- _xcb_unlock_io(c); ++ pthread_mutex_unlock(&c->iolock); + return request; + } + +@@ -240,9 +240,9 @@ int xcb_flush(xcb_connection_t *c) + int ret; + if(c->has_error) + return 0; +- _xcb_lock_io(c); ++ pthread_mutex_lock(&c->iolock); + ret = _xcb_out_flush_to(c, c->out.request); +- _xcb_unlock_io(c); ++ pthread_mutex_unlock(&c->iolock); + return ret; + } + +@@ -297,7 +297,7 @@ int _xcb_out_flush_to(xcb_connection_t *c, unsigned int request) + return _xcb_out_send(c, &vec_ptr, &count); + } + while(c->out.writing) +- _xcb_wait_io(c, &c->out.cond); ++ pthread_cond_wait(&c->out.cond, &c->iolock); + assert(XCB_SEQUENCE_COMPARE(c->out.request_written, >=, request)); + return 1; + } +diff --git a/src/xcbint.h b/src/xcbint.h +index 86e00a4..d610a10 100644 +--- a/src/xcbint.h ++++ b/src/xcbint.h +@@ -172,9 +172,6 @@ struct xcb_connection_t { + }; + + void _xcb_conn_shutdown(xcb_connection_t *c); +-void _xcb_lock_io(xcb_connection_t *c); +-void _xcb_unlock_io(xcb_connection_t *c); +-void _xcb_wait_io(xcb_connection_t *c, pthread_cond_t *cond); + int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count); + + +-- +1.6.0.2.307.gc427.dirty + diff --git a/x11-libs/libxcb/files/xcb-0004-Use-sequence-number-ranges-in-pending-replies.patch b/x11-libs/libxcb/files/xcb-0004-Use-sequence-number-ranges-in-pending-replies.patch new file mode 100644 index 0000000..caffc51 --- a/dev/null +++ b/x11-libs/libxcb/files/xcb-0004-Use-sequence-number-ranges-in-pending-replies.patch @@ -0,0 +1,59 @@ +From 040cf8ca8bda9687e77141c71e559acb020eeeb5 Mon Sep 17 00:00:00 2001 +From: Jamey Sharp <jamey@minilop.net> +Date: Fri, 14 Mar 2008 20:18:29 -0700 +Subject: [PATCH] Use sequence number ranges in pending replies + +This allows optimizing adjacent pending replies with the same flags, and +will help support default flags for a range of future requests. + +Commit by Josh Triplett and Jamey Sharp. +--- + src/xcb_in.c | 11 +++++++---- + 1 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/src/xcb_in.c b/src/xcb_in.c +index 0c04621..61027b7 100644 +--- a/src/xcb_in.c ++++ b/src/xcb_in.c +@@ -52,7 +52,8 @@ struct reply_list { + }; + + typedef struct pending_reply { +- unsigned int request; ++ unsigned int first_request; ++ unsigned int last_request; + enum workarounds workaround; + int flags; + struct pending_reply *next; +@@ -112,7 +113,7 @@ static int read_packet(xcb_connection_t *c) + } + + while(c->in.pending_replies && +- XCB_SEQUENCE_COMPARE (c->in.pending_replies->request, <=, c->in.request_completed)) ++ XCB_SEQUENCE_COMPARE (c->in.pending_replies->last_request, <=, c->in.request_completed)) + { + pending_reply *oldpend = c->in.pending_replies; + c->in.pending_replies = oldpend->next; +@@ -128,7 +129,9 @@ static int read_packet(xcb_connection_t *c) + if(genrep.response_type == XCB_ERROR || genrep.response_type == XCB_REPLY) + { + pend = c->in.pending_replies; +- if(pend && pend->request != c->in.request_read) ++ if(pend && ++ (XCB_SEQUENCE_COMPARE(c->in.request_read, <, pend->first_request) || ++ XCB_SEQUENCE_COMPARE(c->in.request_read, >, pend->last_request))) + pend = 0; + } + +@@ -507,7 +510,7 @@ int _xcb_in_expect_reply(xcb_connection_t *c, unsigned int request, enum workaro + _xcb_conn_shutdown(c); + return 0; + } +- pend->request = request; ++ pend->first_request = pend->last_request = request; + pend->workaround = workaround; + pend->flags = flags; + pend->next = 0; +-- +1.6.0.2.307.gc427.dirty + diff --git a/x11-libs/libxcb/files/xcb-0005-Track-64-bit-sequence-numbers-internally.patch b/x11-libs/libxcb/files/xcb-0005-Track-64-bit-sequence-numbers-internally.patch new file mode 100644 index 0000000..d3e852b --- a/dev/null +++ b/x11-libs/libxcb/files/xcb-0005-Track-64-bit-sequence-numbers-internally.patch @@ -0,0 +1,221 @@ +From cdaaa63e7cc2729164da1326c54ad100eade0aac Mon Sep 17 00:00:00 2001 +From: Jamey Sharp <jamey@minilop.net> +Date: Wed, 21 May 2008 14:43:53 -0700 +Subject: [PATCH] Track 64-bit sequence numbers internally. + +External APIs that used 32-bit sequence numbers continue to do so. + +Commit by Josh Triplett and Jamey Sharp. +--- + src/xcb_in.c | 35 ++++++++++++++++++++--------------- + src/xcb_out.c | 4 ++-- + src/xcbint.h | 17 +++++++++-------- + 3 files changed, 31 insertions(+), 25 deletions(-) + +diff --git a/src/xcb_in.c b/src/xcb_in.c +index 61027b7..ff59894 100644 +--- a/src/xcb_in.c ++++ b/src/xcb_in.c +@@ -52,8 +52,8 @@ struct reply_list { + }; + + typedef struct pending_reply { +- unsigned int first_request; +- unsigned int last_request; ++ uint64_t first_request; ++ uint64_t last_request; + enum workarounds workaround; + int flags; + struct pending_reply *next; +@@ -94,8 +94,8 @@ static int read_packet(xcb_connection_t *c) + /* Compute 32-bit sequence number of this packet. */ + if((genrep.response_type & 0x7f) != XCB_KEYMAP_NOTIFY) + { +- unsigned int lastread = c->in.request_read; +- c->in.request_read = (lastread & 0xffff0000) | genrep.sequence; ++ uint64_t lastread = c->in.request_read; ++ c->in.request_read = (lastread & UINT64_C(0xffffffffffff0000)) | genrep.sequence; + if(XCB_SEQUENCE_COMPARE(c->in.request_read, <, lastread)) + c->in.request_read += 0x10000; + if(XCB_SEQUENCE_COMPARE(c->in.request_read, >, c->in.request_expected)) +@@ -204,10 +204,10 @@ static int read_packet(xcb_connection_t *c) + c->in.current_reply_tail = &cur->next; + for(reader = c->in.readers; + reader && +- XCB_SEQUENCE_COMPARE(reader->request, <=, c->in.request_read); ++ XCB_SEQUENCE_COMPARE_32(reader->request, <=, c->in.request_read); + reader = reader->next) + { +- if(reader->request == c->in.request_read) ++ if(XCB_SEQUENCE_COMPARE_32(reader->request, ==, c->in.request_read)) + { + pthread_cond_signal(reader->data); + break; +@@ -289,7 +289,7 @@ static int poll_for_reply(xcb_connection_t *c, unsigned int request, void **repl + head = 0; + /* We've read requests past the one we want, so if it has replies we have + * them all and they're in the replies map. */ +- else if(XCB_SEQUENCE_COMPARE(request, <, c->in.request_read)) ++ else if(XCB_SEQUENCE_COMPARE_32(request, <, c->in.request_read)) + { + head = _xcb_map_remove(c->in.replies, request); + if(head && head->next) +@@ -297,7 +297,7 @@ static int poll_for_reply(xcb_connection_t *c, unsigned int request, void **repl + } + /* We're currently processing the responses to the request we want, and we + * have a reply ready to return. So just return it without blocking. */ +- else if(request == c->in.request_read && c->in.current_reply) ++ else if(XCB_SEQUENCE_COMPARE_32(request, ==, c->in.request_read) && c->in.current_reply) + { + head = c->in.current_reply; + c->in.current_reply = head->next; +@@ -306,7 +306,7 @@ static int poll_for_reply(xcb_connection_t *c, unsigned int request, void **repl + } + /* We know this request can't have any more replies, and we've already + * established it doesn't have a reply now. Don't bother blocking. */ +- else if(request == c->in.request_completed) ++ else if(XCB_SEQUENCE_COMPARE_32(request, ==, c->in.request_completed)) + head = 0; + /* We may have more replies on the way for this request: block until we're + * sure. */ +@@ -339,6 +339,7 @@ static int poll_for_reply(xcb_connection_t *c, unsigned int request, void **repl + + void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e) + { ++ uint64_t widened_request; + void *ret = 0; + if(e) + *e = 0; +@@ -347,8 +348,12 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_ + + pthread_mutex_lock(&c->iolock); + ++ widened_request = (c->out.request & UINT64_C(0xffffffff00000000)) | request; ++ if(widened_request > c->out.request) ++ widened_request -= UINT64_C(1) << 32; ++ + /* If this request has not been written yet, write it. */ +- if(_xcb_out_flush_to(c, request)) ++ if(_xcb_out_flush_to(c, widened_request)) + { + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + reader_list reader; +@@ -356,7 +361,7 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_ + + for(prev_reader = &c->in.readers; + *prev_reader && +- XCB_SEQUENCE_COMPARE ((*prev_reader)->request, <=, request); ++ XCB_SEQUENCE_COMPARE_32((*prev_reader)->request, <=, request); + prev_reader = &(*prev_reader)->next) + { + /* empty */; +@@ -372,7 +377,7 @@ void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_ + + for(prev_reader = &c->in.readers; + *prev_reader && +- XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, request); ++ XCB_SEQUENCE_COMPARE_32((*prev_reader)->request, <=, request); + prev_reader = &(*prev_reader)->next) + { + if(*prev_reader == &reader) +@@ -446,8 +451,8 @@ xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t co + void *reply; + if(c->has_error) + return 0; +- if(XCB_SEQUENCE_COMPARE(cookie.sequence,>,c->in.request_expected) +- && XCB_SEQUENCE_COMPARE(cookie.sequence,>,c->in.request_completed)) ++ if(XCB_SEQUENCE_COMPARE_32(cookie.sequence,>,c->in.request_expected) ++ && XCB_SEQUENCE_COMPARE_32(cookie.sequence,>,c->in.request_completed)) + { + free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), &ret)); + assert(!ret); +@@ -501,7 +506,7 @@ void _xcb_in_destroy(_xcb_in *in) + } + } + +-int _xcb_in_expect_reply(xcb_connection_t *c, unsigned int request, enum workarounds workaround, int flags) ++int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags) + { + pending_reply *pend = malloc(sizeof(pending_reply)); + assert(workaround != WORKAROUND_NONE || flags != 0); +diff --git a/src/xcb_out.c b/src/xcb_out.c +index ad4240a..1094ceb 100644 +--- a/src/xcb_out.c ++++ b/src/xcb_out.c +@@ -112,7 +112,7 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect + } fields; + uint32_t packet; + } sync_req = { { /* GetInputFocus */ 43, 0, 1 } }; +- unsigned int request; ++ uint64_t request; + uint32_t prefix[3] = { 0 }; + int veclen = req->count; + enum workarounds workaround = WORKAROUND_NONE; +@@ -282,7 +282,7 @@ int _xcb_out_send(xcb_connection_t *c, struct iovec **vector, int *count) + return ret; + } + +-int _xcb_out_flush_to(xcb_connection_t *c, unsigned int request) ++int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request) + { + assert(XCB_SEQUENCE_COMPARE(request, <=, c->out.request)); + if(XCB_SEQUENCE_COMPARE(c->out.request_written, >=, request)) +diff --git a/src/xcbint.h b/src/xcbint.h +index d610a10..cd351de 100644 +--- a/src/xcbint.h ++++ b/src/xcbint.h +@@ -52,7 +52,8 @@ enum lazy_reply_tag + + #define XCB_PAD(i) (-(i) & 3) + +-#define XCB_SEQUENCE_COMPARE(a,op,b) ((int) ((a) - (b)) op 0) ++#define XCB_SEQUENCE_COMPARE(a,op,b) ((int64_t) ((a) - (b)) op 0) ++#define XCB_SEQUENCE_COMPARE_32(a,op,b) (((int) (a) - (int) (b)) op 0) + + /* xcb_list.c */ + +@@ -75,8 +76,8 @@ typedef struct _xcb_out { + char queue[4096]; + int queue_len; + +- unsigned int request; +- unsigned int request_written; ++ uint64_t request; ++ uint64_t request_written; + + pthread_mutex_t reqlenlock; + enum lazy_reply_tag maximum_request_length_tag; +@@ -90,7 +91,7 @@ int _xcb_out_init(_xcb_out *out); + void _xcb_out_destroy(_xcb_out *out); + + int _xcb_out_send(xcb_connection_t *c, struct iovec **vector, int *count); +-int _xcb_out_flush_to(xcb_connection_t *c, unsigned int request); ++int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request); + + + /* xcb_in.c */ +@@ -102,9 +103,9 @@ typedef struct _xcb_in { + char queue[4096]; + int queue_len; + +- unsigned int request_expected; +- unsigned int request_read; +- unsigned int request_completed; ++ uint64_t request_expected; ++ uint64_t request_read; ++ uint64_t request_completed; + struct reply_list *current_reply; + struct reply_list **current_reply_tail; + +@@ -120,7 +121,7 @@ typedef struct _xcb_in { + int _xcb_in_init(_xcb_in *in); + void _xcb_in_destroy(_xcb_in *in); + +-int _xcb_in_expect_reply(xcb_connection_t *c, unsigned int request, enum workarounds workaround, int flags); ++int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags); + + int _xcb_in_read(xcb_connection_t *c); + int _xcb_in_read_block(xcb_connection_t *c, void *buf, int nread); +-- +1.6.0.2.307.gc427.dirty + diff --git a/x11-libs/libxcb/files/xcb-0006-Support-handing-off-socket-write-permission-to-exter.patch b/x11-libs/libxcb/files/xcb-0006-Support-handing-off-socket-write-permission-to-exter.patch new file mode 100644 index 0000000..6533850 --- a/dev/null +++ b/x11-libs/libxcb/files/xcb-0006-Support-handing-off-socket-write-permission-to-exter.patch @@ -0,0 +1,264 @@ +From 3ee2dac8e00be4666bd74d5b5263ff52c2f9f199 Mon Sep 17 00:00:00 2001 +From: Josh Triplett <josh@freedesktop.org> +Date: Sun, 16 Mar 2008 23:16:08 -0700 +Subject: [PATCH] Support handing off socket write permission to external code. + +Libraries like Xlib, some XCB language bindings, and potentially others +have a common problem: they want to share the X connection with XCB. This +requires coordination of request sequence numbers. Previously, XCB had an +Xlib-specific lock, and allowed Xlib to block XCB from making requests. +Now we've replaced that lock with a handoff mechanism, xcb_take_socket, +allowing external code to ask XCB for permission to take over the write +side of the socket and send raw data with xcb_writev. The caller of +xcb_take_socket must supply a callback which XCB can call when it wants +the write side of the socket back to make a request. This callback +synchronizes with the external socket owner, flushes any output queues if +appropriate, and then returns the sequence num |
