diff -rupN /il2/users/yaakovk/tests/X/xcblock/libX11-1.2/src/xcb_io.c libX11/src/xcb_io.c --- /il2/users/yaakovk/tests/X/xcblock/libX11-1.2/src/xcb_io.c 2009-02-17 16:24:40.000000000 +0200 +++ libX11/src/xcb_io.c 2010-01-17 16:17:31.000000000 +0200 @@ -120,6 +120,25 @@ static void call_handlers(Display *dpy, _XError(dpy, (xError *) buf); } +static int check_for_waiting_request(Display * dpy, xcb_generic_event_t * event) +{ + int ret = 0; + if (dpy->xcb->pending_requests != 0 && event->response_type == X_Error) + { + PendingRequest* pr = dpy->xcb->pending_requests; + while (pr != NULL && !ret) + { + if (XLIB_SEQUENCE_COMPARE(pr->sequence, ==, event->full_sequence)) + { + pr->reply = event; + ret = 1; + } + pr = pr->next; + } + } + return ret; +} + static xcb_generic_event_t * wait_or_poll_for_event(Display *dpy, int wait) { xcb_connection_t *c = dpy->xcb->connection; @@ -138,6 +157,8 @@ static xcb_generic_event_t * wait_or_pol event = xcb_wait_for_event(c); LockDisplay(dpy); dpy->xcb->event_waiter = 0; + if (check_for_waiting_request(dpy, event)) + event = NULL; ConditionBroadcast(dpy, dpy->xcb->event_notify); } } @@ -171,6 +192,8 @@ static void process_responses(Display *d { PendingRequest *req = dpy->xcb->pending_requests; unsigned long event_sequence = dpy->last_request_read; + while (req && req->reply) + req = req->next; if(event) widen(&event_sequence, event->full_sequence); assert(!(req && current_request && !XLIB_SEQUENCE_COMPARE(req->sequence, <=, current_request))); @@ -215,7 +238,7 @@ static void process_responses(Display *d else if(req && xcb_poll_for_reply(dpy->xcb->connection, req->sequence, &reply, &error)) { unsigned int sequence = req->sequence; - if(!reply) + if(!reply && !req->reply) { dpy->xcb->pending_requests = req->next; if(!dpy->xcb->pending_requests) @@ -426,9 +449,35 @@ static PendingRequest * insert_pending_r dpy->xcb->pending_requests_tail = &(node->next); *cur = node; } + (*cur)->reply = 0; return *cur; } +static void remove_pending_request(Display* dpy, PendingRequest* req) +{ + PendingRequest *pr = dpy->xcb->pending_requests; + if (pr == req) + { + dpy->xcb->pending_requests = pr->next; + if (!dpy->xcb->pending_requests) + dpy->xcb->pending_requests_tail = &dpy->xcb->pending_requests; + } + else + { + while (pr) + { + if (pr->next == req) + { + pr->next = req->next; + if (!pr->next) + dpy->xcb->pending_requests_tail = &(pr->next); + } + pr = pr->next; + } + free(req); + } +} + /* * _XReply - Wait for a reply packet and copy its contents into the * specified rep. @@ -447,14 +496,30 @@ Status _XReply(Display *dpy, xReply *rep if(dpy->flags & XlibDisplayIOError) return 0; - _XSend(dpy, NULL, 0); current = insert_pending_request(dpy); + _XSend(dpy, NULL, 0); /* FIXME: drop the Display lock while waiting? * Complicates process_responses. */ reply = xcb_wait_for_reply(c, current->sequence, &error); + if (reply == NULL && error == NULL) + { + if(dpy->xcb->event_waiter && current->reply == NULL) + { + ConditionWait(dpy, dpy->xcb->event_notify); + } + if (current->reply != NULL && current->reply->response_type == X_Error) + { + if (current->reply->response_type == X_Error) + error = (xcb_generic_error_t *)current->reply; + else + reply = (char*)current->reply; + remove_pending_request(dpy, current); + } + } check_internal_connections(dpy); - process_responses(dpy, 0, &error, current->sequence); + if (error == NULL) + process_responses(dpy, 0, &error, current->sequence); if(error) { diff -rupN /il2/users/yaakovk/tests/X/xcblock/libX11-1.2/src/Xxcbint.h libX11/src/Xxcbint.h --- /il2/users/yaakovk/tests/X/xcblock/libX11-1.2/src/Xxcbint.h 2009-02-02 18:34:16.000000000 +0200 +++ libX11/src/Xxcbint.h 2010-01-17 16:17:28.000000000 +0200 @@ -16,6 +16,7 @@ typedef struct PendingRequest PendingReq struct PendingRequest { PendingRequest *next; unsigned long sequence; + xcb_generic_event_t* reply; }; typedef struct _X11XCBPrivate {