Merge branch 'wait_for_special_event_with_timeout' into 'master'
WIP: xcb_wait_for_special_event_with_timeout() See merge request xorg/lib/libxcb!9
This commit is contained in:
commit
5c2c26695e
|
@ -361,6 +361,13 @@ xcb_generic_event_t *xcb_poll_for_special_event(xcb_connection_t *c,
|
||||||
*/
|
*/
|
||||||
xcb_generic_event_t *xcb_wait_for_special_event(xcb_connection_t *c,
|
xcb_generic_event_t *xcb_wait_for_special_event(xcb_connection_t *c,
|
||||||
xcb_special_event_t *se);
|
xcb_special_event_t *se);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the next event from a special queue, blocking until one arrives
|
||||||
|
*/
|
||||||
|
xcb_generic_event_t *xcb_wait_for_special_event_with_timeout(xcb_connection_t *c,
|
||||||
|
xcb_special_event_t *se,
|
||||||
|
unsigned int millisecs_timeout);
|
||||||
/**
|
/**
|
||||||
* @typedef typedef struct xcb_extension_t xcb_extension_t
|
* @typedef typedef struct xcb_extension_t xcb_extension_t
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <sys/time.h> /* I bet this does not work on Windows... */
|
||||||
|
|
||||||
#include "xcb.h"
|
#include "xcb.h"
|
||||||
#include "xcbint.h"
|
#include "xcbint.h"
|
||||||
|
@ -464,6 +465,11 @@ xcb_connection_t *_xcb_conn_ret_error(int err)
|
||||||
}
|
}
|
||||||
|
|
||||||
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count)
|
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count)
|
||||||
|
{
|
||||||
|
return _xcb_conn_timedwait(c, cond, vector, count, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _xcb_conn_timedwait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count, struct timeval *now, struct timeval *deadline)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
#if USE_POLL
|
#if USE_POLL
|
||||||
|
@ -475,7 +481,13 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
|
||||||
/* If the thing I should be doing is already being done, wait for it. */
|
/* If the thing I should be doing is already being done, wait for it. */
|
||||||
if(count ? c->out.writing : c->in.reading)
|
if(count ? c->out.writing : c->in.reading)
|
||||||
{
|
{
|
||||||
pthread_cond_wait(cond, &c->iolock);
|
if(deadline) {
|
||||||
|
struct timespec spec;
|
||||||
|
spec.tv_sec = deadline->tv_sec;
|
||||||
|
spec.tv_nsec = deadline->tv_usec * 100;
|
||||||
|
pthread_cond_timedwait(cond, &c->iolock, &spec);
|
||||||
|
} else
|
||||||
|
pthread_cond_wait(cond, &c->iolock);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,7 +519,13 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
|
||||||
pthread_mutex_unlock(&c->iolock);
|
pthread_mutex_unlock(&c->iolock);
|
||||||
do {
|
do {
|
||||||
#if USE_POLL
|
#if USE_POLL
|
||||||
ret = poll(&fd, 1, -1);
|
int timeout = -1;
|
||||||
|
if(deadline && now) {
|
||||||
|
struct timeval diff;
|
||||||
|
timersub(deadline, now, &diff);
|
||||||
|
timeout = now->tv_sec * 1000 + now->tv_usec / 1000;
|
||||||
|
}
|
||||||
|
ret = poll(&fd, 1, timeout);
|
||||||
/* If poll() returns an event we didn't expect, such as POLLNVAL, treat
|
/* If poll() returns an event we didn't expect, such as POLLNVAL, treat
|
||||||
* it as if it failed. */
|
* it as if it failed. */
|
||||||
if(ret >= 0 && (fd.revents & ~fd.events))
|
if(ret >= 0 && (fd.revents & ~fd.events))
|
||||||
|
@ -516,7 +534,13 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
ret = select(c->fd + 1, &rfds, &wfds, 0, 0);
|
struct timeval diff;
|
||||||
|
struct timeval *timeout = NULL;
|
||||||
|
if(deadline && now) {
|
||||||
|
timersub(deadline, now, &diff);
|
||||||
|
timeout = &diff;
|
||||||
|
}
|
||||||
|
ret = select(c->fd + 1, &rfds, &wfds, 0, timeout);
|
||||||
#endif
|
#endif
|
||||||
} while (ret == -1 && errno == EINTR);
|
} while (ret == -1 && errno == EINTR);
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
|
|
37
src/xcb_in.c
37
src/xcb_in.c
|
@ -34,6 +34,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/time.h> /* I bet this does not work on Windows... */
|
||||||
|
|
||||||
#if USE_POLL
|
#if USE_POLL
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
@ -789,6 +790,42 @@ xcb_generic_event_t *xcb_poll_for_special_event(xcb_connection_t *c,
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xcb_generic_event_t *xcb_wait_for_special_event_with_timeout(xcb_connection_t *c,
|
||||||
|
xcb_special_event_t *se,
|
||||||
|
unsigned int millisecs_timeout)
|
||||||
|
{
|
||||||
|
struct timeval now, deadline, timeout;
|
||||||
|
special_list special;
|
||||||
|
xcb_generic_event_t *event;
|
||||||
|
|
||||||
|
if(c->has_error)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
timeout.tv_sec = millisecs_timeout / 1000;
|
||||||
|
timeout.tv_usec = (millisecs_timeout % 1000) * 1000;
|
||||||
|
gettimeofday(&now, NULL); // TODO: Check for errors?
|
||||||
|
timeradd(&now, &timeout, &deadline);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&c->iolock);
|
||||||
|
|
||||||
|
insert_special(&c->in.special_waiters, &special, se);
|
||||||
|
|
||||||
|
/* get_special_event returns 0 on empty list. */
|
||||||
|
while(!(event = get_special_event(c, se))) {
|
||||||
|
if(timercmp(&deadline, &now, <))
|
||||||
|
break;
|
||||||
|
if(!_xcb_conn_timedwait(c, &se->special_event_cond, 0, 0, &now, &deadline))
|
||||||
|
break;
|
||||||
|
gettimeofday(&now, NULL); // TODO: Check for errors?
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_special(&c->in.special_waiters, &special);
|
||||||
|
|
||||||
|
_xcb_in_wake_up_next_reader(c);
|
||||||
|
pthread_mutex_unlock(&c->iolock);
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
xcb_generic_event_t *xcb_wait_for_special_event(xcb_connection_t *c,
|
xcb_generic_event_t *xcb_wait_for_special_event(xcb_connection_t *c,
|
||||||
xcb_special_event_t *se)
|
xcb_special_event_t *se)
|
||||||
{
|
{
|
||||||
|
|
|
@ -229,6 +229,7 @@ XCB_CONST_FUNCTION
|
||||||
xcb_connection_t *_xcb_conn_ret_error(int err);
|
xcb_connection_t *_xcb_conn_ret_error(int err);
|
||||||
|
|
||||||
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count);
|
int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count);
|
||||||
|
int _xcb_conn_timedwait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count, struct timeval *now, struct timeval *deadline);
|
||||||
|
|
||||||
|
|
||||||
/* xcb_auth.c */
|
/* xcb_auth.c */
|
||||||
|
|
Loading…
Reference in New Issue