46
48
int epoll_create(int size);
50
int epoll_create(int size)
47
56
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
58
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
48
64
int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout);
50
int epoll_create(int size)
55
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
60
66
int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout)
71
#if (NGX_HAVE_FILE_AIO)
73
#define SYS_io_setup 245
74
#define SYS_io_destroy 246
75
#define SYS_io_getevents 247
76
#define SYS_eventfd 323
78
typedef u_int aio_context_t;
81
uint64_t data; /* the data field from the iocb */
82
uint64_t obj; /* what iocb this event came from */
83
int64_t res; /* result code for this event */
84
int64_t res2; /* secondary result */
94
ngx_uint_t aio_requests;
70
95
} ngx_epoll_conf_t;
188
#if (NGX_HAVE_FILE_AIO)
191
* We call io_setup(), io_destroy() io_submit(), and io_getevents() directly
192
* as syscalls instead of libaio usage, because the library header file
193
* supports eventfd() since 0.3.107 version only.
195
* Also we do not use eventfd() in glibc, because glibc supports it
196
* since 2.8 version and glibc maps two syscalls eventfd() and eventfd2()
197
* into single eventfd() function with different number of parameters.
201
io_setup(u_int nr_reqs, aio_context_t *ctx)
203
return syscall(SYS_io_setup, nr_reqs, ctx);
208
io_destroy(aio_context_t ctx)
210
return syscall(SYS_io_destroy, ctx);
215
io_getevents(aio_context_t ctx, long min_nr, long nr, struct io_event *events,
216
struct timespec *tmo)
218
return syscall(SYS_io_getevents, ctx, min_nr, nr, events, tmo);
223
ngx_epoll_aio_init(ngx_cycle_t *cycle, ngx_epoll_conf_t *epcf)
226
struct epoll_event ee;
228
ngx_eventfd = syscall(SYS_eventfd, 0);
230
if (ngx_eventfd == -1) {
231
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
237
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
238
"eventfd: %d", ngx_eventfd);
242
if (ioctl(ngx_eventfd, FIONBIO, &n) == -1) {
243
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
244
"ioctl(eventfd, FIONBIO) failed");
248
if (io_setup(epcf->aio_requests, &ngx_aio_ctx) == -1) {
249
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
250
"io_setup() failed");
254
ngx_eventfd_event.data = &ngx_eventfd_conn;
255
ngx_eventfd_event.handler = ngx_epoll_eventfd_handler;
256
ngx_eventfd_event.log = cycle->log;
257
ngx_eventfd_event.active = 1;
258
ngx_eventfd_conn.fd = ngx_eventfd;
259
ngx_eventfd_conn.read = &ngx_eventfd_event;
260
ngx_eventfd_conn.log = cycle->log;
262
ee.events = EPOLLIN|EPOLLET;
263
ee.data.ptr = &ngx_eventfd_conn;
265
if (epoll_ctl(ep, EPOLL_CTL_ADD, ngx_eventfd, &ee) != -1) {
269
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
270
"epoll_ctl(EPOLL_CTL_ADD, eventfd) failed");
272
if (io_destroy(ngx_aio_ctx) == -1) {
273
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
274
"io_destroy() failed");
279
if (close(ngx_eventfd) == -1) {
280
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
281
"eventfd close() failed");
144
293
ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
146
ngx_event_conf_t *ecf;
147
295
ngx_epoll_conf_t *epcf;
149
ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
151
297
epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module);
154
ep = epoll_create(ecf->connections / 2);
300
ep = epoll_create(cycle->connection_n / 2);
157
303
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
158
304
"epoll_create() failed");
159
305
return NGX_ERROR;
308
#if (NGX_HAVE_FILE_AIO)
310
ngx_epoll_aio_init(cycle, epcf);
163
315
if (nevents < epcf->events) {
470
log = c->log ? c->log : cycle->log;
473
635
revents = event_list[i].events;
475
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0,
637
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
476
638
"epoll: fd:%d ev:%04XD d:%p",
477
639
c->fd, revents, event_list[i].data.ptr);
479
641
if (revents & (EPOLLERR|EPOLLHUP)) {
480
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
642
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
481
643
"epoll_wait() error on fd:%d ev:%04XD",
486
648
if (revents & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) {
487
ngx_log_error(NGX_LOG_ALERT, log, 0,
649
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
488
650
"strange epoll_wait() events fd:%d ev:%04XD",
725
#if (NGX_HAVE_FILE_AIO)
728
ngx_epoll_eventfd_handler(ngx_event_t *ev)
735
ngx_event_aio_t *aio;
736
struct io_event event[64];
739
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "eventfd handler");
741
n = read(ngx_eventfd, &ready, 8);
745
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, "eventfd: %d", n);
749
if (err == NGX_EAGAIN) {
753
ngx_log_error(NGX_LOG_ALERT, ev->log, err, "read(eventfd) failed");
757
ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
758
"read(eventfd) returned only %d bytes", n);
767
events = io_getevents(ngx_aio_ctx, 1, 64, event, &ts);
769
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
770
"io_getevents: %l", events);
775
for (i = 0; i < events; i++) {
777
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ev->log, 0,
778
"io_event: %uXL %uXL %L %L",
779
event[i].data, event[i].obj,
780
event[i].res, event[i].res2);
782
e = (ngx_event_t *) (uintptr_t) event[i].data;
789
aio->res = event[i].res;
791
ngx_post_event(e, &ngx_posted_events);
802
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
803
"io_getevents() failed");
552
812
ngx_epoll_create_conf(ngx_cycle_t *cycle)