- /* event, or error without a waiting reader */
- _xcb_queue_enqueue(c->in.events, buf);
- pthread_cond_signal(&c->in.event_cond);
- return 1; /* I have something for you... */
+static int poll_for_reply(XCBConnection *c, unsigned int request, void **reply, XCBGenericError **error)
+{
+ struct reply_list *head;
+
+ /* If an error occurred when issuing the request, fail immediately. */
+ if(!request)
+ head = 0;
+ /* We've read requests past the one we want, so if it has replies we have
+ * them all and they're in the replies map. */
+ else if(request < c->in.request_read)
+ {
+ head = _xcb_map_remove(c->in.replies, request);
+ if(head && head->next)
+ _xcb_map_put(c->in.replies, request, head->next);
+ }
+ /* We're currently processing the responses to the request we want, and we
+ * have a reply ready to return. So just return it without blocking. */
+ else if(request == c->in.request_read && c->in.current_reply)
+ {
+ head = c->in.current_reply;
+ c->in.current_reply = head->next;
+ if(!head->next)
+ c->in.current_reply_tail = &c->in.current_reply;
+ }
+ /* We know this request can't have any more replies, and we've already
+ * established it doesn't have a reply now. Don't bother blocking. */
+ else if(request == c->in.request_completed)
+ head = 0;
+ /* We may have more replies on the way for this request: block until we're
+ * sure. */
+ else
+ return 0;
+
+ if(error)
+ *error = 0;
+ *reply = 0;
+
+ if(head)
+ {
+ if(((XCBGenericRep *) head->reply)->response_type == XCBError)
+ {
+ if(error)
+ *error = head->reply;
+ else
+ free(head->reply);
+ }
+ else
+ *reply = head->reply;
+
+ free(head);
+ }
+
+ return 1;