[core] fdevent_fdnode.c separate from fdevent.c

This commit is contained in:
Glenn Strauss 2021-11-01 20:07:06 -04:00
parent 7113dcb49b
commit 0f51b3728a
6 changed files with 176 additions and 134 deletions

View File

@ -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
)

View File

@ -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

View File

@ -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 \

View File

@ -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;

162
src/fdevent_fdnode.c Normal file
View File

@ -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));
}

View File

@ -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'
],