summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJamey Sharp <jamey@minilop.net>2011-03-18 17:36:32 -0700
committerJamey Sharp <jamey@minilop.net>2011-03-18 21:59:44 -0700
commit29a974f212aae9eeff4fde99f110cee08f0312f3 (patch)
tree6fd18ff26be4e743233ed6fa53f642c585d7ec0d /src
parent131e867fca5cda94e634af69214ad54e066ac871 (diff)
Dequeue readers that can't receive any new responses.
Signed-off-by: Jamey Sharp <jamey@minilop.net> Reviewed-by: Josh Triplett <josh@freedesktop.org>
Diffstat (limited to 'src')
-rw-r--r--src/xcb_in.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/src/xcb_in.c b/src/xcb_in.c
index fb55111..1199e23 100644
--- a/src/xcb_in.c
+++ b/src/xcb_in.c
@@ -80,6 +80,17 @@ typedef struct reader_list {
struct reader_list *next;
} reader_list;
+static void remove_finished_readers(reader_list **prev_reader, uint64_t completed)
+{
+ while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, completed))
+ {
+ /* If you don't have what you're looking for now, you never
+ * will. Wake up and leave me alone. */
+ pthread_cond_signal((*prev_reader)->data);
+ *prev_reader = (*prev_reader)->next;
+ }
+}
+
static int read_packet(xcb_connection_t *c)
{
xcb_generic_reply_t genrep;
@@ -130,6 +141,8 @@ static int read_packet(xcb_connection_t *c)
if(genrep.response_type == XCB_ERROR)
c->in.request_completed = c->in.request_read;
+
+ remove_finished_readers(&c->in.readers, c->in.request_completed);
}
if(genrep.response_type == XCB_ERROR || genrep.response_type == XCB_REPLY)
@@ -194,7 +207,6 @@ static int read_packet(xcb_connection_t *c)
if( genrep.response_type == XCB_REPLY ||
(genrep.response_type == XCB_ERROR && pend && (pend->flags & XCB_REQUEST_CHECKED)))
{
- reader_list *reader;
struct reply_list *cur = malloc(sizeof(struct reply_list));
if(!cur)
{
@@ -206,17 +218,8 @@ static int read_packet(xcb_connection_t *c)
cur->next = 0;
*c->in.current_reply_tail = cur;
c->in.current_reply_tail = &cur->next;
- for(reader = c->in.readers;
- reader &&
- XCB_SEQUENCE_COMPARE(reader->request, <=, c->in.request_read);
- reader = reader->next)
- {
- pthread_cond_signal(reader->data);
- if(reader->request == c->in.request_read)
- {
- break;
- }
- }
+ if(c->in.readers && c->in.readers->request == c->in.request_read)
+ pthread_cond_signal(c->in.readers->data);
return 1;
}