Browse Source

[core] map FDEVENT_* to OS system event frameworks

(avoid need to translate event flags between OS and lighttpd FDEVENT_*)
personal/stbuehler/ci-build
Glenn Strauss 3 years ago
parent
commit
fc914ae442
  1. 4
      src/fdevent.c
  2. 18
      src/fdevent.h
  3. 52
      src/fdevent_impl.h
  4. 50
      src/fdevent_linux_sysepoll.c
  5. 92
      src/fdevent_poll.c
  6. 37
      src/fdevent_solaris_devpoll.c
  7. 23
      src/fdevent_solaris_port.c

4
src/fdevent.c

@ -302,8 +302,10 @@ int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx) {
fdn->handler = handler;
fdn->fd = fd;
fdn->ctx = ctx;
fdn->handler_ctx = NULL;
fdn->events = 0;
#ifdef FDEVENT_USE_LIBEV
fdn->handler_ctx = NULL;
#endif
ev->fdarray[fd] = fdn;

18
src/fdevent.h

@ -12,13 +12,17 @@ typedef handler_t (*fdevent_handler)(struct server *srv, void *ctx, int revents)
/* these are the POLL* values from <bits/poll.h> (linux poll)
*/
#define FDEVENT_IN BV(0)
#define FDEVENT_PRI BV(1)
#define FDEVENT_OUT BV(2)
#define FDEVENT_ERR BV(3)
#define FDEVENT_HUP BV(4)
#define FDEVENT_NVAL BV(5)
#define FDEVENT_RDHUP BV(13)
#define FDEVENT_IN 0x0001
#define FDEVENT_PRI 0x0002
#define FDEVENT_OUT 0x0004
#define FDEVENT_ERR 0x0008
#define FDEVENT_HUP 0x0010
#define FDEVENT_NVAL 0x0020
#if defined(__sun) && defined(__SVR4) /* Solaris */
#define FDEVENT_RDHUP 0x4000
#else
#define FDEVENT_RDHUP 0x2000
#endif
#define FDEVENT_STREAM_REQUEST BV(0)
#define FDEVENT_STREAM_REQUEST_BUFMIN BV(1)

52
src/fdevent_impl.h

@ -63,9 +63,11 @@ typedef enum {
typedef struct _fdnode {
fdevent_handler handler;
void *ctx;
void *handler_ctx;
int fd;
int events;
#ifdef FDEVENT_USE_LIBEV
void *handler_ctx;
#endif
} fdnode;
/**
@ -83,17 +85,34 @@ typedef struct {
#endif
struct fdevents {
struct server *srv;
fdevent_handler_t type;
fdnode **fdarray;
fdnode *pendclose;
size_t maxfds;
int (*event_set)(struct fdevents *ev, int fde_ndx, int fd, int events);
int (*event_del)(struct fdevents *ev, int fde_ndx, int fd);
int (*poll)(struct fdevents *ev, int timeout_ms);
struct server *srv;
size_t maxfds;
#ifdef FDEVENT_USE_LINUX_EPOLL
int epoll_fd;
struct epoll_event *epoll_events;
#endif
#ifdef FDEVENT_USE_SOLARIS_DEVPOLL
int devpoll_fd;
struct pollfd *devpollfds;
#endif
#ifdef FDEVENT_USE_SOLARIS_PORT
int port_fd;
port_event_t *port_events;
#endif
#ifdef FDEVENT_USE_FREEBSD_KQUEUE
int kq_fd;
struct kevent *kq_results;
#endif
#ifdef FDEVENT_USE_LIBEV
struct ev_loop *libev_loop;
#endif
#ifdef FDEVENT_USE_POLL
struct pollfd *pollfds;
@ -113,29 +132,10 @@ struct fdevents {
int select_max_fd;
#endif
#ifdef FDEVENT_USE_SOLARIS_DEVPOLL
int devpoll_fd;
struct pollfd *devpollfds;
#endif
#ifdef FDEVENT_USE_SOLARIS_PORT
port_event_t *port_events;
#endif
#ifdef FDEVENT_USE_FREEBSD_KQUEUE
int kq_fd;
struct kevent *kq_results;
#endif
#ifdef FDEVENT_USE_SOLARIS_PORT
int port_fd;
#endif
#ifdef FDEVENT_USE_LIBEV
struct ev_loop *libev_loop;
#endif
int (*reset)(struct fdevents *ev);
void (*free)(struct fdevents *ev);
int (*event_set)(struct fdevents *ev, int fde_ndx, int fd, int events);
int (*event_del)(struct fdevents *ev, int fde_ndx, int fd);
int (*poll)(struct fdevents *ev, int timeout_ms);
fdevent_handler_t type;
};
int fdevent_select_init(struct fdevents *ev);

50
src/fdevent_linux_sysepoll.c

@ -26,16 +26,9 @@ static void fdevent_linux_sysepoll_free(fdevents *ev) {
}
static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) {
struct epoll_event ep;
if (fde_ndx < 0) return -1;
memset(&ep, 0, sizeof(ep));
ep.data.fd = fd;
ep.data.ptr = NULL;
if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, &ep)) {
if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, NULL)) {
log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
"epoll_ctl failed: ", strerror(errno), ", dying");
@ -44,23 +37,12 @@ static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) {
return 0;
}
return -1;
}
static int fdevent_linux_sysepoll_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
struct epoll_event ep;
int add = 0;
if (fde_ndx == -1) add = 1;
memset(&ep, 0, sizeof(ep));
ep.events = 0;
if (events & FDEVENT_IN) ep.events |= EPOLLIN;
if (events & FDEVENT_OUT) ep.events |= EPOLLOUT;
if (events & FDEVENT_RDHUP) ep.events |= EPOLLRDHUP;
int add = (-1 == fde_ndx);
/**
*
@ -70,9 +52,7 @@ static int fdevent_linux_sysepoll_event_set(fdevents *ev, int fde_ndx, int fd, i
*
*/
ep.events |= EPOLLERR | EPOLLHUP /* | EPOLLET */;
ep.data.ptr = NULL;
ep.events = events | EPOLLERR | EPOLLHUP /* | EPOLLET */;
ep.data.fd = fd;
if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &ep)) {
@ -87,27 +67,13 @@ static int fdevent_linux_sysepoll_event_set(fdevents *ev, int fde_ndx, int fd, i
return fd;
}
static int fdevent_linux_sysepoll_event_get_revent(const fdevents *ev, size_t ndx) {
int events = 0, e;
e = ev->epoll_events[ndx].events;
if (e & EPOLLIN) events |= FDEVENT_IN;
if (e & EPOLLOUT) events |= FDEVENT_OUT;
if (e & EPOLLERR) events |= FDEVENT_ERR;
if (e & EPOLLHUP) events |= FDEVENT_HUP;
if (e & EPOLLPRI) events |= FDEVENT_PRI;
if (e & EPOLLRDHUP) events |= FDEVENT_RDHUP;
return events;
}
static int fdevent_linux_sysepoll_poll(fdevents * const ev, int timeout_ms) {
int n = epoll_wait(ev->epoll_fd, ev->epoll_events, ev->maxfds, timeout_ms);
server * const srv = ev->srv;
for (int i = 0; i < n; ++i) {
int revents = ev->epoll_events[i].events;
fdnode * const fdn = ev->fdarray[ev->epoll_events[i].data.fd];
if (0 == ((uintptr_t)fdn & 0x3)) {
int revents = fdevent_linux_sysepoll_event_get_revent(ev, i);
(*fdn->handler)(srv, fdn->ctx, revents);
}
}
@ -116,6 +82,14 @@ static int fdevent_linux_sysepoll_poll(fdevents * const ev, int timeout_ms) {
int fdevent_linux_sysepoll_init(fdevents *ev) {
ev->type = FDEVENT_HANDLER_LINUX_SYSEPOLL;
force_assert(EPOLLIN == FDEVENT_IN);
force_assert(EPOLLPRI == FDEVENT_PRI);
force_assert(EPOLLOUT == FDEVENT_OUT);
force_assert(EPOLLERR == FDEVENT_ERR);
force_assert(EPOLLHUP == FDEVENT_HUP);
#if 0 != EPOLLRDHUP
force_assert(EPOLLRDHUP == FDEVENT_RDHUP);
#endif
#define SET(x) \
ev->x = fdevent_linux_sysepoll_##x;

92
src/fdevent_poll.c

@ -62,30 +62,12 @@ static int fdevent_poll_event_del(fdevents *ev, int fde_ndx, int fd) {
return -1;
}
#if 0
static int fdevent_poll_event_compress(fdevents *ev) {
size_t j;
if (ev->used == 0) return 0;
if (ev->unused.used != 0) return 0;
for (j = ev->used - 1; j + 1 > 0 && ev->pollfds[j].fd == -1; j--) ev->used--;
return 0;
}
#endif
static int fdevent_poll_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
int pevents = 0;
if (events & FDEVENT_IN) pevents |= POLLIN;
if (events & FDEVENT_OUT) pevents |= POLLOUT;
if (events & FDEVENT_RDHUP) pevents |= POLLRDHUP;
/* known index */
int k;
if (fde_ndx != -1) {
if (ev->pollfds[fde_ndx].fd == fd) {
ev->pollfds[fde_ndx].events = pevents;
ev->pollfds[fde_ndx].events = events;
return fde_ndx;
}
@ -95,12 +77,8 @@ static int fdevent_poll_event_set(fdevents *ev, int fde_ndx, int fd, int events)
}
if (ev->unused.used > 0) {
int k = ev->unused.ptr[--ev->unused.used];
ev->pollfds[k].fd = fd;
ev->pollfds[k].events = pevents;
k = ev->unused.ptr[--ev->unused.used];
return k;
} else {
if (ev->size == ev->used) {
ev->size += 16;
@ -108,47 +86,16 @@ static int fdevent_poll_event_set(fdevents *ev, int fde_ndx, int fd, int events)
force_assert(NULL != ev->pollfds);
}
ev->pollfds[ev->used].fd = fd;
ev->pollfds[ev->used].events = pevents;
return ev->used++;
}
}
static int fdevent_poll_event_get_revent(const fdevents *ev, size_t ndx) {
int r, poll_r;
if (ndx >= ev->used) {
log_error_write(ev->srv, __FILE__, __LINE__, "sii",
"dying because: event: ", (int) ndx, (int) ev->used);
SEGFAULT();
return 0;
k = ev->used++;
}
if (ev->pollfds[ndx].revents & POLLNVAL) {
/* should never happen */
SEGFAULT();
}
r = 0;
poll_r = ev->pollfds[ndx].revents;
/* map POLL* to FDEVEN_*; they are probably the same, but still. */
if (poll_r & POLLIN) r |= FDEVENT_IN;
if (poll_r & POLLOUT) r |= FDEVENT_OUT;
if (poll_r & POLLERR) r |= FDEVENT_ERR;
if (poll_r & POLLHUP) r |= FDEVENT_HUP;
if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
if (poll_r & POLLPRI) r |= FDEVENT_PRI;
if (poll_r & POLLRDHUP) r |= FDEVENT_RDHUP;
ev->pollfds[k].fd = fd;
ev->pollfds[k].events = events;
return r;
return k;
}
static int fdevent_poll_event_next_fdndx(const fdevents *ev, int ndx) {
static int fdevent_poll_next_ndx(const fdevents *ev, int ndx) {
for (size_t i = (size_t)(ndx+1); i < ev->used; ++i) {
if (ev->pollfds[i].revents) return i;
}
@ -156,18 +103,12 @@ static int fdevent_poll_event_next_fdndx(const fdevents *ev, int ndx) {
}
static int fdevent_poll_poll(fdevents *ev, int timeout_ms) {
#if 0
fdevent_poll_event_compress(ev);
#endif
int n = poll(ev->pollfds, ev->used, timeout_ms);
const int n = poll(ev->pollfds, ev->used, timeout_ms);
server * const srv = ev->srv;
for (int ndx = -1, i = 0; i < n; ++i) {
fdnode *fdn;
ndx = fdevent_poll_event_next_fdndx(ev, ndx);
if (-1 == ndx) break;
fdn = ev->fdarray[ev->pollfds[ndx].fd];
for (int ndx=-1,i=0; i<n && -1!=(ndx=fdevent_poll_next_ndx(ev,ndx)); ++i){
int revents = ev->pollfds[ndx].revents;
fdnode *fdn = ev->fdarray[ev->pollfds[ndx].fd];
if (0 == ((uintptr_t)fdn & 0x3)) {
int revents = fdevent_poll_event_get_revent(ev, ndx);
(*fdn->handler)(srv, fdn->ctx, revents);
}
}
@ -176,6 +117,15 @@ static int fdevent_poll_poll(fdevents *ev, int timeout_ms) {
int fdevent_poll_init(fdevents *ev) {
ev->type = FDEVENT_HANDLER_POLL;
force_assert(POLLIN == FDEVENT_IN);
force_assert(POLLPRI == FDEVENT_PRI);
force_assert(POLLOUT == FDEVENT_OUT);
force_assert(POLLERR == FDEVENT_ERR);
force_assert(POLLHUP == FDEVENT_HUP);
force_assert(POLLNVAL == FDEVENT_NVAL);
#if 0 != POLLRDHUP
force_assert(POLLRDHUP == FDEVENT_RDHUP);
#endif
#define SET(x) \
ev->x = fdevent_poll_##x;

37
src/fdevent_solaris_devpoll.c

@ -46,16 +46,10 @@ static int fdevent_solaris_devpoll_event_del(fdevents *ev, int fde_ndx, int fd)
static int fdevent_solaris_devpoll_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
struct pollfd pfd;
int add = 0;
int pevents = 0;
if (events & FDEVENT_IN) pevents |= POLLIN;
if (events & FDEVENT_OUT) pevents |= POLLOUT;
if (fde_ndx == -1) add = 1;
int add = (-1 == fde_ndx);
pfd.fd = fd;
pfd.events = pevents;
pfd.events = events;
pfd.revents = 0;
if (-1 == write(ev->devpoll_fd, &pfd, sizeof(pfd))) {
@ -68,24 +62,6 @@ static int fdevent_solaris_devpoll_event_set(fdevents *ev, int fde_ndx, int fd,
return fd;
}
static int fdevent_solaris_devpoll_event_get_revent(const fdevents *ev, size_t ndx) {
int r, poll_r;
r = 0;
poll_r = ev->devpollfds[ndx].revents;
/* map POLL* to FDEVEN_*; they are probably the same, but still. */
if (poll_r & POLLIN) r |= FDEVENT_IN;
if (poll_r & POLLOUT) r |= FDEVENT_OUT;
if (poll_r & POLLERR) r |= FDEVENT_ERR;
if (poll_r & POLLHUP) r |= FDEVENT_HUP;
if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
if (poll_r & POLLPRI) r |= FDEVENT_PRI;
return r;
}
static int fdevent_solaris_devpoll_poll(fdevents *ev, int timeout_ms) {
int n;
server * const srv = ev->srv;
@ -98,9 +74,9 @@ static int fdevent_solaris_devpoll_poll(fdevents *ev, int timeout_ms) {
n = ioctl(ev->devpoll_fd, DP_POLL, &dopoll);
for (int i = 0; i < n; ++i) {
int revents = ev->devpollfds[i].revents;
fdnode * const fdn = ev->fdarray[ev->devpollfds[i].fd];
if (0 == ((uintptr_t)fdn & 0x3)) {
int revents = fdevent_solaris_devpoll_event_get_revent(ev, i);
(*fdn->handler)(srv, fdn->ctx, revents);
}
}
@ -122,6 +98,13 @@ int fdevent_solaris_devpoll_reset(fdevents *ev) {
}
int fdevent_solaris_devpoll_init(fdevents *ev) {
ev->type = FDEVENT_HANDLER_SOLARIS_DEVPOLL;
force_assert(POLLIN == FDEVENT_IN);
force_assert(POLLPRI == FDEVENT_PRI);
force_assert(POLLOUT == FDEVENT_OUT);
force_assert(POLLERR == FDEVENT_ERR);
force_assert(POLLHUP == FDEVENT_HUP);
force_assert(POLLNVAL == FDEVENT_NVAL);
force_assert(POLLRDHUP == FDEVENT_RDHUP);
#define SET(x) \
ev->x = fdevent_solaris_devpoll_##x;

23
src/fdevent_solaris_port.c

@ -58,20 +58,6 @@ static int fdevent_solaris_port_event_set(fdevents *ev, int fde_ndx, int fd, int
return fd;
}
static int fdevent_solaris_port_event_get_revent(const fdevents *ev, size_t ndx) {
int events = 0, e;
e = ev->port_events[ndx].portev_events;
if (e & POLLIN) events |= FDEVENT_IN;
if (e & POLLOUT) events |= FDEVENT_OUT;
if (e & POLLERR) events |= FDEVENT_ERR;
if (e & POLLHUP) events |= FDEVENT_HUP;
if (e & POLLPRI) events |= FDEVENT_PRI;
if (e & POLLNVAL) events |= FDEVENT_NVAL;
return e;
}
static void fdevent_solaris_port_free(fdevents *ev) {
close(ev->port_fd);
free(ev->port_events);
@ -119,9 +105,9 @@ static int fdevent_solaris_port_poll(fdevents *ev, int timeout_ms) {
}
for (i = 0; i < available_events; ++i) {
int revents = ev->port_events[i].portev_events;
fdnode * const fdn = ev->fdarray[ev->port_events[i].portev_object];
if (0 == ((uintptr_t)fdn & 0x3)) {
int revents = fdevent_solaris_port_event_get_revent(ev, i);
(*fdn->handler)(ev->srv, fdn->ctx, revents);
}
}
@ -130,6 +116,13 @@ static int fdevent_solaris_port_poll(fdevents *ev, int timeout_ms) {
int fdevent_solaris_port_init(fdevents *ev) {
ev->type = FDEVENT_HANDLER_SOLARIS_PORT;
force_assert(POLLIN == FDEVENT_IN);
force_assert(POLLPRI == FDEVENT_PRI);
force_assert(POLLOUT == FDEVENT_OUT);
force_assert(POLLERR == FDEVENT_ERR);
force_assert(POLLHUP == FDEVENT_HUP);
force_assert(POLLNVAL == FDEVENT_NVAL);
force_assert(POLLRDHUP == FDEVENT_RDHUP);
#define SET(x) \
ev->x = fdevent_solaris_port_##x;

Loading…
Cancel
Save