summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--src/xcb_conn.c36
-rw-r--r--src/xcb_in.c16
3 files changed, 52 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index 6fe3e57..46c4611 100644
--- a/configure.ac
+++ b/configure.ac
@@ -116,6 +116,8 @@ AC_PREREQ([2.59c], [], [AC_SUBST([htmldir], [m4_ifset([AC_PACKAGE_TARNAME],
XCB_CHECK_DOXYGEN()
+AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, 1, [poll() function is available])], )
+
XCB_EXTENSION(Composite, "yes")
XCB_EXTENSION(Damage, "yes")
XCB_EXTENSION(DPMS, "yes")
diff --git a/src/xcb_conn.c b/src/xcb_conn.c
index 5b097f7..251d62e 100644
--- a/src/xcb_conn.c
+++ b/src/xcb_conn.c
@@ -31,12 +31,16 @@
#include <unistd.h>
#include <stdlib.h>
#include <netinet/in.h>
-#include <sys/select.h>
#include <fcntl.h>
#include <errno.h>
#include "xcb.h"
#include "xcbint.h"
+#if USE_POLL
+#include <poll.h>
+#else
+#include <sys/select.h>
+#endif
typedef struct {
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 ret;
+#if USE_POLL
+ struct pollfd fd;
+#else
fd_set rfds, wfds;
+#endif
/* If the thing I should be doing is already being done, wait for it. */
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;
}
+#if USE_POLL
+ memset(&fd, 0, sizeof(fd));
+ fd.fd = c->fd;
+ fd.events = POLLIN;
+#else
FD_ZERO(&rfds);
FD_SET(c->fd, &rfds);
+#endif
++c->in.reading;
+#if USE_POLL
+ if(count)
+ {
+ fd.events |= POLLOUT;
+ ++c->out.writing;
+ }
+#else
FD_ZERO(&wfds);
if(count)
{
FD_SET(c->fd, &wfds);
++c->out.writing;
}
+#endif
pthread_mutex_unlock(&c->iolock);
do {
+#if USE_POLL
+ ret = poll(&fd, 1, -1);
+#else
ret = select(c->fd + 1, &rfds, &wfds, 0, 0);
+#endif
} while (ret == -1 && errno == EINTR);
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 USE_POLL
+ if((fd.revents & POLLIN) == POLLIN)
+#else
if(FD_ISSET(c->fd, &rfds))
+#endif
ret = ret && _xcb_in_read(c);
+#if USE_POLL
+ if((fd.revents & POLLOUT) == POLLOUT)
+#else
if(FD_ISSET(c->fd, &wfds))
+#endif
ret = ret && write_vec(c, vector, count);
}
diff --git a/src/xcb_in.c b/src/xcb_in.c
index 212dc9a..26ab358 100644
--- a/src/xcb_in.c
+++ b/src/xcb_in.c
@@ -30,12 +30,16 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
-#include <sys/select.h>
#include <errno.h>
#include "xcb.h"
#include "xcbext.h"
#include "xcbint.h"
+#if USE_POLL
+#include <poll.h>
+#else
+#include <sys/select.h>
+#endif
#define XCB_ERROR 0
#define XCB_REPLY 1
@@ -268,12 +272,22 @@ static int read_block(const int fd, void *buf, const ssize_t len)
done += ret;
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_ZERO(&fds);
FD_SET(fd, &fds);
do {
ret = select(fd + 1, &fds, 0, 0, 0);
} while (ret == -1 && errno == EINTR);
+#endif
}
if(ret <= 0)
return ret;