blob: 4dcb7549a6a0a57204a4d4c1734cd2518ec2f4b6 [file] [log] [blame]
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <assert.h>
#include "fdevent.h"
#include "settings.h"
#include "buffer.h"
#ifdef USE_SELECT
static int fdevent_select_reset(fdevents *ev) {
FD_ZERO(&(ev->select_set_read));
FD_ZERO(&(ev->select_set_write));
FD_ZERO(&(ev->select_set_error));
ev->select_max_fd = -1;
return 0;
}
static int fdevent_select_event_del(fdevents *ev, int fde_ndx, int fd) {
if (fde_ndx < 0) return -1;
FD_CLR(fd, &(ev->select_set_read));
FD_CLR(fd, &(ev->select_set_write));
FD_CLR(fd, &(ev->select_set_error));
return -1;
}
static int fdevent_select_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
UNUSED(fde_ndx);
/* we should be protected by max-fds, but you never know */
assert(fd < FD_SETSIZE);
if (events & FDEVENT_IN) {
FD_SET(fd, &(ev->select_set_read));
FD_CLR(fd, &(ev->select_set_write));
}
if (events & FDEVENT_OUT) {
FD_CLR(fd, &(ev->select_set_read));
FD_SET(fd, &(ev->select_set_write));
}
FD_SET(fd, &(ev->select_set_error));
if (fd > ev->select_max_fd) ev->select_max_fd = fd;
return fd;
}
static int fdevent_select_poll(fdevents *ev, int timeout_ms) {
struct timeval tv;
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = (timeout_ms % 1000) * 1000;
ev->select_read = ev->select_set_read;
ev->select_write = ev->select_set_write;
ev->select_error = ev->select_set_error;
return select(ev->select_max_fd + 1, &(ev->select_read), &(ev->select_write), &(ev->select_error), &tv);
}
static int fdevent_select_event_get_revent(fdevents *ev, size_t ndx) {
int revents = 0;
if (FD_ISSET(ndx, &(ev->select_read))) {
revents |= FDEVENT_IN;
}
if (FD_ISSET(ndx, &(ev->select_write))) {
revents |= FDEVENT_OUT;
}
if (FD_ISSET(ndx, &(ev->select_error))) {
revents |= FDEVENT_ERR;
}
return revents;
}
static int fdevent_select_event_get_fd(fdevents *ev, size_t ndx) {
UNUSED(ev);
return ndx;
}
static int fdevent_select_event_next_fdndx(fdevents *ev, int ndx) {
int i;
i = (ndx < 0) ? 0 : ndx + 1;
for (; i < ev->select_max_fd + 1; i++) {
if (FD_ISSET(i, &(ev->select_read))) break;
if (FD_ISSET(i, &(ev->select_write))) break;
if (FD_ISSET(i, &(ev->select_error))) break;
}
return i;
}
int fdevent_select_init(fdevents *ev) {
ev->type = FDEVENT_HANDLER_SELECT;
#define SET(x) \
ev->x = fdevent_select_##x;
SET(reset);
SET(poll);
SET(event_del);
SET(event_add);
SET(event_next_fdndx);
SET(event_get_fd);
SET(event_get_revent);
return 0;
}
#else
int fdevent_select_init(fdevents *ev) {
UNUSED(ev);
return -1;
}
#endif