use poll() instead of select() when available

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Michael Ost 2009-03-30 11:09:32 +02:00 committed by Julien Danjou
parent beccb0be15
commit f916062edf
3 changed files with 52 additions and 2 deletions

View File

@ -116,6 +116,8 @@ AC_PREREQ([2.59c], [], [AC_SUBST([htmldir], [m4_ifset([AC_PACKAGE_TARNAME],
XCB_CHECK_DOXYGEN() XCB_CHECK_DOXYGEN()
AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, 1, [poll() function is available])], )
XCB_EXTENSION(Composite, "yes") XCB_EXTENSION(Composite, "yes")
XCB_EXTENSION(Damage, "yes") XCB_EXTENSION(Damage, "yes")
XCB_EXTENSION(DPMS, "yes") XCB_EXTENSION(DPMS, "yes")

View File

@ -31,12 +31,16 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/select.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include "xcb.h" #include "xcb.h"
#include "xcbint.h" #include "xcbint.h"
#if USE_POLL
#include <poll.h>
#else
#include <sys/select.h>
#endif
typedef struct { typedef struct {
uint8_t status; uint8_t status;
@ -258,7 +262,11 @@ void _xcb_conn_shutdown(xcb_connection_t *c)
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 ret; int ret;
#if USE_POLL
struct pollfd fd;
#else
fd_set rfds, wfds; fd_set rfds, wfds;
#endif
/* 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)
@ -267,20 +275,38 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
return 1; return 1;
} }
#if USE_POLL
memset(&fd, 0, sizeof(fd));
fd.fd = c->fd;
fd.events = POLLIN;
#else
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(c->fd, &rfds); FD_SET(c->fd, &rfds);
#endif
++c->in.reading; ++c->in.reading;
#if USE_POLL
if(count)
{
fd.events |= POLLOUT;
++c->out.writing;
}
#else
FD_ZERO(&wfds); FD_ZERO(&wfds);
if(count) if(count)
{ {
FD_SET(c->fd, &wfds); FD_SET(c->fd, &wfds);
++c->out.writing; ++c->out.writing;
} }
#endif
pthread_mutex_unlock(&c->iolock); pthread_mutex_unlock(&c->iolock);
do { do {
#if USE_POLL
ret = poll(&fd, 1, -1);
#else
ret = select(c->fd + 1, &rfds, &wfds, 0, 0); ret = select(c->fd + 1, &rfds, &wfds, 0, 0);
#endif
} while (ret == -1 && errno == EINTR); } while (ret == -1 && errno == EINTR);
if (ret < 0) if (ret < 0)
{ {
@ -291,10 +317,18 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
if(ret) if(ret)
{ {
#if USE_POLL
if((fd.revents & POLLIN) == POLLIN)
#else
if(FD_ISSET(c->fd, &rfds)) if(FD_ISSET(c->fd, &rfds))
#endif
ret = ret && _xcb_in_read(c); ret = ret && _xcb_in_read(c);
#if USE_POLL
if((fd.revents & POLLOUT) == POLLOUT)
#else
if(FD_ISSET(c->fd, &wfds)) if(FD_ISSET(c->fd, &wfds))
#endif
ret = ret && write_vec(c, vector, count); ret = ret && write_vec(c, vector, count);
} }

View File

@ -30,12 +30,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <sys/select.h>
#include <errno.h> #include <errno.h>
#include "xcb.h" #include "xcb.h"
#include "xcbext.h" #include "xcbext.h"
#include "xcbint.h" #include "xcbint.h"
#if USE_POLL
#include <poll.h>
#else
#include <sys/select.h>
#endif
#define XCB_ERROR 0 #define XCB_ERROR 0
#define XCB_REPLY 1 #define XCB_REPLY 1
@ -268,12 +272,22 @@ static int read_block(const int fd, void *buf, const ssize_t len)
done += ret; done += ret;
if(ret < 0 && errno == EAGAIN) if(ret < 0 && errno == EAGAIN)
{ {
#if USE_POLL
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN;
pfd.revents = 0;
do {
ret = poll(&pfd, 1, -1);
} while (ret == -1 && errno == EINTR);
#else
fd_set fds; fd_set fds;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(fd, &fds); FD_SET(fd, &fds);
do { do {
ret = select(fd + 1, &fds, 0, 0, 0); ret = select(fd + 1, &fds, 0, 0, 0);
} while (ret == -1 && errno == EINTR); } while (ret == -1 && errno == EINTR);
#endif
} }
if(ret <= 0) if(ret <= 0)
return ret; return ret;