Replace current_reply generic queue with hand-written version. No generic queues...
authorJamey Sharp <jamey@minilop.net>
Mon, 27 Feb 2006 06:58:17 +0000 (22:58 -0800)
committerJamey Sharp <jamey@minilop.net>
Mon, 27 Feb 2006 06:58:17 +0000 (22:58 -0800)
src/xcb_in.c
src/xcb_list.c
src/xcbint.h

index cdaf558..76990f3 100644 (file)
@@ -41,6 +41,11 @@ struct event_list {
     struct event_list *next;
 };
 
+struct reply_list {
+    void *reply;
+    struct reply_list *next;
+};
+
 typedef struct pending_reply {
     unsigned int request;
     enum workarounds workaround;
@@ -99,10 +104,11 @@ static int read_packet(XCBConnection *c)
                     c->in.pending_replies_tail = &c->in.pending_replies;
                 free(oldpend);
             }
-            if(!_xcb_queue_is_empty(c->in.current_reply))
+            if(c->in.current_reply)
             {
                 _xcb_map_put(c->in.replies, lastread, c->in.current_reply);
-                c->in.current_reply = _xcb_queue_new();
+                c->in.current_reply = 0;
+                c->in.current_reply_tail = &c->in.current_reply;
             }
         }
         if(c->in.request_read < lastread)
@@ -140,7 +146,13 @@ static int read_packet(XCBConnection *c)
     if(genrep.response_type == 1 || (genrep.response_type == 0 && pend && (pend->flags & XCB_REQUEST_CHECKED)))
     {
         XCBReplyData *reader = _xcb_list_find(c->in.readers, match_reply, &c->in.request_read);
-        _xcb_queue_enqueue(c->in.current_reply, buf);
+        struct reply_list *cur = malloc(sizeof(struct reply_list));
+        if(!cur)
+            return 0;
+        cur->reply = buf;
+        cur->next = 0;
+        *c->in.current_reply_tail = cur;
+        c->in.current_reply_tail = &cur->next;
         if(reader)
             pthread_cond_signal(reader->data);
         return 1;
@@ -175,6 +187,17 @@ static XCBGenericEvent *get_event(XCBConnection *c)
     return ret;
 }
 
