Mercurial > hg > nginx-vendor-0-6
diff src/event/modules/ngx_aio_module.c @ 0:f0b350454894 NGINX_0_1_0
nginx 0.1.0
*) The first public version.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 04 Oct 2004 00:00:00 +0400 |
parents | |
children | 46833bd150cb |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/src/event/modules/ngx_aio_module.c @@ -0,0 +1,209 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_event.h> +#include <ngx_aio.h> + +#if (HAVE_KQUEUE) +#include <ngx_kqueue_module.h> +#endif + + +static int ngx_aio_init(ngx_cycle_t *cycle); +static void ngx_aio_done(ngx_cycle_t *cycle); +static int ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags); +static int ngx_aio_del_connection(ngx_connection_t *c, u_int flags); +static int ngx_aio_process_events(ngx_cycle_t *cycle); + + +ngx_os_io_t ngx_os_aio = { + ngx_aio_read, + ngx_aio_read_chain, + ngx_aio_write, + ngx_aio_write_chain, + NGX_HAVE_ZEROCOPY +}; + + +static ngx_str_t aio_name = ngx_string("aio"); + +ngx_event_module_t ngx_aio_module_ctx = { + &aio_name, + NULL, /* create configuration */ + NULL, /* init configuration */ + + { + ngx_aio_add_event, /* add an event */ + ngx_aio_del_event, /* delete an event */ + NULL, /* enable an event */ + NULL, /* disable an event */ + NULL, /* add an connection */ + ngx_aio_del_connection, /* delete an connection */ + NULL, /* process the changes */ + ngx_aio_process_events, /* process the events */ + ngx_aio_init, /* init the events */ + ngx_aio_done /* done the events */ + } + +}; + +ngx_module_t ngx_aio_module = { + NGX_MODULE, + &ngx_aio_module_ctx, /* module context */ + NULL, /* module directives */ + NGX_EVENT_MODULE, /* module type */ + NULL, /* init module */ + NULL /* init process */ +}; + + + +#if (HAVE_KQUEUE) + +static int ngx_aio_init(ngx_cycle_t *cycle) +{ + if (ngx_kqueue_module_ctx.actions.init(cycle) == NGX_ERROR) { + return NGX_ERROR; + } + + ngx_io = ngx_os_aio; + + ngx_event_flags = NGX_USE_AIO_EVENT; + ngx_event_actions = ngx_aio_module_ctx.actions; + + + return NGX_OK; +} + + +static void ngx_aio_done(ngx_cycle_t *cycle) +{ + ngx_kqueue_module_ctx.actions.done(cycle); +} + + +/* The event adding and deleting are needed for the listening sockets */ + +static int ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags) +{ + return ngx_kqueue_module_ctx.actions.add(ev, event, flags); +} + + +static int ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags) +{ + return ngx_kqueue_module_ctx.actions.del(ev, event, flags); +} + + +static int ngx_aio_del_connection(ngx_connection_t *c, u_int flags) +{ + int rc; + + if (c->read->active == 0 && c->write->active == 0) { + return NGX_OK; + } + + rc = aio_cancel(c->fd, NULL); + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "aio_cancel: %d", rc); + + if (rc == AIO_CANCELED) { + c->read->active = c->write->active = 0; + return NGX_OK; + } + + if (rc == AIO_ALLDONE) { + c->read->active = c->write->active = 0; + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "aio_cancel() returned AIO_ALLDONE"); + return NGX_OK; + } + + if (rc == -1) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, + "aio_cancel() failed"); + return NGX_ERROR; + } + + if (rc == AIO_NOTCANCELED) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "aio_cancel() returned AIO_NOTCANCELED"); + + return NGX_ERROR; + } + + return NGX_OK; +} + + +static int ngx_aio_process_events(ngx_cycle_t *cycle) +{ + return ngx_kqueue_module_ctx.actions.process_events(cycle); +} + +#endif /* HAVE_KQUEUE */ + + +#if 0 + +/* 1 */ +int ngx_posix_aio_process_events(ngx_log_t *log) +{ + listen via SIGIO; + aio_* via SIGxxx; + + sigsuspend()/sigwaitinfo()/sigtimedwait(); +} + +/* 2 */ +int ngx_posix_aio_process_events(ngx_log_t *log) +{ + unmask signal + + listen via SIGIO; + + /* BUG: SIGIO can be delivered before aio_*() */ + + aio_suspend()/aiowait()/aio_waitcomplete() with timeout + + mask signal + + if (ngx_socket_errno == NGX_EINTR) + look listen + select()/accept() nb listen sockets + else + aio +} + +/* 3 */ +int ngx_posix_aio_process_events(ngx_log_t *log) +{ +#if 0 + unmask signal + + /* BUG: AIO signal can be delivered before select() */ + + select(listen); + + mask signal +#endif + + pselect(listen, mask); + + if (ngx_socket_errno == NGX_EINTR) + look ready array +} + +void aio_sig_handler(int signo, siginfo_t *siginfo, void *context) +{ + push siginfo->si_value.sival_ptr +} + +#endif