[core] fdevent_impl.c separate from fdevent.c
parent
b7a8fd468f
commit
ec52917755
|
@ -762,10 +762,6 @@ set(COMMON_SRC
|
|||
http_chunk.c fdevent.c gw_backend.c
|
||||
stat_cache.c plugin.c http_etag.c array.c
|
||||
algo_md5.c algo_sha1.c algo_splaytree.c
|
||||
fdevent_select.c fdevent_libev.c
|
||||
fdevent_poll.c fdevent_linux_sysepoll.c
|
||||
fdevent_solaris_devpoll.c fdevent_solaris_port.c
|
||||
fdevent_freebsd_kqueue.c
|
||||
configfile-glue.c
|
||||
http-header-glue.c
|
||||
http_cgi.c
|
||||
|
@ -804,6 +800,11 @@ add_executable(lighttpd
|
|||
sock_addr_cache.c
|
||||
ls-hpack/lshpack.c
|
||||
algo_xxhash.c
|
||||
fdevent_impl.c
|
||||
fdevent_select.c fdevent_libev.c
|
||||
fdevent_poll.c fdevent_linux_sysepoll.c
|
||||
fdevent_solaris_devpoll.c fdevent_solaris_port.c
|
||||
fdevent_freebsd_kqueue.c
|
||||
http_range.c
|
||||
network.c
|
||||
network_write.c
|
||||
|
|
|
@ -80,10 +80,6 @@ common_src=base64.c buffer.c burl.c log.c \
|
|||
http_chunk.c fdevent.c gw_backend.c \
|
||||
stat_cache.c plugin.c http_etag.c array.c \
|
||||
algo_md5.c algo_sha1.c algo_splaytree.c \
|
||||
fdevent_select.c fdevent_libev.c \
|
||||
fdevent_poll.c fdevent_linux_sysepoll.c \
|
||||
fdevent_solaris_devpoll.c fdevent_solaris_port.c \
|
||||
fdevent_freebsd_kqueue.c \
|
||||
configfile-glue.c \
|
||||
http-header-glue.c \
|
||||
http_cgi.c \
|
||||
|
@ -101,6 +97,11 @@ src = server.c response.c connections.c h2.c reqpool.c \
|
|||
network_write.c \
|
||||
ls-hpack/lshpack.c \
|
||||
algo_xxhash.c \
|
||||
fdevent_impl.c \
|
||||
fdevent_select.c fdevent_libev.c \
|
||||
fdevent_poll.c fdevent_linux_sysepoll.c \
|
||||
fdevent_solaris_devpoll.c fdevent_solaris_port.c \
|
||||
fdevent_freebsd_kqueue.c \
|
||||
http_range.c \
|
||||
data_config.c \
|
||||
vector.c \
|
||||
|
|
|
@ -60,10 +60,6 @@ common_src = Split("base64.c buffer.c burl.c log.c \
|
|||
http_chunk.c fdevent.c gw_backend.c \
|
||||
stat_cache.c plugin.c http_etag.c array.c \
|
||||
algo_md5.c algo_sha1.c algo_splaytree.c \
|
||||
fdevent_select.c fdevent_libev.c \
|
||||
fdevent_poll.c fdevent_linux_sysepoll.c \
|
||||
fdevent_solaris_devpoll.c fdevent_solaris_port.c \
|
||||
fdevent_freebsd_kqueue.c \
|
||||
configfile-glue.c \
|
||||
http-header-glue.c \
|
||||
http_cgi.c \
|
||||
|
@ -80,6 +76,11 @@ src = Split("server.c response.c connections.c h2.c reqpool.c \
|
|||
sock_addr_cache.c \
|
||||
ls-hpack/lshpack.c \
|
||||
algo_xxhash.c \
|
||||
fdevent_impl.c \
|
||||
fdevent_select.c fdevent_libev.c \
|
||||
fdevent_poll.c fdevent_linux_sysepoll.c \
|
||||
fdevent_solaris_devpoll.c fdevent_solaris_port.c \
|
||||
fdevent_freebsd_kqueue.c \
|
||||
http_range.c \
|
||||
network.c \
|
||||
network_write.c \
|
||||
|
|
283
src/fdevent.c
283
src/fdevent.c
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include "sys-socket.h"
|
||||
#include "sys-time.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -55,243 +54,6 @@ void fdevent_socket_nb_cloexec_init (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
int fdevent_config(const char **event_handler_name, log_error_st *errh) {
|
||||
static const struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] =
|
||||
{
|
||||
/* - epoll is most reliable
|
||||
* - select works everywhere
|
||||
*/
|
||||
#ifdef FDEVENT_USE_LINUX_EPOLL
|
||||
{ FDEVENT_HANDLER_LINUX_SYSEPOLL, "linux-sysepoll" },
|
||||
{ FDEVENT_HANDLER_LINUX_SYSEPOLL, "epoll" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_PORT
|
||||
{ FDEVENT_HANDLER_SOLARIS_PORT, "solaris-eventports" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_DEVPOLL
|
||||
{ FDEVENT_HANDLER_SOLARIS_DEVPOLL,"solaris-devpoll" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_FREEBSD_KQUEUE
|
||||
{ FDEVENT_HANDLER_FREEBSD_KQUEUE, "freebsd-kqueue" },
|
||||
{ FDEVENT_HANDLER_FREEBSD_KQUEUE, "kqueue" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_POLL
|
||||
{ FDEVENT_HANDLER_POLL, "poll" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SELECT
|
||||
{ FDEVENT_HANDLER_SELECT, "select" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_LIBEV
|
||||
{ FDEVENT_HANDLER_LIBEV, "libev" },
|
||||
#endif
|
||||
{ FDEVENT_HANDLER_UNSET, NULL }
|
||||
};
|
||||
|
||||
const char * event_handler = *event_handler_name;
|
||||
fdevent_handler_t et = FDEVENT_HANDLER_UNSET;
|
||||
|
||||
#ifndef FDEVENT_USE_LIBEV
|
||||
if (NULL != event_handler && 0 == strcmp(event_handler, "libev"))
|
||||
event_handler = NULL;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_POLL
|
||||
if (NULL != event_handler && 0 == strcmp(event_handler, "select"))
|
||||
event_handler = "poll";
|
||||
#endif
|
||||
|
||||
if (NULL == event_handler) {
|
||||
/* choose a good default
|
||||
*
|
||||
* the event_handler list is sorted by 'goodness'
|
||||
* taking the first available should be the best solution
|
||||
*/
|
||||
et = event_handlers[0].et;
|
||||
*event_handler_name = event_handlers[0].name;
|
||||
|
||||
if (FDEVENT_HANDLER_UNSET == et) {
|
||||
log_error(errh, __FILE__, __LINE__,
|
||||
"sorry, there is no event handler for this system");
|
||||
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* User override
|
||||
*/
|
||||
|
||||
for (uint32_t i = 0; event_handlers[i].name; ++i) {
|
||||
if (0 == strcmp(event_handlers[i].name, event_handler)) {
|
||||
et = event_handlers[i].et;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FDEVENT_HANDLER_UNSET == et) {
|
||||
log_error(errh, __FILE__, __LINE__,
|
||||
"the selected event-handler in unknown or not supported: %s",
|
||||
event_handler);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return et;
|
||||
}
|
||||
|
||||
const char * fdevent_show_event_handlers(void) {
|
||||
return
|
||||
"\nEvent Handlers:\n\n"
|
||||
#ifdef FDEVENT_USE_SELECT
|
||||
"\t+ select (generic)\n"
|
||||
#else
|
||||
"\t- select (generic)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_POLL
|
||||
"\t+ poll (Unix)\n"
|
||||
#else
|
||||
"\t- poll (Unix)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_LINUX_EPOLL
|
||||
"\t+ epoll (Linux)\n"
|
||||
#else
|
||||
"\t- epoll (Linux)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_DEVPOLL
|
||||
"\t+ /dev/poll (Solaris)\n"
|
||||
#else
|
||||
"\t- /dev/poll (Solaris)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_PORT
|
||||
"\t+ eventports (Solaris)\n"
|
||||
#else
|
||||
"\t- eventports (Solaris)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_FREEBSD_KQUEUE
|
||||
"\t+ kqueue (FreeBSD)\n"
|
||||
#else
|
||||
"\t- kqueue (FreeBSD)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_LIBEV
|
||||
"\t+ libev (generic)\n"
|
||||
#else
|
||||
"\t- libev (generic)\n"
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
fdevents * fdevent_init(const char *event_handler, int *max_fds, int *cur_fds, log_error_st *errh) {
|
||||
fdevents *ev;
|
||||
uint32_t maxfds = (0 != *max_fds)
|
||||
? (uint32_t)*max_fds
|
||||
: 4096;
|
||||
int type = fdevent_config(&event_handler, errh);
|
||||
if (type <= 0) return NULL;
|
||||
|
||||
fdevent_socket_nb_cloexec_init();
|
||||
|
||||
#ifdef FDEVENT_USE_SELECT
|
||||
/* select limits itself
|
||||
* as it is a hard limit and will lead to a segfault we add some safety
|
||||
* */
|
||||
if (type == FDEVENT_HANDLER_SELECT) {
|
||||
if (maxfds > (uint32_t)FD_SETSIZE - 200)
|
||||
maxfds = (uint32_t)FD_SETSIZE - 200;
|
||||
}
|
||||
#endif
|
||||
*max_fds = (int)maxfds;
|
||||
++maxfds; /*(+1 for event-handler fd)*/
|
||||
|
||||
ev = calloc(1, sizeof(*ev));
|
||||
force_assert(NULL != ev);
|
||||
ev->errh = errh;
|
||||
ev->cur_fds = cur_fds;
|
||||
ev->event_handler = event_handler;
|
||||
ev->fdarray = calloc(maxfds, sizeof(*ev->fdarray));
|
||||
if (NULL == ev->fdarray) {
|
||||
log_error(ev->errh, __FILE__, __LINE__,
|
||||
"server.max-fds too large? (%u)", maxfds-1);
|
||||
free(ev);
|
||||
return NULL;
|
||||
}
|
||||
ev->maxfds = maxfds;
|
||||
|
||||
switch(type) {
|
||||
#ifdef FDEVENT_USE_POLL
|
||||
case FDEVENT_HANDLER_POLL:
|
||||
if (0 == fdevent_poll_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SELECT
|
||||
case FDEVENT_HANDLER_SELECT:
|
||||
if (0 == fdevent_select_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_LINUX_EPOLL
|
||||
case FDEVENT_HANDLER_LINUX_SYSEPOLL:
|
||||
if (0 == fdevent_linux_sysepoll_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_DEVPOLL
|
||||
case FDEVENT_HANDLER_SOLARIS_DEVPOLL:
|
||||
if (0 == fdevent_solaris_devpoll_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_PORT
|
||||
case FDEVENT_HANDLER_SOLARIS_PORT:
|
||||
if (0 == fdevent_solaris_port_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_FREEBSD_KQUEUE
|
||||
case FDEVENT_HANDLER_FREEBSD_KQUEUE:
|
||||
if (0 == fdevent_freebsd_kqueue_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_LIBEV
|
||||
case FDEVENT_HANDLER_LIBEV:
|
||||
if (0 == fdevent_libev_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
/*case FDEVENT_HANDLER_UNSET:*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
free(ev->fdarray);
|
||||
free(ev);
|
||||
|
||||
log_error(errh, __FILE__, __LINE__,
|
||||
"event-handler failed: %s; "
|
||||
"try to set server.event-handler = \"poll\" or \"select\"",
|
||||
event_handler);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fdevent_free(fdevents *ev) {
|
||||
if (!ev) return;
|
||||
|
||||
if (ev->free) ev->free(ev);
|
||||
|
||||
for (uint32_t i = 0; i < ev->maxfds; ++i) {
|
||||
/* (fdevent_sched_run() should already have been run,
|
||||
* but take reasonable precautions anyway) */
|
||||
if (ev->fdarray[i])
|
||||
free((fdnode *)((uintptr_t)ev->fdarray[i] & ~0x3));
|
||||
}
|
||||
|
||||
free(ev->fdarray);
|
||||
free(ev);
|
||||
}
|
||||
|
||||
int fdevent_reset(fdevents *ev) {
|
||||
int rc = (NULL != ev->reset) ? ev->reset(ev) : 0;
|
||||
if (-1 == rc) {
|
||||
log_error(ev->errh, __FILE__, __LINE__,
|
||||
"event-handler failed: %s; "
|
||||
"try to set server.event-handler = \"poll\" or \"select\"",
|
||||
ev->event_handler ? ev->event_handler : "");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
__attribute_malloc__
|
||||
__attribute_returns_nonnull__
|
||||
static fdnode *fdnode_init(void) {
|
||||
|
@ -333,42 +95,6 @@ void fdevent_sched_close(fdevents *ev, int fd, int issock) {
|
|||
ev->pendclose = fdn;
|
||||
}
|
||||
|
||||
static void fdevent_sched_run(fdevents *ev) {
|
||||
for (fdnode *fdn = ev->pendclose; fdn; ) {
|
||||
int fd, rc;
|
||||
fdnode *fdn_tmp;
|
||||
#ifdef _WIN32
|
||||
rc = (uintptr_t)fdn & 0x3;
|
||||
#endif
|
||||
fdn = (fdnode *)((uintptr_t)fdn & ~0x3);
|
||||
fd = fdn->fd;
|
||||
#ifdef _WIN32
|
||||
if (rc == 0x1) {
|
||||
rc = closesocket(fd);
|
||||
}
|
||||
else if (rc == 0x2) {
|
||||
rc = close(fd);
|
||||
}
|
||||
#else
|
||||
rc = close(fd);
|
||||
#endif
|
||||
|
||||
if (0 != rc) {
|
||||
log_perror(ev->errh, __FILE__, __LINE__, "close failed %d", fd);
|
||||
}
|
||||
else {
|
||||
--(*ev->cur_fds);
|
||||
}
|
||||
|
||||
fdn_tmp = fdn;
|
||||
fdn = (fdnode *)fdn->ctx; /* next */
|
||||
/*(fdevent_unregister)*/
|
||||
fdnode_free(fdn_tmp);
|
||||
ev->fdarray[fd] = NULL;
|
||||
}
|
||||
ev->pendclose = NULL;
|
||||
}
|
||||
|
||||
__attribute_cold__
|
||||
__attribute_noinline__
|
||||
static int fdevent_fdnode_event_unsetter_retry(fdevents *ev, fdnode *fdn) {
|
||||
|
@ -455,15 +181,6 @@ void fdevent_fdnode_event_clr(fdevents *ev, fdnode *fdn, int event) {
|
|||
if (NULL != fdn) fdevent_fdnode_event_setter(ev, fdn, (fdn->events&~event));
|
||||
}
|
||||
|
||||
int fdevent_poll(fdevents *ev, int timeout_ms) {
|
||||
int n = ev->poll(ev, timeout_ms);
|
||||
if (n >= 0)
|
||||
fdevent_sched_run(ev);
|
||||
else if (errno != EINTR)
|
||||
log_perror(ev->errh, __FILE__, __LINE__, "fdevent_poll failed");
|
||||
return n;
|
||||
}
|
||||
|
||||
void fdevent_setfd_cloexec(int fd) {
|
||||
#ifdef FD_CLOEXEC
|
||||
if (fd < 0) return;
|
||||
|
|
|
@ -0,0 +1,318 @@
|
|||
#include "first.h"
|
||||
|
||||
#include "fdevent_impl.h"
|
||||
#include "fdevent.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h> /* closesocket */
|
||||
#endif
|
||||
|
||||
int
|
||||
fdevent_config (const char **event_handler_name, log_error_st *errh)
|
||||
{
|
||||
static const struct ev_map { fdevent_handler_t et; const char *name; }
|
||||
event_handlers[] =
|
||||
{
|
||||
/* - epoll is most reliable
|
||||
* - select works everywhere
|
||||
*/
|
||||
#ifdef FDEVENT_USE_LINUX_EPOLL
|
||||
{ FDEVENT_HANDLER_LINUX_SYSEPOLL, "linux-sysepoll" },
|
||||
{ FDEVENT_HANDLER_LINUX_SYSEPOLL, "epoll" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_PORT
|
||||
{ FDEVENT_HANDLER_SOLARIS_PORT, "solaris-eventports" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_DEVPOLL
|
||||
{ FDEVENT_HANDLER_SOLARIS_DEVPOLL,"solaris-devpoll" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_FREEBSD_KQUEUE
|
||||
{ FDEVENT_HANDLER_FREEBSD_KQUEUE, "freebsd-kqueue" },
|
||||
{ FDEVENT_HANDLER_FREEBSD_KQUEUE, "kqueue" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_POLL
|
||||
{ FDEVENT_HANDLER_POLL, "poll" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SELECT
|
||||
{ FDEVENT_HANDLER_SELECT, "select" },
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_LIBEV
|
||||
{ FDEVENT_HANDLER_LIBEV, "libev" },
|
||||
#endif
|
||||
{ FDEVENT_HANDLER_UNSET, NULL }
|
||||
};
|
||||
|
||||
const char *event_handler = *event_handler_name;
|
||||
fdevent_handler_t et = FDEVENT_HANDLER_UNSET;
|
||||
|
||||
#ifndef FDEVENT_USE_LIBEV
|
||||
if (NULL != event_handler && 0 == strcmp(event_handler, "libev"))
|
||||
event_handler = NULL;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_POLL
|
||||
if (NULL != event_handler && 0 == strcmp(event_handler, "select"))
|
||||
event_handler = "poll";
|
||||
#endif
|
||||
|
||||
if (NULL == event_handler) {
|
||||
/* choose a good default
|
||||
*
|
||||
* the event_handler list is sorted by 'goodness'
|
||||
* taking the first available should be the best solution
|
||||
*/
|
||||
et = event_handlers[0].et;
|
||||
*event_handler_name = event_handlers[0].name;
|
||||
|
||||
if (FDEVENT_HANDLER_UNSET == et) {
|
||||
log_error(errh, __FILE__, __LINE__,
|
||||
"sorry, there is no event handler for this system");
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* User override
|
||||
*/
|
||||
|
||||
for (uint32_t i = 0; event_handlers[i].name; ++i) {
|
||||
if (0 == strcmp(event_handlers[i].name, event_handler)) {
|
||||
et = event_handlers[i].et;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FDEVENT_HANDLER_UNSET == et) {
|
||||
log_error(errh, __FILE__, __LINE__,
|
||||
"the selected event-handler in unknown or not supported: %s",
|
||||
event_handler);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return et;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
fdevent_show_event_handlers (void)
|
||||
{
|
||||
return
|
||||
"\nEvent Handlers:\n\n"
|
||||
#ifdef FDEVENT_USE_SELECT
|
||||
"\t+ select (generic)\n"
|
||||
#else
|
||||
"\t- select (generic)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_POLL
|
||||
"\t+ poll (Unix)\n"
|
||||
#else
|
||||
"\t- poll (Unix)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_LINUX_EPOLL
|
||||
"\t+ epoll (Linux)\n"
|
||||
#else
|
||||
"\t- epoll (Linux)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_DEVPOLL
|
||||
"\t+ /dev/poll (Solaris)\n"
|
||||
#else
|
||||
"\t- /dev/poll (Solaris)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_PORT
|
||||
"\t+ eventports (Solaris)\n"
|
||||
#else
|
||||
"\t- eventports (Solaris)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_FREEBSD_KQUEUE
|
||||
"\t+ kqueue (FreeBSD)\n"
|
||||
#else
|
||||
"\t- kqueue (FreeBSD)\n"
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_LIBEV
|
||||
"\t+ libev (generic)\n"
|
||||
#else
|
||||
"\t- libev (generic)\n"
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
fdevents *
|
||||
fdevent_init (const char *event_handler, int *max_fds, int *cur_fds, log_error_st *errh)
|
||||
{
|
||||
fdevents *ev;
|
||||
uint32_t maxfds = (0 != *max_fds)
|
||||
? (uint32_t)*max_fds
|
||||
: 4096;
|
||||
int type = fdevent_config(&event_handler, errh);
|
||||
if (type <= 0) return NULL;
|
||||
|
||||
fdevent_socket_nb_cloexec_init();
|
||||
|
||||
#ifdef FDEVENT_USE_SELECT
|
||||
/* select limits itself
|
||||
* as it is a hard limit and will lead to a segfault we add some safety
|
||||
* */
|
||||
if (type == FDEVENT_HANDLER_SELECT) {
|
||||
if (maxfds > (uint32_t)FD_SETSIZE - 200)
|
||||
maxfds = (uint32_t)FD_SETSIZE - 200;
|
||||
}
|
||||
#endif
|
||||
*max_fds = (int)maxfds;
|
||||
++maxfds; /*(+1 for event-handler fd)*/
|
||||
|
||||
ev = calloc(1, sizeof(*ev));
|
||||
force_assert(NULL != ev);
|
||||
ev->errh = errh;
|
||||
ev->cur_fds = cur_fds;
|
||||
ev->event_handler = event_handler;
|
||||
ev->fdarray = calloc(maxfds, sizeof(*ev->fdarray));
|
||||
if (NULL == ev->fdarray) {
|
||||
log_error(ev->errh, __FILE__, __LINE__,
|
||||
"server.max-fds too large? (%u)", maxfds-1);
|
||||
free(ev);
|
||||
return NULL;
|
||||
}
|
||||
ev->maxfds = maxfds;
|
||||
|
||||
switch(type) {
|
||||
#ifdef FDEVENT_USE_POLL
|
||||
case FDEVENT_HANDLER_POLL:
|
||||
if (0 == fdevent_poll_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SELECT
|
||||
case FDEVENT_HANDLER_SELECT:
|
||||
if (0 == fdevent_select_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_LINUX_EPOLL
|
||||
case FDEVENT_HANDLER_LINUX_SYSEPOLL:
|
||||
if (0 == fdevent_linux_sysepoll_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_DEVPOLL
|
||||
case FDEVENT_HANDLER_SOLARIS_DEVPOLL:
|
||||
if (0 == fdevent_solaris_devpoll_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_SOLARIS_PORT
|
||||
case FDEVENT_HANDLER_SOLARIS_PORT:
|
||||
if (0 == fdevent_solaris_port_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_FREEBSD_KQUEUE
|
||||
case FDEVENT_HANDLER_FREEBSD_KQUEUE:
|
||||
if (0 == fdevent_freebsd_kqueue_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
#ifdef FDEVENT_USE_LIBEV
|
||||
case FDEVENT_HANDLER_LIBEV:
|
||||
if (0 == fdevent_libev_init(ev)) return ev;
|
||||
break;
|
||||
#endif
|
||||
/*case FDEVENT_HANDLER_UNSET:*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
free(ev->fdarray);
|
||||
free(ev);
|
||||
|
||||
log_error(errh, __FILE__, __LINE__,
|
||||
"event-handler failed: %s; "
|
||||
"try to set server.event-handler = \"poll\" or \"select\"",
|
||||
event_handler);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fdevent_free (fdevents *ev)
|
||||
{
|
||||
if (!ev) return;
|
||||
if (ev->free) ev->free(ev);
|
||||
|
||||
for (uint32_t i = 0; i < ev->maxfds; ++i) {
|
||||
/* (fdevent_sched_run() should already have been run,
|
||||
* but take reasonable precautions anyway) */
|
||||
if (ev->fdarray[i])
|
||||
free((fdnode *)((uintptr_t)ev->fdarray[i] & ~0x3));
|
||||
}
|
||||
|
||||
free(ev->fdarray);
|
||||
free(ev);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fdevent_reset (fdevents *ev)
|
||||
{
|
||||
int rc = (NULL != ev->reset) ? ev->reset(ev) : 0;
|
||||
if (-1 == rc) {
|
||||
log_error(ev->errh, __FILE__, __LINE__,
|
||||
"event-handler failed: %s; "
|
||||
"try to set server.event-handler = \"poll\" or \"select\"",
|
||||
ev->event_handler ? ev->event_handler : "");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fdevent_sched_run (fdevents * const ev)
|
||||
{
|
||||
for (fdnode *fdn = ev->pendclose; fdn; ) {
|
||||
int fd, rc;
|
||||
#ifdef _WIN32
|
||||
rc = (uintptr_t)fdn & 0x3;
|
||||
#endif
|
||||
fdn = (fdnode *)((uintptr_t)fdn & ~0x3);
|
||||
fd = fdn->fd;
|
||||
#ifdef _WIN32
|
||||
if (rc == 0x1) {
|
||||
rc = closesocket(fd);
|
||||
}
|
||||
else if (rc == 0x2) {
|
||||
rc = close(fd);
|
||||
}
|
||||
#else
|
||||
rc = close(fd);
|
||||
#endif
|
||||
|
||||
if (0 != rc) {
|
||||
log_perror(ev->errh, __FILE__, __LINE__, "close failed %d", fd);
|
||||
}
|
||||
else {
|
||||
--(*ev->cur_fds);
|
||||
}
|
||||
|
||||
fdnode * const fdn_tmp = fdn;
|
||||
fdn = (fdnode *)fdn->ctx; /* next */
|
||||
/*(fdevent_unregister)*/
|
||||
free(fdn_tmp); /*fdnode_free(fdn_tmp);*/
|
||||
ev->fdarray[fd] = NULL;
|
||||
}
|
||||
ev->pendclose = NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fdevent_poll (fdevents * const ev, const int timeout_ms)
|
||||
{
|
||||
const int n = ev->poll(ev, timeout_ms);
|
||||
if (n >= 0)
|
||||
fdevent_sched_run(ev);
|
||||
else if (errno != EINTR)
|
||||
log_perror(ev->errh, __FILE__, __LINE__, "fdevent_poll failed");
|
||||
return n;
|
||||
}
|
|
@ -727,13 +727,6 @@ common_src = [
|
|||
'chunk.c',
|
||||
'configfile-glue.c',
|
||||
'http_etag.c',
|
||||
'fdevent_freebsd_kqueue.c',
|
||||
'fdevent_libev.c',
|
||||
'fdevent_linux_sysepoll.c',
|
||||
'fdevent_poll.c',
|
||||
'fdevent_select.c',
|
||||
'fdevent_solaris_devpoll.c',
|
||||
'fdevent_solaris_port.c',
|
||||
'fdevent.c',
|
||||
'fdlog_maint.c',
|
||||
'fdlog.c',
|
||||
|
@ -765,6 +758,14 @@ main_src = [
|
|||
'sock_addr_cache.c',
|
||||
'ls-hpack/lshpack.c',
|
||||
'algo_xxhash.c',
|
||||
'fdevent_impl.c',
|
||||
'fdevent_freebsd_kqueue.c',
|
||||
'fdevent_libev.c',
|
||||
'fdevent_linux_sysepoll.c',
|
||||
'fdevent_poll.c',
|
||||
'fdevent_select.c',
|
||||
'fdevent_solaris_devpoll.c',
|
||||
'fdevent_solaris_port.c',
|
||||
'http_range.c',
|
||||
'network_write.c',
|
||||
'network.c',
|
||||
|
|
|
@ -117,15 +117,6 @@ int main (void)
|
|||
* stub functions
|
||||
*/
|
||||
|
||||
#include "fdevent_impl.h"
|
||||
int fdevent_select_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_poll_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_linux_sysepoll_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_solaris_devpoll_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_solaris_port_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_freebsd_kqueue_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_libev_init(struct fdevents *ev) { return NULL == ev; }
|
||||
|
||||
int config_plugin_values_init(server *srv, void *p_d, const config_plugin_keys_t *cpk, const char *mname) {
|
||||
UNUSED(srv);
|
||||
UNUSED(p_d);
|
||||
|
|
|
@ -178,15 +178,6 @@ int main (void)
|
|||
* stub functions
|
||||
*/
|
||||
|
||||
#include "fdevent_impl.h"
|
||||
int fdevent_select_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_poll_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_linux_sysepoll_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_solaris_devpoll_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_solaris_port_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_freebsd_kqueue_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_libev_init(struct fdevents *ev) { return NULL == ev; }
|
||||
|
||||
int config_plugin_values_init(server *srv, void *p_d, const config_plugin_keys_t *cpk, const char *mname) {
|
||||
UNUSED(srv);
|
||||
UNUSED(p_d);
|
||||
|
|
|
@ -439,15 +439,6 @@ int main (void)
|
|||
* stub functions
|
||||
*/
|
||||
|
||||
#include "fdevent_impl.h"
|
||||
int fdevent_select_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_poll_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_linux_sysepoll_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_solaris_devpoll_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_solaris_port_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_freebsd_kqueue_init(struct fdevents *ev) { return NULL == ev; }
|
||||
int fdevent_libev_init(struct fdevents *ev) { return NULL == ev; }
|
||||
|
||||
int config_plugin_values_init(server *srv, void *p_d, const config_plugin_keys_t *cpk, const char *mname) {
|
||||
UNUSED(srv);
|
||||
UNUSED(p_d);
|
||||
|
|
Loading…
Reference in New Issue