+static void free_reply_list(struct reply_list *head)
+{
+    while(head)
+    {
+        struct reply_list *cur = head;
+        head = cur->next;
+        free(cur->reply);
+        free(cur);
+    }
+}
+
 static int read_block(const int fd, void *buf, const size_t len)
 {
     int done = 0;
@@ -202,6 +225,7 @@ void *XCBWaitForReply(XCBConnection *c, unsigned int request, XCBGenericError **
 {
     pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
     XCBReplyData reader;
+    struct reply_list *head;
     void *ret = 0;
     if(e)
         *e = 0;
@@ -222,31 +246,40 @@ void *XCBWaitForReply(XCBConnection *c, unsigned int request, XCBGenericError **
 
     /* If this request has not been read yet, wait for it. */
     while(((signed int) (c->in.request_read - request) < 0 ||
-            (c->in.request_read == request &&
-            _xcb_queue_is_empty(c->in.current_reply))))
+            (c->in.request_read == request && !c->in.current_reply)))
         if(!_xcb_conn_wait(c, /*should_write*/ 0, &cond))
             goto done;
 
     if(c->in.request_read != request)
     {
-        _xcb_queue *q = _xcb_map_get(c->in.replies, request);
-        if(q)
+        head = _xcb_map_remove(c->in.replies, request);
+        if(head && head->next)
+            _xcb_map_put(c->in.replies, request, head->next);
+    }
+    else
+    {
+        head = c->in.current_reply;
+        if(head)
         {
-            ret = _xcb_queue_dequeue(q);
-            if(_xcb_queue_is_empty(q))
-                _xcb_queue_delete(_xcb_map_remove(c->in.replies, request), free);
+            c->in.current_reply = head->next;
+            if(!head->next)
+                c->in.current_reply_tail = &c->in.current_reply;
         }
     }
-    else
-        ret = _xcb_queue_dequeue(c->in.current_reply);
 
-    if(ret && ((XCBGenericRep *) ret)->response_type == 0) /* X error */
+    if(head)
     {
-        if(e)
-            *e = ret;
-        else
-            free(ret);
-        ret = 0;
+        ret = head->reply;
+        free(head);
+
+        if(((XCBGenericRep *) ret)->response_type == 0) /* X error */
+        {
+            if(e)
+                *e = ret;
+            else
+                free(ret);
+            ret = 0;
+        }
     }
 
 done:
@@ -319,13 +352,13 @@ int _xcb_in_init(_xcb_in *in)
     in->queue_len = 0;
 
     in->request_read = 0;
-    in->current_reply = _xcb_queue_new();
 
     in->replies = _xcb_map_new();
     in->readers = _xcb_list_new();
-    if(!in->current_reply || !in->replies || !in->readers)
+    if(!in->replies || !in->readers)
         return 0;
 
+    in->current_reply_tail = &in->current_reply;
     in->events_tail = &in->events;
     in->pending_replies_tail = &in->pending_replies;
 
@@ -335,8 +368,8 @@ int _xcb_in_init(_xcb_in *in)
 void _xcb_in_destroy(_xcb_in *in)
 {
     pthread_cond_destroy(&in->event_cond);
-    _xcb_queue_delete(in->current_reply, free);
-    _xcb_map_delete(in->replies, free);
+    free_reply_list(in->current_reply);
+    _xcb_map_delete(in->replies, (void (*)(void *)) free_reply_list);
     _xcb_list_delete(in->readers, 0);
     while(in->events)
     {
index 5b2edc0..6a72c16 100644 (file)
@@ -144,16 +144,6 @@ void *_xcb_list_find(_xcb_list *list, int (*cmp)(const void *, const void *), co
     return 0;
 }
 
-_xcb_queue *_xcb_queue_new(void) __attribute__ ((alias ("_xcb_list_new")));
-void _xcb_queue_delete(_xcb_queue *q, XCBListFreeFunc do_free) __attribute__ ((alias ("_xcb_list_delete")));
-int _xcb_queue_enqueue(_xcb_queue *q, void *data) __attribute__ ((alias ("_xcb_list_append")));
-void *_xcb_queue_dequeue(_xcb_queue *q) __attribute__ ((alias ("_xcb_list_remove_head")));
-
-int _xcb_queue_is_empty(_xcb_queue *q)
-{
-    return q->head == 0;
-}
-
 typedef struct {
     unsigned int key;
     void *value;
index 6a61d18..c508504 100644 (file)
@@ -53,14 +53,6 @@ void *_xcb_list_remove_head(_xcb_list *list);
 void *_xcb_list_remove(_xcb_list *list, int (*cmp)(const void *, const void *), const void *data);
 void *_xcb_list_find(_xcb_list *list, int (*cmp)(const void *, const void *), const void *data);
 
-typedef _xcb_list _xcb_queue;
-
-_xcb_queue *_xcb_queue_new(void);
-void _xcb_queue_delete(_xcb_queue *q, XCBListFreeFunc do_free);
-int _xcb_queue_enqueue(_xcb_queue *q, void *data);
-void *_xcb_queue_dequeue(_xcb_queue *q);
-int _xcb_queue_is_empty(_xcb_queue *q);
-
 typedef _xcb_list _xcb_map;
 
 _xcb_map *_xcb_map_new(void);
@@ -106,7 +98,8 @@ typedef struct _xcb_in {
     int queue_len;
 
     unsigned int request_read;
-    _xcb_queue *current_reply;
+    struct reply_list *current_reply;
+    struct reply_list **current_reply_tail;
 
     _xcb_map *replies;
     struct event_list *events;