[core] fdevent_fdnode.c separate from fdevent.c
This commit is contained in:
parent
7113dcb49b
commit
0f51b3728a
|
@ -759,7 +759,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
|||
set(COMMON_SRC
|
||||
base64.c buffer.c burl.c log.c
|
||||
http_header.c http_kv.c keyvalue.c chunk.c
|
||||
http_chunk.c fdevent.c gw_backend.c
|
||||
http_chunk.c fdevent.c fdevent_fdnode.c gw_backend.c
|
||||
stat_cache.c plugin.c http_etag.c array.c
|
||||
algo_md5.c algo_sha1.c algo_splaytree.c
|
||||
configfile-glue.c
|
||||
|
@ -943,6 +943,7 @@ add_executable(test_mod_indexfile
|
|||
fdlog.c
|
||||
sock_addr.c
|
||||
stat_cache.c
|
||||
fdevent_fdnode.c
|
||||
algo_splaytree.c
|
||||
ck.c
|
||||
)
|
||||
|
@ -978,6 +979,7 @@ add_executable(test_mod_ssi
|
|||
fdlog.c
|
||||
sock_addr.c
|
||||
stat_cache.c
|
||||
fdevent_fdnode.c
|
||||
algo_splaytree.c
|
||||
ck.c
|
||||
)
|
||||
|
@ -1003,6 +1005,7 @@ add_executable(test_mod_staticfile
|
|||
fdlog.c
|
||||
sock_addr.c
|
||||
stat_cache.c
|
||||
fdevent_fdnode.c
|
||||
algo_splaytree.c
|
||||
ck.c
|
||||
)
|
||||
|
|
|
@ -77,7 +77,7 @@ CLEANFILES = versionstamp.h versionstamp.h.tmp lemon$(BUILD_EXEEXT)
|
|||
|
||||
common_src=base64.c buffer.c burl.c log.c \
|
||||
http_header.c http_kv.c keyvalue.c chunk.c \
|
||||
http_chunk.c fdevent.c gw_backend.c \
|
||||
http_chunk.c fdevent.c fdevent_fdnode.c gw_backend.c \
|
||||
stat_cache.c plugin.c http_etag.c array.c \
|
||||
algo_md5.c algo_sha1.c algo_splaytree.c \
|
||||
configfile-glue.c \
|
||||
|
@ -666,16 +666,16 @@ t_test_mod_access_LDADD = $(LIBUNWIND_LIBS)
|
|||
t_test_mod_evhost_SOURCES = t/test_mod_evhost.c buffer.c array.c log.c fdlog.c ck.c
|
||||
t_test_mod_evhost_LDADD = $(LIBUNWIND_LIBS)
|
||||
|
||||
t_test_mod_indexfile_SOURCES = t/test_mod_indexfile.c request.c base64.c buffer.c burl.c array.c fdevent.c http_etag.c http_header.c http_kv.c log.c fdlog.c sock_addr.c stat_cache.c algo_splaytree.c ck.c
|
||||
t_test_mod_indexfile_SOURCES = t/test_mod_indexfile.c request.c base64.c buffer.c burl.c array.c fdevent.c http_etag.c http_header.c http_kv.c log.c fdlog.c sock_addr.c stat_cache.c fdevent_fdnode.c algo_splaytree.c ck.c
|
||||
t_test_mod_indexfile_LDADD = $(LIBUNWIND_LIBS) $(FAM_LIBS)
|
||||
|
||||
t_test_mod_simple_vhost_SOURCES = t/test_mod_simple_vhost.c buffer.c array.c log.c fdlog.c ck.c
|
||||
t_test_mod_simple_vhost_LDADD = $(LIBUNWIND_LIBS)
|
||||
|
||||
t_test_mod_ssi_SOURCES = t/test_mod_ssi.c request.c base64.c buffer.c burl.c array.c chunk.c fdevent.c http-header-glue.c http_cgi.c http_chunk.c http_date.c http_etag.c http_header.c http_kv.c log.c fdlog.c sock_addr.c stat_cache.c algo_splaytree.c ck.c
|
||||
t_test_mod_ssi_SOURCES = t/test_mod_ssi.c request.c base64.c buffer.c burl.c array.c chunk.c fdevent.c http-header-glue.c http_cgi.c http_chunk.c http_date.c http_etag.c http_header.c http_kv.c log.c fdlog.c sock_addr.c stat_cache.c fdevent_fdnode.c algo_splaytree.c ck.c
|
||||
t_test_mod_ssi_LDADD = $(LIBUNWIND_LIBS) $(FAM_LIBS)
|
||||
|
||||
t_test_mod_staticfile_SOURCES = t/test_mod_staticfile.c request.c base64.c buffer.c burl.c array.c chunk.c fdevent.c http-header-glue.c http_cgi.c http_chunk.c http_date.c http_etag.c http_header.c http_kv.c log.c fdlog.c sock_addr.c stat_cache.c algo_splaytree.c ck.c
|
||||
t_test_mod_staticfile_SOURCES = t/test_mod_staticfile.c request.c base64.c buffer.c burl.c array.c chunk.c fdevent.c http-header-glue.c http_cgi.c http_chunk.c http_date.c http_etag.c http_header.c http_kv.c log.c fdlog.c sock_addr.c stat_cache.c fdevent_fdnode.c algo_splaytree.c ck.c
|
||||
t_test_mod_staticfile_LDADD = $(LIBUNWIND_LIBS) $(FAM_LIBS)
|
||||
|
||||
t_test_mod_userdir_SOURCES = t/test_mod_userdir.c buffer.c array.c log.c fdlog.c ck.c
|
||||
|
|
|
@ -57,7 +57,7 @@ def GatherLibs(env, *libs):
|
|||
|
||||
common_src = Split("base64.c buffer.c burl.c log.c \
|
||||
http_header.c http_kv.c keyvalue.c chunk.c \
|
||||
http_chunk.c fdevent.c gw_backend.c \
|
||||
http_chunk.c fdevent.c fdevent_fdnode.c gw_backend.c \
|
||||
stat_cache.c plugin.c http_etag.c array.c \
|
||||
algo_md5.c algo_sha1.c algo_splaytree.c \
|
||||
configfile-glue.c \
|
||||
|
|
129
src/fdevent.c
129
src/fdevent.c
|
@ -1,6 +1,5 @@
|
|||
#include "first.h"
|
||||
|
||||
#include "fdevent_impl.h"
|
||||
#include "fdevent.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
|
@ -18,6 +17,7 @@
|
|||
#include <sys/stat.h> /* _S_IREAD _S_IWRITE */
|
||||
#include <io.h>
|
||||
#include <share.h> /* _SH_DENYRW */
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef SOCK_CLOEXEC
|
||||
|
@ -54,133 +54,6 @@ void fdevent_socket_nb_cloexec_init (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
__attribute_malloc__
|
||||
__attribute_returns_nonnull__
|
||||
static fdnode *fdnode_init(void) {
|
||||
fdnode * const restrict fdn = calloc(1, sizeof(fdnode));
|
||||
force_assert(NULL != fdn);
|
||||
return fdn;
|
||||
}
|
||||
|
||||
static void fdnode_free(fdnode *fdn) {
|
||||
free(fdn);
|
||||
}
|
||||
|
||||
fdnode * fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx) {
|
||||
fdnode *fdn = ev->fdarray[fd] = fdnode_init();
|
||||
fdn->handler = handler;
|
||||
fdn->fd = fd;
|
||||
fdn->ctx = ctx;
|
||||
fdn->events = 0;
|
||||
fdn->fde_ndx = -1;
|
||||
#ifdef FDEVENT_USE_LIBEV
|
||||
fdn->handler_ctx = NULL;
|
||||
#endif
|
||||
return fdn;
|
||||
}
|
||||
|
||||
void fdevent_unregister(fdevents *ev, int fd) {
|
||||
fdnode *fdn = ev->fdarray[fd];
|
||||
if ((uintptr_t)fdn & 0x3) return; /*(should not happen)*/
|
||||
ev->fdarray[fd] = NULL;
|
||||
fdnode_free(fdn);
|
||||
}
|
||||
|
||||
void fdevent_sched_close(fdevents *ev, int fd, int issock) {
|
||||
fdnode *fdn = ev->fdarray[fd];
|
||||
if ((uintptr_t)fdn & 0x3) return;
|
||||
ev->fdarray[fd] = (fdnode *)((uintptr_t)fdn | (issock ? 0x1 : 0x2));
|
||||
fdn->handler = (fdevent_handler)NULL;
|
||||
fdn->ctx = ev->pendclose;
|
||||
ev->pendclose = fdn;
|
||||
}
|
||||
|
||||
__attribute_cold__
|
||||
__attribute_noinline__
|
||||
static int fdevent_fdnode_event_unsetter_retry(fdevents *ev, fdnode *fdn) {
|
||||
do {
|
||||
switch (errno) {
|
||||
#ifdef EWOULDBLOCK
|
||||
#if EAGAIN != EWOULDBLOCK
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
#endif
|
||||
case EAGAIN:
|
||||
case EINTR:
|
||||
/* temporary error; retry */
|
||||
break;
|
||||
/*case ENOMEM:*/
|
||||
default:
|
||||
/* unrecoverable error; might leak fd */
|
||||
log_perror(ev->errh, __FILE__, __LINE__,
|
||||
"fdevent event_del failed on fd %d", fdn->fd);
|
||||
return 0;
|
||||
}
|
||||
} while (0 != ev->event_del(ev, fdn));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void fdevent_fdnode_event_unsetter(fdevents *ev, fdnode *fdn) {
|
||||
if (-1 == fdn->fde_ndx) return;
|
||||
if (0 != ev->event_del(ev, fdn))
|
||||
fdevent_fdnode_event_unsetter_retry(ev, fdn);
|
||||
fdn->fde_ndx = -1;
|
||||
fdn->events = 0;
|
||||
}
|
||||
|
||||
__attribute_cold__
|
||||
__attribute_noinline__
|
||||
static int fdevent_fdnode_event_setter_retry(fdevents *ev, fdnode *fdn, int events) {
|
||||
do {
|
||||
switch (errno) {
|
||||
#ifdef EWOULDBLOCK
|
||||
#if EAGAIN != EWOULDBLOCK
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
#endif
|
||||
case EAGAIN:
|
||||
case EINTR:
|
||||
/* temporary error; retry */
|
||||
break;
|
||||
/*case ENOMEM:*/
|
||||
default:
|
||||
/* unrecoverable error */
|
||||
log_perror(ev->errh, __FILE__, __LINE__,
|
||||
"fdevent event_set failed on fd %d", fdn->fd);
|
||||
return 0;
|
||||
}
|
||||
} while (0 != ev->event_set(ev, fdn, events));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void fdevent_fdnode_event_setter(fdevents *ev, fdnode *fdn, int events) {
|
||||
/*(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 (fdn->events == events) return;/*(no change; nothing to do)*/
|
||||
|
||||
if (0 == ev->event_set(ev, fdn, events)
|
||||
|| fdevent_fdnode_event_setter_retry(ev, fdn, events))
|
||||
fdn->events = events;
|
||||
}
|
||||
|
||||
void fdevent_fdnode_event_del(fdevents *ev, fdnode *fdn) {
|
||||
if (NULL != fdn) fdevent_fdnode_event_unsetter(ev, fdn);
|
||||
}
|
||||
|
||||
void fdevent_fdnode_event_set(fdevents *ev, fdnode *fdn, int events) {
|
||||
if (NULL != fdn) fdevent_fdnode_event_setter(ev, fdn, events);
|
||||
}
|
||||
|
||||
void fdevent_fdnode_event_add(fdevents *ev, fdnode *fdn, int event) {
|
||||
if (NULL != fdn) fdevent_fdnode_event_setter(ev, fdn, (fdn->events|event));
|
||||
}
|
||||
|
||||
void fdevent_fdnode_event_clr(fdevents *ev, fdnode *fdn, int event) {
|
||||
if (NULL != fdn) fdevent_fdnode_event_setter(ev, fdn, (fdn->events&~event));
|
||||
}
|
||||
|
||||
void fdevent_setfd_cloexec(int fd) {
|
||||
#ifdef FD_CLOEXEC
|
||||
if (fd < 0) return;
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
#include "first.h"
|
||||
|
||||
#include "fdevent_impl.h"
|
||||
#include "fdevent.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
__attribute_malloc__
|
||||
__attribute_returns_nonnull__
|
||||
static fdnode *
|
||||
fdnode_init (void)
|
||||
{
|
||||
fdnode * const restrict fdn = calloc(1, sizeof(fdnode));
|
||||
force_assert(NULL != fdn);
|
||||
return fdn;
|
||||
}
|
||||
|
||||
static void
|
||||
fdnode_free (fdnode *fdn)
|
||||
{
|
||||
free(fdn);
|
||||
}
|
||||
|
||||
fdnode *
|
||||
fdevent_register (fdevents *ev, int fd, fdevent_handler handler, void *ctx)
|
||||
{
|
||||
fdnode *fdn = ev->fdarray[fd] = fdnode_init();
|
||||
fdn->handler = handler;
|
||||
fdn->fd = fd;
|
||||
fdn->ctx = ctx;
|
||||
fdn->events = 0;
|
||||
fdn->fde_ndx = -1;
|
||||
#ifdef FDEVENT_USE_LIBEV
|
||||
fdn->handler_ctx = NULL;
|
||||
#endif
|
||||
return fdn;
|
||||
}
|
||||
|
||||
void
|
||||
fdevent_unregister (fdevents *ev, int fd)
|
||||
{
|
||||
fdnode *fdn = ev->fdarray[fd];
|
||||
if ((uintptr_t)fdn & 0x3) return; /*(should not happen)*/
|
||||
ev->fdarray[fd] = NULL;
|
||||
fdnode_free(fdn);
|
||||
}
|
||||
|
||||
void
|
||||
fdevent_sched_close (fdevents *ev, int fd, int issock)
|
||||
{
|
||||
fdnode *fdn = ev->fdarray[fd];
|
||||
if ((uintptr_t)fdn & 0x3) return;
|
||||
ev->fdarray[fd] = (fdnode *)((uintptr_t)fdn | (issock ? 0x1 : 0x2));
|
||||
fdn->handler = (fdevent_handler)NULL;
|
||||
fdn->ctx = ev->pendclose;
|
||||
ev->pendclose = fdn;
|
||||
}
|
||||
|
||||
__attribute_cold__
|
||||
__attribute_noinline__
|
||||
static int
|
||||
fdevent_fdnode_event_unsetter_retry (fdevents *ev, fdnode *fdn)
|
||||
{
|
||||
do {
|
||||
switch (errno) {
|
||||
#ifdef EWOULDBLOCK
|
||||
#if EAGAIN != EWOULDBLOCK
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
#endif
|
||||
case EAGAIN:
|
||||
case EINTR:
|
||||
/* temporary error; retry */
|
||||
break;
|
||||
/*case ENOMEM:*/
|
||||
default:
|
||||
/* unrecoverable error; might leak fd */
|
||||
log_perror(ev->errh, __FILE__, __LINE__,
|
||||
"fdevent event_del failed on fd %d", fdn->fd);
|
||||
return 0;
|
||||
}
|
||||
} while (0 != ev->event_del(ev, fdn));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
fdevent_fdnode_event_unsetter (fdevents *ev, fdnode *fdn)
|
||||
{
|
||||
if (-1 == fdn->fde_ndx) return;
|
||||
if (0 != ev->event_del(ev, fdn))
|
||||
fdevent_fdnode_event_unsetter_retry(ev, fdn);
|
||||
fdn->fde_ndx = -1;
|
||||
fdn->events = 0;
|
||||
}
|
||||
|
||||
__attribute_cold__
|
||||
__attribute_noinline__
|
||||
static int
|
||||
fdevent_fdnode_event_setter_retry (fdevents *ev, fdnode *fdn, int events)
|
||||
{
|
||||
do {
|
||||
switch (errno) {
|
||||
#ifdef EWOULDBLOCK
|
||||
#if EAGAIN != EWOULDBLOCK
|
||||
case EWOULDBLOCK:
|
||||
#endif
|
||||
#endif
|
||||
case EAGAIN:
|
||||
case EINTR:
|
||||
/* temporary error; retry */
|
||||
break;
|
||||
/*case ENOMEM:*/
|
||||
default:
|
||||
/* unrecoverable error */
|
||||
log_perror(ev->errh, __FILE__, __LINE__,
|
||||
"fdevent event_set failed on fd %d", fdn->fd);
|
||||
return 0;
|
||||
}
|
||||
} while (0 != ev->event_set(ev, fdn, events));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
fdevent_fdnode_event_setter (fdevents *ev, fdnode *fdn, int events)
|
||||
{
|
||||
/*(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 (fdn->events == events) return;/*(no change; nothing to do)*/
|
||||
|
||||
if (0 == ev->event_set(ev, fdn, events)
|
||||
|| fdevent_fdnode_event_setter_retry(ev, fdn, events))
|
||||
fdn->events = events;
|
||||
}
|
||||
|
||||
void
|
||||
fdevent_fdnode_event_del (fdevents *ev, fdnode *fdn)
|
||||
{
|
||||
if (NULL != fdn) fdevent_fdnode_event_unsetter(ev, fdn);
|
||||
}
|
||||
|
||||
void
|
||||
fdevent_fdnode_event_set (fdevents *ev, fdnode *fdn, int events)
|
||||
{
|
||||
if (NULL != fdn) fdevent_fdnode_event_setter(ev, fdn, events);
|
||||
}
|
||||
|
||||
void
|
||||
fdevent_fdnode_event_add (fdevents *ev, fdnode *fdn, int event)
|
||||
{
|
||||
if (NULL != fdn) fdevent_fdnode_event_setter(ev, fdn, (fdn->events|event));
|
||||
}
|
||||
|
||||
void
|
||||
fdevent_fdnode_event_clr (fdevents *ev, fdnode *fdn, int event)
|
||||
{
|
||||
if (NULL != fdn) fdevent_fdnode_event_setter(ev, fdn, (fdn->events&~event));
|
||||
}
|
|
@ -728,6 +728,7 @@ common_src = [
|
|||
'configfile-glue.c',
|
||||
'http_etag.c',
|
||||
'fdevent.c',
|
||||
'fdevent_fdnode.c',
|
||||
'fdlog_maint.c',
|
||||
'fdlog.c',
|
||||
'gw_backend.c',
|
||||
|
@ -967,6 +968,7 @@ test('test_mod_indexfile', executable('test_mod_indexfile',
|
|||
'fdlog.c',
|
||||
'sock_addr.c',
|
||||
'stat_cache.c',
|
||||
'fdevent_fdnode.c',
|
||||
'algo_splaytree.c',
|
||||
'ck.c'
|
||||
],
|
||||
|
@ -1013,6 +1015,7 @@ test('test_mod_ssi', executable('test_mod_ssi',
|
|||
'fdlog.c',
|
||||
'sock_addr.c',
|
||||
'stat_cache.c',
|
||||
'fdevent_fdnode.c',
|
||||
'algo_splaytree.c',
|
||||
'ck.c'
|
||||
],
|
||||
|
@ -1046,6 +1049,7 @@ test('test_mod_staticfile', executable('test_mod_staticfile',
|
|||
'fdlog.c',
|
||||
'sock_addr.c',
|
||||
'stat_cache.c',
|
||||
'fdevent_fdnode.c',
|
||||
'algo_splaytree.c',
|
||||
'ck.c'
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue