xref: /f-stack/app/nginx-1.16.1/src/event/ngx_event.h (revision 3da8d17d)
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 
21 typedef struct {
22     WSAOVERLAPPED    ovlp;
23     ngx_event_t     *event;
24     int              error;
25 } ngx_event_ovlp_t;
26 
27 #endif
28 
29 
30 struct 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) || (NGX_HAVE_FSTACK)
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) || (NGX_HAVE_FSTACK)
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 #if (NGX_HAVE_FSTACK)
147     unsigned        belong_to_host:1;
148 #endif
149 };
150 
151 
152 #if (NGX_HAVE_FILE_AIO)
153 
154 struct ngx_event_aio_s {
155     void                      *data;
156     ngx_event_handler_pt       handler;
157     ngx_file_t                *file;
158 
159     ngx_fd_t                   fd;
160 
161 #if (NGX_HAVE_AIO_SENDFILE || NGX_COMPAT)
162     ssize_t                  (*preload_handler)(ngx_buf_t *file);
163 #endif
164 
165 #if (NGX_HAVE_EVENTFD)
166     int64_t                    res;
167 #endif
168 
169 #if !(NGX_HAVE_EVENTFD) || (NGX_TEST_BUILD_EPOLL)
170     ngx_err_t                  err;
171     size_t                     nbytes;
172 #endif
173 
174     ngx_aiocb_t                aiocb;
175     ngx_event_t                event;
176 };
177 
178 #endif
179 
180 
181 typedef struct {
182     ngx_int_t  (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
183     ngx_int_t  (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
184 
185     ngx_int_t  (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
186     ngx_int_t  (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
187 
188     ngx_int_t  (*add_conn)(ngx_connection_t *c);
189     ngx_int_t  (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);
190 
191     ngx_int_t  (*notify)(ngx_event_handler_pt handler);
192 
193     ngx_int_t  (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
194                                  ngx_uint_t flags);
195 
196     ngx_int_t  (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
197     void       (*done)(ngx_cycle_t *cycle);
198 } ngx_event_actions_t;
199 
200 
201 extern ngx_event_actions_t   ngx_event_actions;
202 #if (NGX_HAVE_EPOLLRDHUP)
203 extern ngx_uint_t            ngx_use_epoll_rdhup;
204 #endif
205 #if (NGX_HAVE_FSTACK)
206 extern ngx_event_actions_t   ngx_ff_host_event_actions;
207 #endif
208 
209 
210 /*
211  * The event filter requires to read/write the whole data:
212  * select, poll, /dev/poll, kqueue, epoll.
213  */
214 #define NGX_USE_LEVEL_EVENT      0x00000001
215 
216 /*
217  * The event filter is deleted after a notification without an additional
218  * syscall: kqueue, epoll.
219  */
220 #define NGX_USE_ONESHOT_EVENT    0x00000002
221 
222 /*
223  * The event filter notifies only the changes and an initial level:
224  * kqueue, epoll.
225  */
226 #define NGX_USE_CLEAR_EVENT      0x00000004
227 
228 /*
229  * The event filter has kqueue features: the eof flag, errno,
230  * available data, etc.
231  */
232 #define NGX_USE_KQUEUE_EVENT     0x00000008
233 
234 /*
235  * The event filter supports low water mark: kqueue's NOTE_LOWAT.
236  * kqueue in FreeBSD 4.1-4.2 has no NOTE_LOWAT so we need a separate flag.
237  */
238 #define NGX_USE_LOWAT_EVENT      0x00000010
239 
240 /*
241  * The event filter requires to do i/o operation until EAGAIN: epoll.
242  */
243 #define NGX_USE_GREEDY_EVENT     0x00000020
244 
245 /*
246  * The event filter is epoll.
247  */
248 #define NGX_USE_EPOLL_EVENT      0x00000040
249 
250 /*
251  * Obsolete.
252  */
253 #define NGX_USE_RTSIG_EVENT      0x00000080
254 
255 /*
256  * Obsolete.
257  */
258 #define NGX_USE_AIO_EVENT        0x00000100
259 
260 /*
261  * Need to add socket or handle only once: i/o completion port.
262  */
263 #define NGX_USE_IOCP_EVENT       0x00000200
264 
265 /*
266  * The event filter has no opaque data and requires file descriptors table:
267  * poll, /dev/poll.
268  */
269 #define NGX_USE_FD_EVENT         0x00000400
270 
271 /*
272  * The event module handles periodic or absolute timer event by itself:
273  * kqueue in FreeBSD 4.4, NetBSD 2.0, and MacOSX 10.4, Solaris 10's event ports.
274  */
275 #define NGX_USE_TIMER_EVENT      0x00000800
276 
277 /*
278  * All event filters on file descriptor are deleted after a notification:
279  * Solaris 10's event ports.
280  */
281 #define NGX_USE_EVENTPORT_EVENT  0x00001000
282 
283 /*
284  * The event filter support vnode notifications: kqueue.
285  */
286 #define NGX_USE_VNODE_EVENT      0x00002000
287 
288 
289 /*
290  * The event filter is deleted just before the closing file.
291  * Has no meaning for select and poll.
292  * kqueue, epoll, eventport:         allows to avoid explicit delete,
293  *                                   because filter automatically is deleted
294  *                                   on file close,
295  *
296  * /dev/poll:                        we need to flush POLLREMOVE event
297  *                                   before closing file.
298  */
299 #define NGX_CLOSE_EVENT    1
300 
301 /*
302  * disable temporarily event filter, this may avoid locks
303  * in kernel malloc()/free(): kqueue.
304  */
305 #define NGX_DISABLE_EVENT  2
306 
307 /*
308  * event must be passed to kernel right now, do not wait until batch processing.
309  */
310 #define NGX_FLUSH_EVENT    4
311 
312 
313 /* these flags have a meaning only for kqueue */
314 #define NGX_LOWAT_EVENT    0
315 #define NGX_VNODE_EVENT    0
316 
317 
318 #if (NGX_HAVE_EPOLL) && !(NGX_HAVE_EPOLLRDHUP)
319 #define EPOLLRDHUP         0
320 #endif
321 
322 
323 #if (NGX_HAVE_KQUEUE) || (NGX_HAVE_FSTACK)
324 
325 #define NGX_READ_EVENT     EVFILT_READ
326 #define NGX_WRITE_EVENT    EVFILT_WRITE
327 
328 #undef  NGX_VNODE_EVENT
329 #define NGX_VNODE_EVENT    EVFILT_VNODE
330 
331 /*
332  * NGX_CLOSE_EVENT, NGX_LOWAT_EVENT, and NGX_FLUSH_EVENT are the module flags
333  * and they must not go into a kernel so we need to choose the value
334  * that must not interfere with any existent and future kqueue flags.
335  * kqueue has such values - EV_FLAG1, EV_EOF, and EV_ERROR:
336  * they are reserved and cleared on a kernel entrance.
337  */
338 #undef  NGX_CLOSE_EVENT
339 #define NGX_CLOSE_EVENT    EV_EOF
340 
341 #undef  NGX_LOWAT_EVENT
342 #define NGX_LOWAT_EVENT    EV_FLAG1
343 
344 #undef  NGX_FLUSH_EVENT
345 #define NGX_FLUSH_EVENT    EV_ERROR
346 
347 #define NGX_LEVEL_EVENT    0
348 #define NGX_ONESHOT_EVENT  EV_ONESHOT
349 #define NGX_CLEAR_EVENT    EV_CLEAR
350 
351 #undef  NGX_DISABLE_EVENT
352 #define NGX_DISABLE_EVENT  EV_DISABLE
353 
354 
355 #elif (NGX_HAVE_DEVPOLL && !(NGX_TEST_BUILD_DEVPOLL)) \
356       || (NGX_HAVE_EVENTPORT && !(NGX_TEST_BUILD_EVENTPORT))
357 
358 #define NGX_READ_EVENT     POLLIN
359 #define NGX_WRITE_EVENT    POLLOUT
360 
361 #define NGX_LEVEL_EVENT    0
362 #define NGX_ONESHOT_EVENT  1
363 
364 
365 #elif (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
366 
367 #define NGX_READ_EVENT     (EPOLLIN|EPOLLRDHUP)
368 #define NGX_WRITE_EVENT    EPOLLOUT
369 
370 #define NGX_LEVEL_EVENT    0
371 #define NGX_CLEAR_EVENT    EPOLLET
372 #define NGX_ONESHOT_EVENT  0x70000000
373 #if 0
374 #define NGX_ONESHOT_EVENT  EPOLLONESHOT
375 #endif
376 
377 #if (NGX_HAVE_EPOLLEXCLUSIVE)
378 #define NGX_EXCLUSIVE_EVENT  EPOLLEXCLUSIVE
379 #endif
380 
381 #elif (NGX_HAVE_POLL)
382 
383 #define NGX_READ_EVENT     POLLIN
384 #define NGX_WRITE_EVENT    POLLOUT
385 
386 #define NGX_LEVEL_EVENT    0
387 #define NGX_ONESHOT_EVENT  1
388 
389 
390 #else /* select */
391 
392 #define NGX_READ_EVENT     0
393 #define NGX_WRITE_EVENT    1
394 
395 #define NGX_LEVEL_EVENT    0
396 #define NGX_ONESHOT_EVENT  1
397 
398 #endif /* NGX_HAVE_KQUEUE */
399 
400 
401 #if (NGX_HAVE_IOCP)
402 #define NGX_IOCP_ACCEPT      0
403 #define NGX_IOCP_IO          1
404 #define NGX_IOCP_CONNECT     2
405 #endif
406 
407 
408 #if (NGX_TEST_BUILD_EPOLL)
409 #define NGX_EXCLUSIVE_EVENT  0
410 #endif
411 
412 
413 #ifndef NGX_CLEAR_EVENT
414 #define NGX_CLEAR_EVENT    0    /* dummy declaration */
415 #endif
416 
417 #if (NGX_HAVE_FSTACK)
418 
419 static inline ngx_int_t
ngx_add_event(ngx_event_t * ev,ngx_int_t event,ngx_uint_t flags)420 ngx_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) {
421     if (1 == ev->belong_to_host) {
422         return ngx_ff_host_event_actions.add(ev, event, flags);
423     } else {
424         return ngx_event_actions.add(ev, event, flags);
425     }
426 }
427 
428 static inline ngx_int_t
ngx_del_event(ngx_event_t * ev,ngx_int_t event,ngx_uint_t flags)429 ngx_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) {
430     if (1 == ev->belong_to_host) {
431         return ngx_ff_host_event_actions.del(ev, event, flags);
432     } else {
433         return ngx_event_actions.del(ev, event, flags);
434     }
435 }
436 
ngx_add_conn(ngx_connection_t * c)437 static inline ngx_int_t ngx_add_conn(ngx_connection_t *c)
438 {
439     return ngx_event_actions.add_conn(c);
440 }
441 
ngx_del_conn(ngx_connection_t * c,ngx_uint_t flags)442 static inline ngx_int_t ngx_del_conn(
443     ngx_connection_t *c, ngx_uint_t flags) {
444     return ngx_event_actions.del_conn(c, flags);
445 }
446 
ngx_notify(ngx_event_handler_pt handler)447 static inline ngx_int_t ngx_notify(ngx_event_handler_pt handler) {
448     return ngx_event_actions.notify(handler);
449 }
450 
ngx_process_events(ngx_cycle_t * cycle,ngx_msec_t timer,ngx_uint_t flags)451 static inline ngx_int_t ngx_process_events(
452     ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
453 {
454     return ngx_event_actions.process_events(cycle, timer, flags);
455 }
456 
457 #define ngx_ff_process_host_events   ngx_ff_host_event_actions.process_events
458 
459 #else
460 
461 #define ngx_process_events   ngx_event_actions.process_events
462 #define ngx_done_events      ngx_event_actions.done
463 
464 #define ngx_add_event        ngx_event_actions.add
465 #define ngx_del_event        ngx_event_actions.del
466 #define ngx_add_conn         ngx_event_actions.add_conn
467 #define ngx_del_conn         ngx_event_actions.del_conn
468 
469 #define ngx_notify           ngx_event_actions.notify
470 
471 #endif /* NGX_HAVE_FSTACK */
472 
473 #define ngx_add_timer        ngx_event_add_timer
474 #define ngx_del_timer        ngx_event_del_timer
475 
476 
477 extern ngx_os_io_t  ngx_io;
478 
479 #define ngx_recv             ngx_io.recv
480 #define ngx_recv_chain       ngx_io.recv_chain
481 #define ngx_udp_recv         ngx_io.udp_recv
482 #define ngx_send             ngx_io.send
483 #define ngx_send_chain       ngx_io.send_chain
484 #define ngx_udp_send         ngx_io.udp_send
485 #define ngx_udp_send_chain   ngx_io.udp_send_chain
486 
487 
488 #define NGX_EVENT_MODULE      0x544E5645  /* "EVNT" */
489 #define NGX_EVENT_CONF        0x02000000
490 
491 
492 typedef struct {
493     ngx_uint_t    connections;
494     ngx_uint_t    use;
495 
496     ngx_flag_t    multi_accept;
497     ngx_flag_t    accept_mutex;
498 
499     ngx_msec_t    accept_mutex_delay;
500 
501     u_char       *name;
502 
503 #if (NGX_DEBUG)
504     ngx_array_t   debug_connection;
505 #endif
506 } ngx_event_conf_t;
507 
508 
509 typedef struct {
510     ngx_str_t              *name;
511 
512     void                 *(*create_conf)(ngx_cycle_t *cycle);
513     char                 *(*init_conf)(ngx_cycle_t *cycle, void *conf);
514 
515     ngx_event_actions_t     actions;
516 } ngx_event_module_t;
517 
518 
519 extern ngx_atomic_t          *ngx_connection_counter;
520 
521 extern ngx_atomic_t          *ngx_accept_mutex_ptr;
522 extern ngx_shmtx_t            ngx_accept_mutex;
523 extern ngx_uint_t             ngx_use_accept_mutex;
524 extern ngx_uint_t             ngx_accept_events;
525 extern ngx_uint_t             ngx_accept_mutex_held;
526 extern ngx_msec_t             ngx_accept_mutex_delay;
527 extern ngx_int_t              ngx_accept_disabled;
528 
529 
530 #if (NGX_STAT_STUB)
531 
532 extern ngx_atomic_t  *ngx_stat_accepted;
533 extern ngx_atomic_t  *ngx_stat_handled;
534 extern ngx_atomic_t  *ngx_stat_requests;
535 extern ngx_atomic_t  *ngx_stat_active;
536 extern ngx_atomic_t  *ngx_stat_reading;
537 extern ngx_atomic_t  *ngx_stat_writing;
538 extern ngx_atomic_t  *ngx_stat_waiting;
539 
540 #endif
541 
542 
543 #define NGX_UPDATE_TIME         1
544 #define NGX_POST_EVENTS         2
545 
546 
547 extern sig_atomic_t           ngx_event_timer_alarm;
548 extern ngx_uint_t             ngx_event_flags;
549 extern ngx_module_t           ngx_events_module;
550 extern ngx_module_t           ngx_event_core_module;
551 
552 
553 #define ngx_event_get_conf(conf_ctx, module)                                  \
554              (*(ngx_get_conf(conf_ctx, ngx_events_module))) [module.ctx_index]
555 
556 
557 
558 void ngx_event_accept(ngx_event_t *ev);
559 #if !(NGX_WIN32)
560 void ngx_event_recvmsg(ngx_event_t *ev);
561 void ngx_udp_rbtree_insert_value(ngx_rbtree_node_t *temp,
562     ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
563 #endif
564 void ngx_delete_udp_connection(void *data);
565 ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle);
566 ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
567 u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len);
568 #if (NGX_DEBUG)
569 void ngx_debug_accepted_connection(ngx_event_conf_t *ecf, ngx_connection_t *c);
570 #endif
571 
572 
573 void ngx_process_events_and_timers(ngx_cycle_t *cycle);
574 ngx_int_t ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags);
575 ngx_int_t ngx_handle_write_event(ngx_event_t *wev, size_t lowat);
576 
577 
578 #if (NGX_WIN32)
579 void ngx_event_acceptex(ngx_event_t *ev);
580 ngx_int_t ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n);
581 u_char *ngx_acceptex_log_error(ngx_log_t *log, u_char *buf, size_t len);
582 #endif
583 
584 
585 ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat);
586 
587 
588 /* used in ngx_log_debugX() */
589 #define ngx_event_ident(p)  ((ngx_connection_t *) (p))->fd
590 
591 
592 #include <ngx_event_timer.h>
593 #include <ngx_event_posted.h>
594 
595 #if (NGX_WIN32)
596 #include <ngx_iocp_module.h>
597 #endif
598 
599 
600 #endif /* _NGX_EVENT_H_INCLUDED_ */
601