version 1.1, 2013/10/14 10:32:47
|
version 1.1.1.3, 2016/11/02 10:35:00
|
Line 1
|
Line 1
|
|
#include "first.h" |
|
|
#include "base.h" |
#include "base.h" |
#include "log.h" |
#include "log.h" |
|
|
Line 16 fdevents *fdevent_init(server *srv, size_t maxfds, fde
|
Line 18 fdevents *fdevent_init(server *srv, size_t maxfds, fde
|
fdevents *ev; |
fdevents *ev; |
|
|
ev = calloc(1, sizeof(*ev)); |
ev = calloc(1, sizeof(*ev)); |
|
force_assert(NULL != ev); |
ev->srv = srv; |
ev->srv = srv; |
ev->fdarray = calloc(maxfds, sizeof(*ev->fdarray)); |
ev->fdarray = calloc(maxfds, sizeof(*ev->fdarray)); |
|
force_assert(NULL != ev->fdarray); |
ev->maxfds = maxfds; |
ev->maxfds = maxfds; |
|
|
switch(type) { |
switch(type) { |
case FDEVENT_HANDLER_POLL: |
case FDEVENT_HANDLER_POLL: |
if (0 != fdevent_poll_init(ev)) { |
if (0 != fdevent_poll_init(ev)) { |
log_error_write(ev->srv, __FILE__, __LINE__, "S", | log_error_write(srv, __FILE__, __LINE__, "S", |
"event-handler poll failed"); |
"event-handler poll failed"); |
| goto error; |
return NULL; | |
} |
} |
return ev; |
return ev; |
case FDEVENT_HANDLER_SELECT: |
case FDEVENT_HANDLER_SELECT: |
if (0 != fdevent_select_init(ev)) { |
if (0 != fdevent_select_init(ev)) { |
log_error_write(ev->srv, __FILE__, __LINE__, "S", | log_error_write(srv, __FILE__, __LINE__, "S", |
"event-handler select failed"); |
"event-handler select failed"); |
return NULL; | goto error; |
} |
} |
return ev; |
return ev; |
case FDEVENT_HANDLER_LINUX_SYSEPOLL: |
case FDEVENT_HANDLER_LINUX_SYSEPOLL: |
if (0 != fdevent_linux_sysepoll_init(ev)) { |
if (0 != fdevent_linux_sysepoll_init(ev)) { |
log_error_write(ev->srv, __FILE__, __LINE__, "S", | log_error_write(srv, __FILE__, __LINE__, "S", |
"event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\""); |
"event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\""); |
return NULL; | goto error; |
} |
} |
return ev; |
return ev; |
case FDEVENT_HANDLER_SOLARIS_DEVPOLL: |
case FDEVENT_HANDLER_SOLARIS_DEVPOLL: |
if (0 != fdevent_solaris_devpoll_init(ev)) { |
if (0 != fdevent_solaris_devpoll_init(ev)) { |
log_error_write(ev->srv, __FILE__, __LINE__, "S", | log_error_write(srv, __FILE__, __LINE__, "S", |
"event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\""); |
"event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\""); |
return NULL; | goto error; |
} |
} |
return ev; |
return ev; |
case FDEVENT_HANDLER_SOLARIS_PORT: |
case FDEVENT_HANDLER_SOLARIS_PORT: |
if (0 != fdevent_solaris_port_init(ev)) { |
if (0 != fdevent_solaris_port_init(ev)) { |
log_error_write(ev->srv, __FILE__, __LINE__, "S", | log_error_write(srv, __FILE__, __LINE__, "S", |
"event-handler solaris-eventports failed, try to set server.event-handler = \"poll\" or \"select\""); |
"event-handler solaris-eventports failed, try to set server.event-handler = \"poll\" or \"select\""); |
return NULL; | goto error; |
} |
} |
return ev; |
return ev; |
case FDEVENT_HANDLER_FREEBSD_KQUEUE: |
case FDEVENT_HANDLER_FREEBSD_KQUEUE: |
if (0 != fdevent_freebsd_kqueue_init(ev)) { |
if (0 != fdevent_freebsd_kqueue_init(ev)) { |
log_error_write(ev->srv, __FILE__, __LINE__, "S", | log_error_write(srv, __FILE__, __LINE__, "S", |
"event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\""); |
"event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\""); |
return NULL; | goto error; |
} |
} |
return ev; |
return ev; |
case FDEVENT_HANDLER_LIBEV: |
case FDEVENT_HANDLER_LIBEV: |
if (0 != fdevent_libev_init(ev)) { |
if (0 != fdevent_libev_init(ev)) { |
log_error_write(ev->srv, __FILE__, __LINE__, "S", | log_error_write(srv, __FILE__, __LINE__, "S", |
"event-handler libev failed, try to set server.event-handler = \"poll\" or \"select\""); |
"event-handler libev failed, try to set server.event-handler = \"poll\" or \"select\""); |
return NULL; | goto error; |
} |
} |
return ev; |
return ev; |
case FDEVENT_HANDLER_UNSET: |
case FDEVENT_HANDLER_UNSET: |
break; |
break; |
} |
} |
|
|
log_error_write(ev->srv, __FILE__, __LINE__, "S", | error: |
| free(ev->fdarray); |
| free(ev); |
| |
| log_error_write(srv, __FILE__, __LINE__, "S", |
"event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\""); |
"event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\""); |
return NULL; |
return NULL; |
} |
} |
Line 104 static fdnode *fdnode_init(void) {
|
Line 111 static fdnode *fdnode_init(void) {
|
fdnode *fdn; |
fdnode *fdn; |
|
|
fdn = calloc(1, sizeof(*fdn)); |
fdn = calloc(1, sizeof(*fdn)); |
|
force_assert(NULL != fdn); |
fdn->fd = -1; |
fdn->fd = -1; |
return fdn; |
return fdn; |
} |
} |
Line 133 int fdevent_unregister(fdevents *ev, int fd) {
|
Line 141 int fdevent_unregister(fdevents *ev, int fd) {
|
if (!ev) return 0; |
if (!ev) return 0; |
fdn = ev->fdarray[fd]; |
fdn = ev->fdarray[fd]; |
|
|
assert(fdn->events == 0); |
|
|
|
fdnode_free(fdn); |
fdnode_free(fdn); |
|
|
ev->fdarray[fd] = NULL; |
ev->fdarray[fd] = NULL; |
Line 142 int fdevent_unregister(fdevents *ev, int fd) {
|
Line 148 int fdevent_unregister(fdevents *ev, int fd) {
|
return 0; |
return 0; |
} |
} |
|
|
int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd) { | void fdevent_event_del(fdevents *ev, int *fde_ndx, int fd) { |
int fde = fde_ndx ? *fde_ndx : -1; | if (-1 == fd) return; |
| if (NULL == ev->fdarray[fd]) return; |
|
|
if (NULL == ev->fdarray[fd]) return 0; | if (ev->event_del) *fde_ndx = ev->event_del(ev, *fde_ndx, fd); |
| |
if (ev->event_del) fde = ev->event_del(ev, fde, fd); | |
ev->fdarray[fd]->events = 0; |
ev->fdarray[fd]->events = 0; |
|
} |
|
|
if (fde_ndx) *fde_ndx = fde; | void fdevent_event_set(fdevents *ev, int *fde_ndx, int fd, int events) { |
| if (-1 == fd) return; |
|
|
return 0; | /*(Note: skips registering with kernel if initial events is 0, |
| * so caller should pass non-zero events for initial registration. |
| * If never registered due to never being called with non-zero events, |
| * then FDEVENT_HUP or FDEVENT_ERR will never be returned.) */ |
| if (ev->fdarray[fd]->events == events) return;/*(no change; nothing to do)*/ |
| |
| if (ev->event_set) *fde_ndx = ev->event_set(ev, *fde_ndx, fd, events); |
| ev->fdarray[fd]->events = events; |
} |
} |
|
|
int fdevent_event_set(fdevents *ev, int *fde_ndx, int fd, int events) { | void fdevent_event_add(fdevents *ev, int *fde_ndx, int fd, int event) { |
int fde = fde_ndx ? *fde_ndx : -1; | int events; |
| if (-1 == fd) return; |
|
|
if (ev->event_set) fde = ev->event_set(ev, fde, fd, events); | events = ev->fdarray[fd]->events; |
| if ((events & event) || 0 == event) return; /*(no change; nothing to do)*/ |
| |
| events |= event; |
| if (ev->event_set) *fde_ndx = ev->event_set(ev, *fde_ndx, fd, events); |
ev->fdarray[fd]->events = events; |
ev->fdarray[fd]->events = events; |
|
} |
|
|
if (fde_ndx) *fde_ndx = fde; | void fdevent_event_clr(fdevents *ev, int *fde_ndx, int fd, int event) { |
| int events; |
| if (-1 == fd) return; |
|
|
return 0; | events = ev->fdarray[fd]->events; |
| if (!(events & event)) return; /*(no change; nothing to do)*/ |
| |
| events &= ~event; |
| if (ev->event_set) *fde_ndx = ev->event_set(ev, *fde_ndx, fd, events); |
| ev->fdarray[fd]->events = events; |
} |
} |
|
|
int fdevent_poll(fdevents *ev, int timeout_ms) { |
int fdevent_poll(fdevents *ev, int timeout_ms) { |
Line 197 void * fdevent_get_context(fdevents *ev, int fd) {
|
Line 224 void * fdevent_get_context(fdevents *ev, int fd) {
|
return ev->fdarray[fd]->ctx; |
return ev->fdarray[fd]->ctx; |
} |
} |
|
|
int fdevent_fcntl_set(fdevents *ev, int fd) { | void fd_close_on_exec(int fd) { |
#ifdef FD_CLOEXEC |
#ifdef FD_CLOEXEC |
/* close fd on exec (cgi) */ | if (fd < 0) return; |
fcntl(fd, F_SETFD, FD_CLOEXEC); | force_assert(-1 != fcntl(fd, F_SETFD, FD_CLOEXEC)); |
| #else |
| UNUSED(fd); |
#endif |
#endif |
|
} |
|
|
|
int fdevent_fcntl_set(fdevents *ev, int fd) { |
|
fd_close_on_exec(fd); |
if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd); |
if ((ev) && (ev->fcntl_set)) return ev->fcntl_set(ev, fd); |
#ifdef O_NONBLOCK |
#ifdef O_NONBLOCK |
return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR); |
return fcntl(fd, F_SETFL, O_NONBLOCK | O_RDWR); |