More return value changes, and make _xcb_in_read_packet static since it is not called from outside xcb_in.c.
This commit is contained in:
parent
5b1d39e27b
commit
6149c7a6b5
|
@ -208,10 +208,10 @@ int _xcb_conn_wait(XCBConnection *c, const int should_write, pthread_cond_t *con
|
|||
if(ret)
|
||||
{
|
||||
if(FD_ISSET(c->fd, &rfds))
|
||||
ret = ret && _xcb_in_read(c) > 0;
|
||||
ret = ret && _xcb_in_read(c);
|
||||
|
||||
if(FD_ISSET(c->fd, &wfds))
|
||||
ret = ret && _xcb_out_write(c) > 0;
|
||||
ret = ret && _xcb_out_write(c);
|
||||
}
|
||||
|
||||
if(should_write)
|
||||
|
|
176
src/xcb_in.c
176
src/xcb_in.c
|
@ -68,6 +68,90 @@ static void wake_up_next_reader(XCBConnection *c)
|
|||
assert(pthreadret == 0);
|
||||
}
|
||||
|
||||
static int read_packet(XCBConnection *c)
|
||||
{
|
||||
XCBGenericRep genrep;
|
||||
int length = 32;
|
||||
unsigned char *buf;
|
||||
|
||||
/* Wait for there to be enough data for us to read a whole packet */
|
||||
if(c->in.queue_len < length)
|
||||
return 0;
|
||||
|
||||
/* Get the response type, length, and sequence number. */
|
||||
memcpy(&genrep, c->in.queue, sizeof(genrep));
|
||||
|
||||
/* Compute 32-bit sequence number of this packet. */
|
||||
if((genrep.response_type & 0x7f) != KeymapNotify)
|
||||
{
|
||||
int lastread = c->in.request_read;
|
||||
c->in.request_read = (lastread & 0xffff0000) | genrep.sequence;
|
||||
if(c->in.request_read != lastread && !_xcb_queue_is_empty(c->in.current_reply))
|
||||
{
|
||||
_xcb_map_put(c->in.replies, lastread, c->in.current_reply);
|
||||
c->in.current_reply = _xcb_queue_new();
|
||||
}
|
||||
if(c->in.request_read < lastread)
|
||||
c->in.request_read += 0x10000;
|
||||
}
|
||||
|
||||
/* For reply packets, check that the entire packet is available. */
|
||||
if(genrep.response_type == 1)
|
||||
{
|
||||
pending_reply *pend = _xcb_list_peek_head(c->in.pending_replies);
|
||||
if(pend && pend->request == c->in.request_read)
|
||||
{
|
||||
switch(pend->workaround)
|
||||
{
|
||||
case WORKAROUND_NONE:
|
||||
break;
|
||||
case WORKAROUND_GLX_GET_FB_CONFIGS_BUG:
|
||||
{
|
||||
CARD32 *p = (CARD32 *) c->in.queue;
|
||||
genrep.length = p[2] * p[3] * 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
free(_xcb_queue_dequeue(c->in.pending_replies));
|
||||
}
|
||||
length += genrep.length * 4;
|
||||
}
|
||||
|
||||
buf = malloc(length);
|
||||
if(!buf)
|
||||
return 0;
|
||||
if(_xcb_in_read_block(c, buf, length) <= 0)
|
||||
{
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(buf[0] == 1) /* response is a reply */
|
||||
{
|
||||
XCBReplyData *reader = _xcb_list_find(c->in.readers, match_reply, &c->in.request_read);
|
||||
_xcb_queue_enqueue(c->in.current_reply, buf);
|
||||
if(reader)
|
||||
pthread_cond_signal(reader->data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(buf[0] == 0) /* response is an error */
|
||||
{
|
||||
XCBReplyData *reader = _xcb_list_find(c->in.readers, match_reply, &c->in.request_read);
|
||||
if(reader && reader->error)
|
||||
{
|
||||
*reader->error = (XCBGenericError *) buf;
|
||||
pthread_cond_signal(reader->data);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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... */
|
||||
}
|
||||
|
||||
/* Public interface */
|
||||
|
||||
void *XCBWaitForReply(XCBConnection *c, unsigned int request, XCBGenericError **e)
|
||||
|
@ -165,7 +249,7 @@ XCBGenericEvent *XCBPollForEvent(XCBConnection *c, int *error)
|
|||
if(error)
|
||||
*error = 0;
|
||||
/* FIXME: follow X meets Z architecture changes. */
|
||||
if(_xcb_in_read(c) >= 0)
|
||||
if(_xcb_in_read(c))
|
||||
ret = _xcb_queue_dequeue(c->in.events);
|
||||
else if(error)
|
||||
*error = -1;
|
||||
|
@ -241,98 +325,12 @@ int _xcb_in_expect_reply(XCBConnection *c, unsigned int request, enum workaround
|
|||
return 1;
|
||||
}
|
||||
|
||||
int _xcb_in_read_packet(XCBConnection *c)
|
||||
{
|
||||
XCBGenericRep genrep;
|
||||
int length = 32;
|
||||
unsigned char *buf;
|
||||
|
||||
/* Wait for there to be enough data for us to read a whole packet */
|
||||
if(c->in.queue_len < length)
|
||||
return 0;
|
||||
|
||||
/* Get the response type, length, and sequence number. */
|
||||
memcpy(&genrep, c->in.queue, sizeof(genrep));
|
||||
|
||||
/* Compute 32-bit sequence number of this packet. */
|
||||
if((genrep.response_type & 0x7f) != KeymapNotify)
|
||||
{
|
||||
int lastread = c->in.request_read;
|
||||
c->in.request_read = (lastread & 0xffff0000) | genrep.sequence;
|
||||
if(c->in.request_read != lastread && !_xcb_queue_is_empty(c->in.current_reply))
|
||||
{
|
||||
_xcb_map_put(c->in.replies, lastread, c->in.current_reply);
|
||||
c->in.current_reply = _xcb_queue_new();
|
||||
}
|
||||
if(c->in.request_read < lastread)
|
||||
c->in.request_read += 0x10000;
|
||||
}
|
||||
|
||||
/* For reply packets, check that the entire packet is available. */
|
||||
if(genrep.response_type == 1)
|
||||
{
|
||||
pending_reply *pend = _xcb_list_peek_head(c->in.pending_replies);
|
||||
if(pend && pend->request == c->in.request_read)
|
||||
{
|
||||
switch(pend->workaround)
|
||||
{
|
||||
case WORKAROUND_NONE:
|
||||
break;
|
||||
case WORKAROUND_GLX_GET_FB_CONFIGS_BUG:
|
||||
{
|
||||
CARD32 *p = (CARD32 *) c->in.queue;
|
||||
genrep.length = p[2] * p[3] * 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
free(_xcb_queue_dequeue(c->in.pending_replies));
|
||||
}
|
||||
length += genrep.length * 4;
|
||||
}
|
||||
|
||||
buf = malloc(length);
|
||||
if(!buf)
|
||||
return 0;
|
||||
if(_xcb_in_read_block(c, buf, length) <= 0)
|
||||
{
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(buf[0] == 1) /* response is a reply */
|
||||
{
|
||||
XCBReplyData *reader = _xcb_list_find(c->in.readers, match_reply, &c->in.request_read);
|
||||
_xcb_queue_enqueue(c->in.current_reply, buf);
|
||||
if(reader)
|
||||
pthread_cond_signal(reader->data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(buf[0] == 0) /* response is an error */
|
||||
{
|
||||
XCBReplyData *reader = _xcb_list_find(c->in.readers, match_reply, &c->in.request_read);
|
||||
if(reader && reader->error)
|
||||
{
|
||||
*reader->error = (XCBGenericError *) buf;
|
||||
pthread_cond_signal(reader->data);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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... */
|
||||
}
|
||||
|
||||
int _xcb_in_read(XCBConnection *c)
|
||||
{
|
||||
int n = _xcb_readn(c->fd, c->in.queue, sizeof(c->in.queue), &c->in.queue_len);
|
||||
if(n < 0 && errno == EAGAIN)
|
||||
n = 1;
|
||||
while(_xcb_in_read_packet(c) > 0)
|
||||
while(read_packet(c))
|
||||
/* empty */;
|
||||
return n;
|
||||
return (n > 0) || (n < 0 && errno == EAGAIN);
|
||||
}
|
||||
|
||||
int _xcb_in_read_block(XCBConnection *c, void *buf, int len)
|
||||
|
|
|
@ -199,8 +199,9 @@ int _xcb_out_write(XCBConnection *c)
|
|||
else
|
||||
n = _xcb_write(c->fd, &c->out.queue, &c->out.queue_len);
|
||||
|
||||
if(n < 0 && errno == EAGAIN)
|
||||
n = 1;
|
||||
/* XXX: should "nothing was written" be considered failure or
|
||||
* success for this function? it's not an I/O error, but... */
|
||||
n = (n > 0) || (n < 0 && errno == EAGAIN);
|
||||
|
||||
if(c->out.vec_len)
|
||||
{
|
||||
|
|
|
@ -138,7 +138,6 @@ void _xcb_in_destroy(_xcb_in *in);
|
|||
|
||||
int _xcb_in_expect_reply(XCBConnection *c, unsigned int request, enum workarounds workaround);
|
||||
|
||||
int _xcb_in_read_packet(XCBConnection *c);
|
||||
int _xcb_in_read(XCBConnection *c);
|
||||
int _xcb_in_read_block(XCBConnection *c, void *buf, int nread);
|
||||
|
||||
|
|
Loading…
Reference in New Issue