X-Git-Url: http://git.demorecorder.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fxcb_in.c;h=2ac1e5239c728dd5aa44f6748eb67d2cde4e870f;hb=2c8b5994b3fbba343199ef555594a32e29d8bcee;hp=d513cdd331788783d49861d43231fc73bfd84112;hpb=a92716f1da2741fca850b3c37299e80032726276;p=free-sw%2Fxcb%2Flibxcb diff --git a/src/xcb_in.c b/src/xcb_in.c index d513cdd..2ac1e52 100644 --- a/src/xcb_in.c +++ b/src/xcb_in.c @@ -108,8 +108,8 @@ static int read_packet(XCBConnection *c) } 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)) @@ -142,7 +142,10 @@ static int read_packet(XCBConnection *c) 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); @@ -164,7 +167,10 @@ static int read_packet(XCBConnection *c) 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; @@ -187,6 +193,7 @@ static int read_packet(XCBConnection *c) event = malloc(sizeof(struct event_list)); if(!event) { + _xcb_conn_shutdown(c); free(buf); return 0; } @@ -308,6 +315,8 @@ void *XCBWaitForReply(XCBConnection *c, unsigned int request, XCBGenericError ** void *ret = 0; if(e) *e = 0; + if(c->has_error) + return 0; pthread_mutex_lock(&c->iolock); @@ -356,6 +365,13 @@ void *XCBWaitForReply(XCBConnection *c, unsigned int request, XCBGenericError ** 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); @@ -366,6 +382,8 @@ int XCBPollForReply(XCBConnection *c, unsigned int request, void **reply, XCBGen 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))) @@ -379,22 +397,31 @@ XCBGenericEvent *XCBWaitForEvent(XCBConnection *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; } XCBGenericError *XCBRequestCheck(XCBConnection *c, XCBVoidCookie cookie) @@ -404,6 +431,8 @@ XCBGenericError *XCBRequestCheck(XCBConnection *c, XCBVoidCookie cookie) * 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)) { @@ -464,7 +493,10 @@ int _xcb_in_expect_reply(XCBConnection *c, unsigned int request, enum workaround 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; @@ -481,7 +513,10 @@ int _xcb_in_read(XCBConnection *c) 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) @@ -498,7 +533,10 @@ 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;