- /* If this request has not been written yet, write it. */
- if(!_xcb_out_flush_to(c, request))
- goto done; /* error */
-
- for(prev_reader = &c->in.readers; *prev_reader && (*prev_reader)->request <= request; prev_reader = &(*prev_reader)->next)
- if((*prev_reader)->request == request)
- goto done; /* error */
-
- reader.request = request;
- reader.data = &cond;
- reader.next = *prev_reader;
- *prev_reader = &reader;
-
- /* If this request has not completed yet and has no reply waiting,
- * wait for one. */
- while(!poll_for_reply(c, request, &ret, e))
- if(!_xcb_conn_wait(c, &cond, 0, 0))
- goto done;
-
-done:
- for(prev_reader = &c->in.readers; *prev_reader && (*prev_reader)->request <= request; prev_reader = &(*prev_reader)->next)
- if(*prev_reader == &reader)
- {
- *prev_reader = (*prev_reader)->next;
+static void insert_pending_discard(xcb_connection_t *c, pending_reply **prev_next, uint64_t seq)
+{
+ pending_reply *pend;
+ pend = malloc(sizeof(*pend));
+ if(!pend)
+ {
+ _xcb_conn_shutdown(c);
+ return;
+ }
+
+ pend->first_request = seq;
+ pend->last_request = seq;
+ pend->workaround = 0;
+ pend->flags = XCB_REQUEST_DISCARD_REPLY;
+ pend->next = *prev_next;
+ *prev_next = pend;
+
+ if(!pend->next)
+ c->in.pending_replies_tail = &pend->next;
+}
+
+static void discard_reply(xcb_connection_t *c, uint64_t request)
+{
+ void *reply;
+ pending_reply **prev_pend;
+
+ /* Free any replies or errors that we've already read. Stop if
+ * xcb_wait_for_reply would block or we've run out of replies. */
+ while(poll_for_reply(c, request, &reply, 0) && reply)
+ free(reply);
+
+ /* If we've proven there are no more responses coming, we're done. */
+ if(XCB_SEQUENCE_COMPARE(request, <=, c->in.request_completed))
+ return;
+
+ /* Walk the list of pending requests. Mark the first match for deletion. */
+ for(prev_pend = &c->in.pending_replies; *prev_pend; prev_pend = &(*prev_pend)->next)
+ {
+ if(XCB_SEQUENCE_COMPARE((*prev_pend)->first_request, >, request))