1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
5 */
6
7
8#ifndef _NGX_EVENT_H_INCLUDED_
9#define _NGX_EVENT_H_INCLUDED_
10
11
12#include <ngx_config.h>
13#include <ngx_core.h>
14
15
16#define NGX_INVALID_INDEX  0xd0d0d0d0
17
18
19#if (NGX_HAVE_IOCP)
20
21typedef struct {
22    WSAOVERLAPPED    ovlp;
23    ngx_event_t     *event;
24    int              error;
25} ngx_event_ovlp_t;
26
27#endif
28
29
30struct ngx_event_s {
31    void            *data;
32
33    unsigned         write:1;
34
35    unsigned         accept:1;
36
37    /* used to detect the stale events in kqueue and epoll */
38    unsigned         instance:1;
39
40    /*
41     * the event was passed or would be passed to a kernel;
42     * in aio mode - operation was posted.
43     */
44    unsigned         active:1;
45
46    unsigned         disabled:1;
47
48    /* the ready event; in aio mode 0 means that no operation can be posted */
49    unsigned         ready:1;
50
51    unsigned         oneshot:1;
52
53    /* aio operation is complete */
54    unsigned         complete:1;
55
56    unsigned         eof:1;
57    unsigned         error:1;
58
59    unsigned         timedout:1;
60    unsigned         timer_set:1;
61
62    unsigned         delayed:1;
63
64    unsigned         deferred_accept:1;
65
66    /* the pending eof reported by kqueue, epoll or in aio chain operation */
67    unsigned         pending_eof:1;
68
69    unsigned         posted:1;
70
71    unsigned         closed:1;
72
73    /* to test on worker exit */
74    unsigned         channel:1;
75    unsigned         resolver:1;
76
77    unsigned         cancelable:1;
78
79#if (NGX_HAVE_KQUEUE)
80    unsigned         kq_vnode:1;
81
82    /* the pending errno reported by kqueue */
83    int              kq_errno;
84#endif
85
86    /*
87     * kqueue only:
88     *   accept:     number of sockets that wait to be accepted
89     *   read:       bytes to read when event is ready
90     *               or lowat when event is set with NGX_LOWAT_EVENT flag
91     *   write:      available space in buffer when event is ready
92     *               or lowat when event is set with NGX_LOWAT_EVENT flag
93     *
94     * epoll with EPOLLRDHUP:
95     *   accept:     1 if accept many, 0 otherwise
96     *   read:       1 if there can be data to read, 0 otherwise
97     *
98     * iocp: TODO
99     *
100     * otherwise:
101     *   accept:     1 if accept many, 0 otherwise
102     */
103
104#if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP)
105    int              available;
106#else
107    unsigned         available:1;
108#endif
109
110    ngx_event_handler_pt  handler;
111
112
113#if (NGX_HAVE_IOCP)
114    ngx_event_ovlp_t ovlp;
115#endif
116
117    ngx_uint_t       index;
118
119    ngx_log_t       *log;
120
121    ngx_rbtree_node_t   timer;
122
123    /* the posted queue */
124    ngx_queue_t      queue;
125
126#if 0
127
128    /* the threads support */
129
130    /*
131     * the event thread context, we store it here
132     * if $(CC) does not understand __thread declaration
133     * and pthread_getspecific() is too costly
134     */
135
136    void            *thr_ctx;
137
138#if (NGX_EVENT_T_PADDING)
139
140    /* event should not cross cache line in SMP */
141
142    uint32_t         padding[NGX_EVENT_T_PADDING];
143#endif
144#endif
145};
146
147
148#if (NGX_HAVE_FILE_AIO)
149
150struct ngx_event_aio_s {
151    void                      *data;
152    ngx_event_handler_pt       handler;
153    ngx_file_t                *file;
154
155#if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT)
156    ssize_t                  (*preload_handler)(ngx_buf_t *file);
157#endif
158
159    ngx_fd_t                   fd;
160
161#if (NGX_HAVE_EVENTFD)
162    int64_t                    res;
163#endif
164
165#if !(NGX_HAVE_EVENTFD) || (NGX_TEST_BUILD_EPOLL)
166    ngx_err_t                  err;
167    size_t                     nbytes;
168#endif
169
170    ngx_aiocb_t                aiocb;
171    ngx_event_t                event;
172};
173
174#endif
175
176
177typedef struct {
178    ngx_int_t  (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
179    ngx_int_t  (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
180
181    ngx_int_t  (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
182    ngx_int_t  (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
183
184    ngx_int_t  (*add_conn)(ngx_connection_t *c);
185    ngx_int_t  (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);
186
187    ngx_int_t  (*notify)(ngx_event_handler_pt handler);
188
189    ngx_int_t  (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
190                                 ngx_uint_t flags);
191
192    ngx_int_t  (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
193    void       (*done)(ngx_cycle_t *cycle);
194} ngx_event_actions_t;
195
196
197extern ngx_event_actions_t   ngx_event_actions;
198#if (NGX_HAVE_EPOLLRDHUP)
199extern ngx_uint_t            ngx_use_epoll_rdhup;
200#endif
201
202
203/*
204 * The event filter requires to read/write the whole data:
205 * select, poll, /dev/poll, kqueue, epoll.
206 */
207#define NGX_USE_LEVEL_EVENT      0x00000001
208
209/*
210 * The event filter is deleted after a notification without an additional
211 * syscall: kqueue, epoll.
212 */
213#define NGX_USE_ONESHOT_EVENT    0x00000002
214
215/*
216 * The event filter notifies only the changes and an initial level:
217 * kqueue, epoll.
218 */
219#define NGX_USE_CLEAR_EVENT      0x00000004
220
221/*
222 * The event filter has kqueue features: the eof flag, errno,
223 * available data, etc.
224 */
225#define NGX_USE_KQUEUE_EVENT     0x00000008
226
227/*
228 * The event filter supports low water mark: kqueue's NOTE_LOWAT.
229 * kqueue in FreeBSD 4.1-4.2 has no NOTE_LOWAT so we need a separate flag.
230 */
231#define NGX_USE_LOWAT_EVENT      0x00000010
232
233/*
234 * The event filter requires to do i/o operation until EAGAIN: epoll.
235 */
236#define NGX_USE_GREEDY_EVENT     0x00000020
237
238/*
239 * The event filter is epoll.
240 */
241#define NGX_USE_EPOLL_EVENT      0x00000040
242
243/*
244 * Obsolete.
245 */
246#define NGX_USE_RTSIG_EVENT      0x00000080
247
248/*
249 * Obsolete.
250 */
251#define NGX_USE_AIO_EVENT        0x00000100
252
253/*
254 * Need to add socket or handle only once: i/o completion port.
255 */
256#define NGX_USE_IOCP_EVENT       0x00000200
257
258/*
259 * The event filter has no opaque data and requires file descriptors table:
260 * poll, /dev/poll.
261 */
262#define NGX_USE_FD_EVENT         0x00000400
263
264/*
265 * The event module handles periodic or absolute timer event by itself:
266 * kqueue in FreeBSD 4.4, NetBSD 2.0, and MacOSX 10.4, Solaris 10's event ports.
267 */
268#define NGX_USE_TIMER_EVENT      0x00000800
269
270/*
271 * All event filters on file descriptor are deleted after a notification:
272 * Solaris 10's event ports.
273 */
274#define NGX_USE_EVENTPORT_EVENT  0x00001000
275
276/*
277 * The event filter support vnode notifications: kqueue.
278 */
279#define NGX_USE_VNODE_EVENT      0x00002000
280
281
282/*
283 * The event filter is deleted just before the closing file.
284 * Has no meaning for select and poll.
285 * kqueue, epoll, eventport:         allows to avoid explicit delete,
286 *                                   because filter automatically is deleted
287 *                                   on file close,
288 *
289 * /dev/poll:                        we need to flush POLLREMOVE event
290 *                                   before closing file.
291 */
292#define NGX_CLOSE_EVENT    1
293
294/*
295 * disable temporarily event filter, this may avoid locks
296 * in kernel malloc()/free(): kqueue.
297 */
298#define NGX_DISABLE_EVENT  2
299
300/*
301 * event must be passed to kernel right now, do not wait until batch processing.
302 */
303#define NGX_FLUSH_EVENT    4
304
305
306/* these flags have a meaning only for kqueue */
307#define NGX_LOWAT_EVENT    0
308#define NGX_VNODE_EVENT    0
309
310
311#if (NGX_HAVE_EPOLL) && !(NGX_HAVE_EPOLLRDHUP)
312#define EPOLLRDHUP         0
313#endif
314
315
316#if (NGX_HAVE_KQUEUE)
317
318#define NGX_READ_EVENT     EVFILT_READ
319#define NGX_WRITE_EVENT    EVFILT_WRITE
320
321#undef  NGX_VNODE_EVENT
322#define NGX_VNODE_EVENT    EVFILT_VNODE
323
324/*
325 * NGX_CLOSE_EVENT, NGX_LOWAT_EVENT, and NGX_FLUSH_EVENT are the module flags
326 * and they must not go into a kernel so we need to choose the value
327 * that must not interfere with any existent and future kqueue flags.
328 * kqueue has such values - EV_FLAG1, EV_EOF, and EV_ERROR:
329 * they are reserved and cleared on a kernel entrance.
330 */
331#undef  NGX_CLOSE_EVENT
332#define NGX_CLOSE_EVENT    EV_EOF
333
334#undef  NGX_LOWAT_EVENT
335#define NGX_LOWAT_EVENT    EV_FLAG1
336
337#undef  NGX_FLUSH_EVENT
338#define NGX_FLUSH_EVENT    EV_ERROR
339
340#define NGX_LEVEL_EVENT    0
341#define NGX_ONESHOT_EVENT  EV_ONESHOT
342#define NGX_CLEAR_EVENT    EV_CLEAR
343
344#undef  NGX_DISABLE_EVENT
345#define NGX_DISABLE_EVENT  EV_DISABLE
346
347
348#elif (NGX_HAVE_DEVPOLL && !(NGX_TEST_BUILD_DEVPOLL)) \
349      || (NGX_HAVE_EVENTPORT && !(NGX_TEST_BUILD_EVENTPORT))
350
351#define NGX_READ_EVENT     POLLIN
352#define NGX_WRITE_EVENT    POLLOUT
353
354#define NGX_LEVEL_EVENT    0
355#define NGX_ONESHOT_EVENT  1
356
357
358#elif (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
359
360#define NGX_READ_EVENT     (EPOLLIN|EPOLLRDHUP)
361#define NGX_WRITE_EVENT    EPOLLOUT
362
363#define NGX_LEVEL_EVENT    0
364#define NGX_CLEAR_EVENT    EPOLLET
365#define NGX_ONESHOT_EVENT  0x70000000
366#if 0
367#define NGX_ONESHOT_EVENT  EPOLLONESHOT
368#endif
369
370#if (NGX_HAVE_EPOLLEXCLUSIVE)
371#define NGX_EXCLUSIVE_EVENT  EPOLLEXCLUSIVE
372#endif
373
374#elif (NGX_HAVE_POLL)
375
376#define NGX_READ_EVENT     POLLIN
377#define NGX_WRITE_EVENT    POLLOUT
378
379#define NGX_LEVEL_EVENT    0
380#define NGX_ONESHOT_EVENT  1
381
382
383#else /* select */
384
385#define NGX_READ_EVENT     0
386#define NGX_WRITE_EVENT    1
387
388#define NGX_LEVEL_EVENT    0
389#define NGX_ONESHOT_EVENT  1
390
391#endif /* NGX_HAVE_KQUEUE */
392
393
394#if (NGX_HAVE_IOCP)
395#define NGX_IOCP_ACCEPT      0
396#define NGX_IOCP_IO          1
397#define NGX_IOCP_CONNECT     2
398#endif
399
400
401#if (NGX_TEST_BUILD_EPOLL)
402#define NGX_EXCLUSIVE_EVENT  0
403#endif
404
405
406#ifndef NGX_CLEAR_EVENT
407#define NGX_CLEAR_EVENT    0    /* dummy declaration */
408#endif
409
410
411#define ngx_process_events   ngx_event_actions.process_events
412#define ngx_done_events      ngx_event_actions.done
413
414#define ngx_add_event        ngx_event_actions.add
415#define ngx_del_event        ngx_event_actions.del
416#define ngx_add_conn         ngx_event_actions.add_conn
417#define ngx_del_conn         ngx_event_actions.del_conn
418
419#define ngx_notify           ngx_event_actions.notify
420
421#define ngx_add_timer        ngx_event_add_timer
422#define ngx_del_timer        ngx_event_del_timer
423
424
425extern ngx_os_io_t  ngx_io;
426
427#define ngx_recv             ngx_io.recv
428#define ngx_recv_chain       ngx_io.recv_chain
429#define ngx_udp_recv         ngx_io.udp_recv
430#define ngx_send             ngx_io.send
431#define ngx_send_chain       ngx_io.send_chain
432#define ngx_udp_send         ngx_io.udp_send
433#define ngx_udp_send_chain   ngx_io.udp_send_chain
434
435
436#define NGX_EVENT_MODULE      0x544E5645  /* "EVNT" */
437#define NGX_EVENT_CONF        0x02000000
438
439
440typedef struct {
441    ngx_uint_t    connections;
442    ngx_uint_t    use;
443
444    ngx_flag_t    multi_accept;
445    ngx_flag_t    accept_mutex;
446
447    ngx_msec_t    accept_mutex_delay;
448
449    u_char       *name;
450
451#if (NGX_DEBUG)
452    ngx_array_t   debug_connection;
453#endif
454} ngx_event_conf_t;
455
456
457typedef struct {
458    ngx_str_t              *name;
459
460    void                 *(*create_conf)(ngx_cycle_t *cycle);
461    char                 *(*init_conf)(ngx_cycle_t *cycle, void *conf);
462
463    ngx_event_actions_t     actions;
464} ngx_event_module_t;
465
466
467extern ngx_atomic_t          *ngx_connection_counter;
468
469extern ngx_atomic_t          *ngx_accept_mutex_ptr;
470extern ngx_shmtx_t            ngx_accept_mutex;
471extern ngx_uint_t             ngx_use_accept_mutex;
472extern ngx_uint_t             ngx_accept_events;
473extern ngx_uint_t             ngx_accept_mutex_held;
474extern ngx_msec_t             ngx_accept_mutex_delay;
475extern ngx_int_t              ngx_accept_disabled;
476
477
478#if (NGX_STAT_STUB)
479
480extern ngx_atomic_t  *ngx_stat_accepted;
481extern ngx_atomic_t  *ngx_stat_handled;
482extern ngx_atomic_t  *ngx_stat_requests;
483extern ngx_atomic_t  *ngx_stat_active;
484extern ngx_atomic_t  *ngx_stat_reading;
485extern ngx_atomic_t  *ngx_stat_writing;
486extern ngx_atomic_t  *ngx_stat_waiting;
487
488#endif
489
490
491#define NGX_UPDATE_TIME         1
492#define NGX_POST_EVENTS         2
493
494
495extern sig_atomic_t           ngx_event_timer_alarm;
496extern ngx_uint_t             ngx_event_flags;
497extern ngx_module_t           ngx_events_module;
498extern ngx_module_t           ngx_event_core_module;
499
500
501#define ngx_event_get_conf(conf_ctx, module)                                  \
502             (*(ngx_get_conf(conf_ctx, ngx_events_module))) [module.ctx_index];
503
504
505
506void ngx_event_accept(ngx_event_t *ev);
507#if !(NGX_WIN32)
508void ngx_event_recvmsg(ngx_event_t *ev);
509#endif
510ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle);
511u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len);
512
513
514void ngx_process_events_and_timers(ngx_cycle_t *cycle);
515ngx_int_t ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags);
516ngx_int_t ngx_handle_write_event(ngx_event_t *wev, size_t lowat);
517
518
519#if (NGX_WIN32)
520void ngx_event_acceptex(ngx_event_t *ev);
521ngx_int_t ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n);
522u_char *ngx_acceptex_log_error(ngx_log_t *log, u_char *buf, size_t len);
523#endif
524
525
526ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat);
527
528
529/* used in ngx_log_debugX() */
530#define ngx_event_ident(p)  ((ngx_connection_t *) (p))->fd
531
532
533#include <ngx_event_timer.h>
534#include <ngx_event_posted.h>
535
536#if (NGX_WIN32)
537#include <ngx_iocp_module.h>
538#endif
539
540
541#endif /* _NGX_EVENT_H_INCLUDED_ */
542