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:
Jamey Sharp 2006-02-23 12:15:09 -08:00
parent 5b1d39e27b
commit 6149c7a6b5
4 changed files with 92 additions and 94 deletions

View File

@ -208,10 +208,10 @@ int _xcb_conn_wait(XCBConnection *c, const int should_write, pthread_cond_t *con
if(ret) if(ret)
{ {
if(FD_ISSET(c->fd, &rfds)) 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)) if(FD_ISSET(c->fd, &wfds))
ret = ret && _xcb_out_write(c) > 0; ret = ret && _xcb_out_write(c);
} }
if(should_write) if(should_write)

View File

@ -68,6 +68,90 @@ static void wake_up_next_reader(XCBConnection *c)
assert(pthreadret == 0); 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 */ /* Public interface */
void *XCBWaitForReply(XCBConnection *c, unsigned int request, XCBGenericError **e) void *XCBWaitForReply(XCBConnection *c, unsigned int request, XCBGenericError **e)
@ -165,7 +249,7 @@ XCBGenericEvent *XCBPollForEvent(XCBConnection *c, int *error)
if(error) if(error)
*error = 0; *error = 0;
/* FIXME: follow X meets Z architecture changes. */ /* 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); ret = _xcb_queue_dequeue(c->in.events);
else if(error) else if(error)
*error = -1; *error = -1;
@ -241,98 +325,12 @@ int _xcb_in_expect_reply(XCBConnection *c, unsigned int request, enum workaround
return 1; 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 _xcb_in_read(XCBConnection *c)
{ {
int n = _xcb_readn(c->fd, c->in.queue, sizeof(c->in.queue), &c->in.queue_len); int n = _xcb_readn(c->fd, c->in.queue, sizeof(c->in.queue), &c->in.queue_len);
if(n < 0 && errno == EAGAIN) while(read_packet(c))
n = 1;
while(_xcb_in_read_packet(c) > 0)
/* empty */; /* empty */;
return n; return (n > 0) || (n < 0 && errno == EAGAIN);
} }
int _xcb_in_read_block(XCBConnection *c, void *buf, int len) int _xcb_in_read_block(XCBConnection *c, void *buf, int len)

View File

@ -199,8 +199,9 @@ int _xcb_out_write(XCBConnection *c)
else else
n = _xcb_write(c->fd, &c->out.queue, &c->out.queue_len); n = _xcb_write(c->fd, &c->out.queue, &c->out.queue_len);
if(n < 0 && errno == EAGAIN) /* XXX: should "nothing was written" be considered failure or
n = 1; * success for this function? it's not an I/O error, but... */
n = (n > 0) || (n < 0 && errno == EAGAIN);
if(c->out.vec_len) if(c->out.vec_len)
{ {

View File

@ -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_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(XCBConnection *c);
int _xcb_in_read_block(XCBConnection *c, void *buf, int nread); int _xcb_in_read_block(XCBConnection *c, void *buf, int nread);