diff options
| author | Jamey Sharp <jamey@minilop.net> | 2010-04-16 19:45:11 -0700 |
|---|---|---|
| committer | Jamey Sharp <jamey@minilop.net> | 2010-04-18 01:28:14 -0700 |
| commit | f2735889908d6e5a7f8dbee42f00c54a52665191 (patch) | |
| tree | 8731e92d7ee991c3e08054c10e361858e194d462 | |
| parent | d9cf5885b0f97942fbbd2a7cc50118132ece50f6 (diff) | |
Pending requests are always added in-order.
Replace insert_pending_request, which did an in-order search of the
queue to find the right insertion point, with a simpler
append_pending_request, and use that in _XSend as well.
Includes assertions to check that the list of pending requests is in
order by sequence number and does not have duplicates.
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Reviewed-by: Josh Triplett <josh@freedesktop.org>
| -rw-r--r-- | src/Xxcbint.h | 2 | ||||
| -rw-r--r-- | src/xcb_disp.c | 1 | ||||
| -rw-r--r-- | src/xcb_io.c | 71 |
3 files changed, 39 insertions, 35 deletions
diff --git a/src/Xxcbint.h b/src/Xxcbint.h index f6afa183..8b6a3619 100644 --- a/src/Xxcbint.h +++ b/src/Xxcbint.h @@ -21,7 +21,7 @@ struct PendingRequest { typedef struct _X11XCBPrivate { xcb_connection_t *connection; PendingRequest *pending_requests; - PendingRequest **pending_requests_tail; + PendingRequest *pending_requests_tail; xcb_generic_event_t *next_event; char *real_bufmax; char *reply_data; diff --git a/src/xcb_disp.c b/src/xcb_disp.c index 2625966d..622afe76 100644 --- a/src/xcb_disp.c +++ b/src/xcb_disp.c @@ -95,7 +95,6 @@ int _XConnectXCB(Display *dpy, _Xconst char *display, char **fullnamep, int *scr dpy->fd = xcb_get_file_descriptor(c); dpy->xcb->connection = c; - 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(); diff --git a/src/xcb_io.c b/src/xcb_io.c index 463ef844..77287d7b 100644 --- a/src/xcb_io.c +++ b/src/xcb_io.c @@ -116,6 +116,38 @@ static void check_internal_connections(Display *dpy) } } +static PendingRequest *append_pending_request(Display *dpy, unsigned long sequence) +{ + PendingRequest *node = malloc(sizeof(PendingRequest)); + assert(node); + node->next = NULL; + node->sequence = sequence; + if(dpy->xcb->pending_requests_tail) + { + assert(XLIB_SEQUENCE_COMPARE(dpy->xcb->pending_requests_tail->sequence, <, node->sequence)); + assert(dpy->xcb->pending_requests_tail->next == NULL); + dpy->xcb->pending_requests_tail->next = node; + } + else + dpy->xcb->pending_requests = node; + dpy->xcb->pending_requests_tail = node; + return node; +} + +static void dequeue_pending_request(Display *dpy, PendingRequest *req) +{ + assert(req == dpy->xcb->pending_requests); + dpy->xcb->pending_requests = req->next; + if(!dpy->xcb->pending_requests) + { + assert(req == dpy->xcb->pending_requests_tail); + dpy->xcb->pending_requests_tail = NULL; + } + else + assert(XLIB_SEQUENCE_COMPARE(req->sequence, <, dpy->xcb->pending_requests->sequence)); + free(req); +} + static int handle_error(Display *dpy, xError *err, Bool in_XReply) { _XExtension *ext; @@ -252,12 +284,7 @@ static void process_responses(Display *dpy, int wait_for_first_event, xcb_generi free(error); } if(!reply) - { - dpy->xcb->pending_requests = req->next; - if(!dpy->xcb->pending_requests) - dpy->xcb->pending_requests_tail = &dpy->xcb->pending_requests; - free(req); - } + dequeue_pending_request(dpy, req); } else break; @@ -331,14 +358,7 @@ void _XSend(Display *dpy, const char *data, long size) { uint64_t sequence; for(sequence = dpy->xcb->last_flushed; sequence < dpy->request; ++sequence) - { - PendingRequest *req = malloc(sizeof(PendingRequest)); - assert(req); - req->next = NULL; - req->sequence = sequence; - *dpy->xcb->pending_requests_tail = req; - dpy->xcb->pending_requests_tail = &req->next; - } + append_pending_request(dpy, sequence); } requests = dpy->request - dpy->xcb->last_flushed; dpy->xcb->last_flushed = dpy->request; @@ -430,24 +450,6 @@ static void _XFreeReplyData(Display *dpy, Bool force) dpy->xcb->reply_data = NULL; } -static PendingRequest * insert_pending_request(Display *dpy) -{ - PendingRequest **cur = &dpy->xcb->pending_requests; - while(*cur && XLIB_SEQUENCE_COMPARE((*cur)->sequence, <, dpy->request)) - cur = &((*cur)->next); - if(!*cur || (*cur)->sequence != dpy->request) - { - PendingRequest *node = malloc(sizeof(PendingRequest)); - assert(node); - node->next = *cur; - node->sequence = dpy->request; - if(cur == dpy->xcb->pending_requests_tail) - dpy->xcb->pending_requests_tail = &(node->next); - *cur = node; - } - return *cur; -} - /* * _XReply - Wait for a reply packet and copy its contents into the * specified rep. @@ -467,7 +469,10 @@ Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard) return 0; _XSend(dpy, NULL, 0); - current = insert_pending_request(dpy); + if(dpy->xcb->pending_requests_tail && dpy->xcb->pending_requests_tail->sequence == dpy->request) + current = dpy->xcb->pending_requests_tail; + else + current = append_pending_request(dpy, dpy->request); /* FIXME: drop the Display lock while waiting? * Complicates process_responses. */ reply = xcb_wait_for_reply(c, current->sequence, &error); |
