}
c->in.request_completed = c->in.request_read - 1;
}
- if(genrep.response_type != XCBReply) /* error or event */
- c->in.request_completed = c->in.request_read; /* XXX: does event/error imply no more replies? */
+ if(genrep.response_type == XCBError)
+ c->in.request_completed = c->in.request_read;
while(c->in.pending_replies &&
XCB_SEQUENCE_COMPARE (c->in.pending_replies->request, <=, c->in.request_completed))
buf = malloc(length + (genrep.response_type == XCBReply ? 0 : sizeof(CARD32)));
if(!buf)
+ {
+ _xcb_conn_shutdown(c);
return 0;
+ }
if(_xcb_in_read_block(c, buf, length) <= 0)
{
free(buf);
reader_list *reader;
struct reply_list *cur = malloc(sizeof(struct reply_list));
if(!cur)
+ {
+ _xcb_conn_shutdown(c);
return 0;
+ }
cur->reply = buf;
cur->next = 0;
*c->in.current_reply_tail = cur;
event = malloc(sizeof(struct event_list));
if(!event)
{
+ _xcb_conn_shutdown(c);
free(buf);
return 0;
}
void *ret = 0;
if(e)
*e = 0;
+ if(c->has_error)
+ return 0;
pthread_mutex_lock(&c->iolock);
int XCBPollForReply(XCBConnection *c, unsigned int request, void **reply, XCBGenericError **error)
{
int ret;
+ if(c->has_error)
+ {
+ *reply = 0;
+ if(error)
+ *error = 0;
+ return 1; /* would not block */
+ }
assert(reply != 0);
pthread_mutex_lock(&c->iolock);
ret = poll_for_reply(c, request, reply, error);
return ret;
}
-XCBGenericEvent *XCBWaitEvent(XCBConnection *c)
-{
- return XCBWaitForEvent(c);
-}
-
XCBGenericEvent *XCBWaitForEvent(XCBConnection *c)
{
XCBGenericEvent *ret;
+ if(c->has_error)
+ return 0;
pthread_mutex_lock(&c->iolock);
/* get_event returns 0 on empty list. */
while(!(ret = get_event(c)))
XCBGenericEvent *XCBPollForEvent(XCBConnection *c, int *error)
{
- XCBGenericEvent *ret = 0;
- pthread_mutex_lock(&c->iolock);
+ if(!c->has_error)
+ {
+ XCBGenericEvent *ret = 0;
+ int success;
+ pthread_mutex_lock(&c->iolock);
+ /* FIXME: follow X meets Z architecture changes. */
+ success = _xcb_in_read(c);
+ if(success)
+ ret = get_event(c);
+ pthread_mutex_unlock(&c->iolock);
+ if(success)
+ {
+ if(error)
+ *error = 0;
+ return ret;
+ }
+ }
if(error)
- *error = 0;
- /* FIXME: follow X meets Z architecture changes. */
- if(_xcb_in_read(c))
- ret = get_event(c);
- else if(error)
*error = -1;
else
{
fprintf(stderr, "XCBPollForEvent: I/O error occured, but no handler provided.\n");
abort();
}
- pthread_mutex_unlock(&c->iolock);
- return ret;
+ return 0;
}
-unsigned int XCBGetRequestRead(XCBConnection *c)
+XCBGenericError *XCBRequestCheck(XCBConnection *c, XCBVoidCookie cookie)
{
- unsigned int ret;
- pthread_mutex_lock(&c->iolock);
- /* FIXME: follow X meets Z architecture changes. */
- _xcb_in_read(c);
- ret = c->in.request_read;
- pthread_mutex_unlock(&c->iolock);
+ /* FIXME: this could hold the lock to avoid syncing unnecessarily, but
+ * that would require factoring the locking out of XCBGetInputFocus,
+ * XCBGetInputFocusReply, and XCBWaitForReply. */
+ XCBGenericError *ret;
+ void *reply;
+ if(c->has_error)
+ return 0;
+ if(XCB_SEQUENCE_COMPARE(cookie.sequence,>,c->in.request_expected)
+ && XCB_SEQUENCE_COMPARE(cookie.sequence,>,c->in.request_completed))
+ {
+ free(XCBGetInputFocusReply(c, XCBGetInputFocus(c), &ret));
+ assert(!ret);
+ }
+ reply = XCBWaitForReply(c, cookie.sequence, &ret);
+ assert(!reply);
return ret;
}
pending_reply *pend = malloc(sizeof(pending_reply));
assert(workaround != WORKAROUND_NONE || flags != 0);
if(!pend)
+ {
+ _xcb_conn_shutdown(c);
return 0;
+ }
pend->request = request;
pend->workaround = workaround;
pend->flags = flags;
c->in.queue_len += n;
while(read_packet(c))
/* empty */;
- return (n > 0) || (n < 0 && errno == EAGAIN);
+ if((n > 0) || (n < 0 && errno == EAGAIN))
+ return 1;
+ _xcb_conn_shutdown(c);
+ return 0;
}
int _xcb_in_read_block(XCBConnection *c, void *buf, int len)
{
int ret = read_block(c->fd, (char *) buf + done, len - done);
if(ret <= 0)
+ {
+ _xcb_conn_shutdown(c);
return ret;
+ }
}
return len;