summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamey Sharp <jamey@minilop.net>2010-04-16 19:45:11 -0700
committerJamey Sharp <jamey@minilop.net>2010-04-18 01:28:14 -0700
commitf2735889908d6e5a7f8dbee42f00c54a52665191 (patch)
tree8731e92d7ee991c3e08054c10e361858e194d462
parentd9cf5885b0f97942fbbd2a7cc50118132ece50f6 (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.h2
-rw-r--r--src/xcb_disp.c1
-rw-r--r--src/xcb_io.c71
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);