Replace events generic queue with hand-written typesafe version.
This commit is contained in:
parent
ff7b6c9124
commit
0f130b4d94
51
src/xcb_in.c
51
src/xcb_in.c
|
@ -36,6 +36,11 @@
|
||||||
#include "xcbext.h"
|
#include "xcbext.h"
|
||||||
#include "xcbint.h"
|
#include "xcbint.h"
|
||||||
|
|
||||||
|
struct event_list {
|
||||||
|
XCBGenericEvent *event;
|
||||||
|
struct event_list *next;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct pending_reply {
|
typedef struct pending_reply {
|
||||||
unsigned int request;
|
unsigned int request;
|
||||||
enum workarounds workaround;
|
enum workarounds workaround;
|
||||||
|
@ -68,8 +73,9 @@ static int read_packet(XCBConnection *c)
|
||||||
{
|
{
|
||||||
XCBGenericRep genrep;
|
XCBGenericRep genrep;
|
||||||
int length = 32;
|
int length = 32;
|
||||||
unsigned char *buf;
|
void *buf;
|
||||||
pending_reply *pend = 0;
|
pending_reply *pend = 0;
|
||||||
|
struct event_list *event;
|
||||||
|
|
||||||
/* Wait for there to be enough data for us to read a whole packet */
|
/* Wait for there to be enough data for us to read a whole packet */
|
||||||
if(c->in.queue_len < length)
|
if(c->in.queue_len < length)
|
||||||
|
@ -141,11 +147,34 @@ static int read_packet(XCBConnection *c)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* event, or unchecked error */
|
/* event, or unchecked error */
|
||||||
_xcb_queue_enqueue(c->in.events, buf);
|
event = malloc(sizeof(struct event_list));
|
||||||
|
if(!event)
|
||||||
|
{
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
event->event = buf;
|
||||||
|
event->next = 0;
|
||||||
|
*c->in.events_tail = event;
|
||||||
|
c->in.events_tail = &event->next;
|
||||||
pthread_cond_signal(&c->in.event_cond);
|
pthread_cond_signal(&c->in.event_cond);
|
||||||
return 1; /* I have something for you... */
|
return 1; /* I have something for you... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static XCBGenericEvent *get_event(XCBConnection *c)
|
||||||
|
{
|
||||||
|
struct event_list *cur = c->in.events;
|
||||||
|
XCBGenericEvent *ret;
|
||||||
|
if(!c->in.events)
|
||||||
|
return 0;
|
||||||
|
ret = cur->event;
|
||||||
|
c->in.events = cur->next;
|
||||||
|
if(!cur->next)
|
||||||
|
c->in.events_tail = &c->in.events;
|
||||||
|
free(cur);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int read_block(const int fd, void *buf, const size_t len)
|
static int read_block(const int fd, void *buf, const size_t len)
|
||||||
{
|
{
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
@ -238,8 +267,8 @@ XCBGenericEvent *XCBWaitForEvent(XCBConnection *c)
|
||||||
{
|
{
|
||||||
XCBGenericEvent *ret;
|
XCBGenericEvent *ret;
|
||||||
pthread_mutex_lock(&c->iolock);
|
pthread_mutex_lock(&c->iolock);
|
||||||
/* _xcb_list_remove_head returns 0 on empty list. */
|
/* get_event returns 0 on empty list. */
|
||||||
while(!(ret = _xcb_queue_dequeue(c->in.events)))
|
while(!(ret = get_event(c)))
|
||||||
if(!_xcb_conn_wait(c, /*should_write*/ 0, &c->in.event_cond))
|
if(!_xcb_conn_wait(c, /*should_write*/ 0, &c->in.event_cond))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -256,7 +285,7 @@ XCBGenericEvent *XCBPollForEvent(XCBConnection *c, int *error)
|
||||||
*error = 0;
|
*error = 0;
|
||||||
/* FIXME: follow X meets Z architecture changes. */
|
/* FIXME: follow X meets Z architecture changes. */
|
||||||
if(_xcb_in_read(c))
|
if(_xcb_in_read(c))
|
||||||
ret = _xcb_queue_dequeue(c->in.events);
|
ret = get_event(c);
|
||||||
else if(error)
|
else if(error)
|
||||||
*error = -1;
|
*error = -1;
|
||||||
else
|
else
|
||||||
|
@ -293,11 +322,11 @@ int _xcb_in_init(_xcb_in *in)
|
||||||
in->current_reply = _xcb_queue_new();
|
in->current_reply = _xcb_queue_new();
|
||||||
|
|
||||||
in->replies = _xcb_map_new();
|
in->replies = _xcb_map_new();
|
||||||
in->events = _xcb_queue_new();
|
|
||||||
in->readers = _xcb_list_new();
|
in->readers = _xcb_list_new();
|
||||||
if(!in->current_reply || !in->replies || !in->events || !in->readers)
|
if(!in->current_reply || !in->replies || !in->readers)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
in->events_tail = &in->events;
|
||||||
in->pending_replies_tail = &in->pending_replies;
|
in->pending_replies_tail = &in->pending_replies;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -308,8 +337,14 @@ void _xcb_in_destroy(_xcb_in *in)
|
||||||
pthread_cond_destroy(&in->event_cond);
|
pthread_cond_destroy(&in->event_cond);
|
||||||
_xcb_queue_delete(in->current_reply, free);
|
_xcb_queue_delete(in->current_reply, free);
|
||||||
_xcb_map_delete(in->replies, free);
|
_xcb_map_delete(in->replies, free);
|
||||||
_xcb_queue_delete(in->events, free);
|
|
||||||
_xcb_list_delete(in->readers, 0);
|
_xcb_list_delete(in->readers, 0);
|
||||||
|
while(in->events)
|
||||||
|
{
|
||||||
|
struct event_list *e = in->events;
|
||||||
|
in->events = e->next;
|
||||||
|
free(e->event);
|
||||||
|
free(e);
|
||||||
|
}
|
||||||
while(in->pending_replies)
|
while(in->pending_replies)
|
||||||
{
|
{
|
||||||
pending_reply *pend = in->pending_replies;
|
pending_reply *pend = in->pending_replies;
|
||||||
|
|
|
@ -109,7 +109,8 @@ typedef struct _xcb_in {
|
||||||
_xcb_queue *current_reply;
|
_xcb_queue *current_reply;
|
||||||
|
|
||||||
_xcb_map *replies;
|
_xcb_map *replies;
|
||||||
_xcb_queue *events;
|
struct event_list *events;
|
||||||
|
struct event_list **events_tail;
|
||||||
_xcb_list *readers;
|
_xcb_list *readers;
|
||||||
|
|
||||||
struct pending_reply *pending_replies;
|
struct pending_reply *pending_replies;
|
||||||
|
|
Loading…
Reference in New Issue