comparison src/event/ngx_event.h @ 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 cc9f381affaa
comparison
equal deleted inserted replaced
-1:000000000000 0:f0b350454894
1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #ifndef _NGX_EVENT_H_INCLUDED_
8 #define _NGX_EVENT_H_INCLUDED_
9
10
11 #include <ngx_config.h>
12 #include <ngx_core.h>
13
14
15 #define NGX_INVALID_INDEX 0xd0d0d0d0
16
17
18 #if (HAVE_IOCP)
19
20 typedef struct {
21 WSAOVERLAPPED ovlp;
22 ngx_event_t *event;
23 int error;
24 } ngx_event_ovlp_t;
25
26 #endif
27
28
29 typedef struct {
30 ngx_uint_t lock;
31
32 ngx_event_t *events;
33 ngx_event_t *last;
34 } ngx_event_mutex_t;
35
36
37 struct ngx_event_s {
38 void *data;
39
40 unsigned write:1;
41
42 unsigned accept:1;
43
44 unsigned oneshot:1;
45
46 /* used to detect the stale events in kqueue, rt signals and epoll */
47 unsigned instance:1;
48
49 /*
50 * the event was passed or would be passed to a kernel;
51 * in aio mode - operation was posted.
52 */
53 unsigned active:1;
54
55 unsigned disabled:1;
56
57 /* the ready event; in aio mode 0 means that no operation can be posted */
58 unsigned ready:1;
59
60 /* aio operation is complete */
61 unsigned complete:1;
62
63 unsigned eof:1;
64 unsigned error:1;
65
66 unsigned timedout:1;
67 unsigned timer_set:1;
68
69 unsigned delayed:1;
70
71 unsigned read_discarded:1;
72
73 unsigned unexpected_eof:1;
74
75 unsigned deferred_accept:1;
76
77 /* the pending eof reported by kqueue or in aio chain operation */
78 unsigned pending_eof:1;
79
80 #if !(NGX_THREADS)
81 unsigned posted_ready:1;
82 #endif
83
84 #if (WIN32)
85 /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was succesfull */
86 unsigned accept_context_updated:1;
87 #endif
88
89 #if (HAVE_KQUEUE)
90 unsigned kq_vnode:1;
91
92 /* the pending errno reported by kqueue */
93 int kq_errno;
94 #endif
95
96 /*
97 * kqueue only:
98 * accept: number of sockets that wait to be accepted
99 * read: bytes to read when event is ready
100 * or lowat when event is set with NGX_LOWAT_EVENT flag
101 * write: available space in buffer when event is ready
102 * or lowat when event is set with NGX_LOWAT_EVENT flag
103 *
104 * iocp: TODO
105 *
106 * otherwise:
107 * accept: 1 if accept many, 0 otherwise
108 */
109
110 #if (HAVE_KQUEUE) || (HAVE_IOCP)
111 int available;
112 #else
113 unsigned available:1;
114 #endif
115
116 /* TODO rename to handler */
117 ngx_event_handler_pt event_handler;
118
119
120 #if (HAVE_AIO)
121
122 #if (HAVE_IOCP)
123 ngx_event_ovlp_t ovlp;
124 #else
125 struct aiocb aiocb;
126 #endif
127
128 #endif
129
130 u_int index;
131
132 ngx_log_t *log;
133
134 /* TODO: threads: padding to cache line */
135
136 /*
137 * STUB: The inline of "ngx_rbtree_t rbtree;"
138 */
139
140 ngx_int_t rbtree_key;
141 void *rbtree_left;
142 void *rbtree_right;
143 void *rbtree_parent;
144 char rbtree_color;
145
146
147 unsigned closed:1;
148
149 #if (NGX_THREADS)
150
151 unsigned locked:1;
152
153 unsigned posted_ready:1;
154 unsigned posted_timedout:1;
155 unsigned posted_eof:1;
156
157 #if (HAVE_KQUEUE)
158 /* the pending errno reported by kqueue */
159 int posted_errno;
160 #endif
161
162 #if (HAVE_KQUEUE) || (HAVE_IOCP)
163 int posted_available;
164 #else
165 unsigned posted_available:1;
166 #endif
167
168 ngx_atomic_t *lock;
169 ngx_atomic_t *own_lock;
170
171 #endif
172
173 /* the links of the posted queue */
174 ngx_event_t *next;
175 ngx_event_t **prev;
176
177
178 #if 0
179
180 /* the threads support */
181
182 /*
183 * the event thread context, we store it here
184 * if $(CC) does not understand __thread declaration
185 * and pthread_getspecific() is too costly
186 */
187
188 void *thr_ctx;
189
190 #if (NGX_EVENT_T_PADDING)
191
192 /* event should not cross cache line in SMP */
193
194 int padding[NGX_EVENT_T_PADDING];
195 #endif
196 #endif
197 };
198
199
200 typedef struct {
201 ngx_int_t (*add)(ngx_event_t *ev, int event, u_int flags);
202 ngx_int_t (*del)(ngx_event_t *ev, int event, u_int flags);
203
204 ngx_int_t (*enable)(ngx_event_t *ev, int event, u_int flags);
205 ngx_int_t (*disable)(ngx_event_t *ev, int event, u_int flags);
206
207 ngx_int_t (*add_conn)(ngx_connection_t *c);
208 ngx_int_t (*del_conn)(ngx_connection_t *c, u_int flags);
209
210 ngx_int_t (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t try);
211 ngx_int_t (*process_events)(ngx_cycle_t *cycle);
212
213 ngx_int_t (*init)(ngx_cycle_t *cycle);
214 void (*done)(ngx_cycle_t *cycle);
215 } ngx_event_actions_t;
216
217
218 extern ngx_event_actions_t ngx_event_actions;
219
220
221 /*
222 * The event filter requires to read/write the whole data -
223 * select, poll, /dev/poll, kqueue, epoll.
224 */
225 #define NGX_USE_LEVEL_EVENT 0x00000001
226
227 /*
228 * The event filter is deleted after a notification without an additional
229 * syscall - select, poll, kqueue, epoll, Solaris 10's event ports.
230 */
231 #define NGX_USE_ONESHOT_EVENT 0x00000002
232
233 /*
234 * The event filter notifies only the changes and an initial level -
235 * kqueue, epoll.
236 */
237 #define NGX_USE_CLEAR_EVENT 0x00000004
238
239 /*
240 * The event filter has kqueue features - the eof flag, errno,
241 * available data, etc.
242 */
243 #define NGX_HAVE_KQUEUE_EVENT 0x00000008
244
245 /*
246 * The event filter supports low water mark - kqueue's NOTE_LOWAT.
247 * kqueue in FreeBSD 4.1-4.2 has no NOTE_LOWAT so we need a separate flag.
248 */
249 #define NGX_HAVE_LOWAT_EVENT 0x00000010
250
251 /*
252 * The event filter requires to do i/o operation until EAGAIN -
253 * epoll, rt signals.
254 */
255 #define NGX_HAVE_GREEDY_EVENT 0x00000020
256
257 /*
258 * The event filter is epoll,
259 */
260 #define NGX_USE_EPOLL_EVENT 0x00000040
261
262 /*
263 * No need to add or delete the event filters - rt signals.
264 */
265 #define NGX_USE_RTSIG_EVENT 0x00000080
266
267 /*
268 * No need to add or delete the event filters - overlapped, aio_read,
269 * aioread, io_submit.
270 */
271 #define NGX_USE_AIO_EVENT 0x00000100
272
273 /*
274 * Need to add socket or handle only once - i/o completion port.
275 * It also requires HAVE_AIO and NGX_USE_AIO_EVENT to be set.
276 */
277 #define NGX_USE_IOCP_EVENT 0x00000200
278
279
280
281 /*
282 * The event filter is deleted before the closing file.
283 * Has no meaning for select, poll, epoll.
284 *
285 * kqueue: kqueue deletes event filters for file that closed
286 * so we need only to delete filters in user-level batch array
287 * /dev/poll: we need to flush POLLREMOVE event before closing file
288 */
289
290 #define NGX_CLOSE_EVENT 1
291 #define NGX_DISABLE_EVENT 2
292
293
294 /* these flags have a meaning only for kqueue */
295 #define NGX_LOWAT_EVENT 0
296 #define NGX_VNODE_EVENT 0
297
298
299 #if (HAVE_KQUEUE)
300
301 #define NGX_READ_EVENT EVFILT_READ
302 #define NGX_WRITE_EVENT EVFILT_WRITE
303
304 #undef NGX_VNODE_EVENT
305 #define NGX_VNODE_EVENT EVFILT_VNODE
306
307 /*
308 * NGX_CLOSE_EVENT and NGX_LOWAT_EVENT are the module flags and they would
309 * not go into a kernel so we need to choose the value that would not interfere
310 * with any existent and future kqueue flags. kqueue has such values -
311 * EV_FLAG1, EV_EOF and EV_ERROR. They are reserved and cleared on a kernel
312 * entrance.
313 */
314 #undef NGX_CLOSE_EVENT
315 #define NGX_CLOSE_EVENT EV_EOF
316
317 #undef NGX_LOWAT_EVENT
318 #define NGX_LOWAT_EVENT EV_FLAG1
319
320 #define NGX_LEVEL_EVENT 0
321 #define NGX_ONESHOT_EVENT EV_ONESHOT
322 #define NGX_CLEAR_EVENT EV_CLEAR
323
324 #undef NGX_DISABLE_EVENT
325 #define NGX_DISABLE_EVENT EV_DISABLE
326
327
328 #elif (HAVE_DEVPOLL)
329
330 #define NGX_READ_EVENT POLLIN
331 #define NGX_WRITE_EVENT POLLOUT
332
333 #define NGX_LEVEL_EVENT 0
334 #define NGX_ONESHOT_EVENT 1
335
336
337 #elif (HAVE_EPOLL)
338
339 #define NGX_READ_EVENT EPOLLIN
340 #define NGX_WRITE_EVENT EPOLLOUT
341
342 #define NGX_LEVEL_EVENT 0
343 #define NGX_CLEAR_EVENT EPOLLET
344 #define NGX_ONESHOT_EVENT 0x70000000
345 #if 0
346 #define NGX_ONESHOT_EVENT EPOLLONESHOT
347 #endif
348
349
350 #elif (HAVE_POLL)
351
352 #define NGX_READ_EVENT POLLIN
353 #define NGX_WRITE_EVENT POLLOUT
354
355 #define NGX_LEVEL_EVENT 0
356 #define NGX_ONESHOT_EVENT 1
357
358
359 #else /* select */
360
361 #define NGX_READ_EVENT 0
362 #define NGX_WRITE_EVENT 1
363
364 #define NGX_LEVEL_EVENT 0
365 #define NGX_ONESHOT_EVENT 1
366
367 #endif /* HAVE_KQUEUE */
368
369
370 #if (HAVE_IOCP)
371 #define NGX_IOCP_ACCEPT 0
372 #define NGX_IOCP_IO 1
373 #define NGX_IOCP_CONNECT 2
374 #endif
375
376
377 #ifndef NGX_CLEAR_EVENT
378 #define NGX_CLEAR_EVENT 0 /* dummy declaration */
379 #endif
380
381
382 #define ngx_process_changes ngx_event_actions.process_changes
383 #define ngx_process_events ngx_event_actions.process_events
384 #define ngx_done_events ngx_event_actions.done
385
386 #define ngx_add_event ngx_event_actions.add
387 #define ngx_del_event ngx_event_actions.del
388 #define ngx_add_conn ngx_event_actions.add_conn
389 #define ngx_del_conn ngx_event_actions.del_conn
390
391 #define ngx_add_timer ngx_event_add_timer
392 #define ngx_del_timer ngx_event_del_timer
393
394
395 #define ngx_recv ngx_io.recv
396 #define ngx_recv_chain ngx_io.recv_chain
397 #define ngx_send ngx_io.send
398 #define ngx_send_chain ngx_io.send_chain
399
400
401
402 #define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */
403 #define NGX_EVENT_CONF 0x02000000
404
405
406 typedef struct {
407 ngx_uint_t connections;
408 ngx_uint_t use;
409
410 ngx_flag_t multi_accept;
411 ngx_flag_t accept_mutex;
412
413 ngx_msec_t accept_mutex_delay;
414
415 u_char *name;
416
417 #if (NGX_DEBUG)
418 ngx_array_t debug_connection;
419 #endif
420 } ngx_event_conf_t;
421
422
423 typedef struct {
424 ngx_str_t *name;
425
426 void *(*create_conf)(ngx_cycle_t *cycle);
427 char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
428
429 ngx_event_actions_t actions;
430 } ngx_event_module_t;
431
432
433 extern ngx_atomic_t *ngx_connection_counter;
434
435 extern ngx_atomic_t *ngx_accept_mutex_ptr;
436 extern ngx_atomic_t *ngx_accept_mutex;
437 extern ngx_uint_t ngx_accept_mutex_held;
438 extern ngx_msec_t ngx_accept_mutex_delay;
439 extern ngx_int_t ngx_accept_disabled;
440
441
442 #if (NGX_STAT_STUB)
443
444 extern ngx_atomic_t *ngx_stat_accepted;
445 extern ngx_atomic_t *ngx_stat_requests;
446 extern ngx_atomic_t *ngx_stat_active;
447 extern ngx_atomic_t *ngx_stat_reading;
448 extern ngx_atomic_t *ngx_stat_writing;
449
450 #endif
451
452
453
454 #define ngx_accept_mutex_unlock() \
455 if (ngx_accept_mutex_held) { \
456 *ngx_accept_mutex = 0; \
457 }
458
459
460 extern ngx_uint_t ngx_event_flags;
461 extern ngx_module_t ngx_events_module;
462 extern ngx_module_t ngx_event_core_module;
463
464
465 #define ngx_event_get_conf(conf_ctx, module) \
466 (*(ngx_get_conf(conf_ctx, ngx_events_module))) [module.ctx_index];
467
468
469
470 void ngx_event_accept(ngx_event_t *ev);
471 ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle);
472 ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle);
473 ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
474
475
476 #if (WIN32)
477 void ngx_event_acceptex(ngx_event_t *ev);
478 int ngx_event_post_acceptex(ngx_listening_t *ls, int n);
479 #endif
480
481
482 /* used in ngx_log_debugX() */
483 #define ngx_event_ident(p) ((ngx_connection_t *) (p))->fd
484
485
486 #include <ngx_event_timer.h>
487 #include <ngx_event_posted.h>
488 #include <ngx_event_busy_lock.h>
489
490 #if (WIN32)
491 #include <ngx_iocp_module.h>
492 #endif
493
494
495
496 ngx_inline static int ngx_handle_read_event(ngx_event_t *rev, u_int flags)
497 {
498 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
499
500 /* kqueue */
501
502 if (!rev->active && !rev->ready) {
503 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT)
504 == NGX_ERROR) {
505 return NGX_ERROR;
506 }
507 }
508
509 return NGX_OK;
510
511 } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
512
513 /* select, poll, /dev/poll */
514
515 if (!rev->active && !rev->ready) {
516 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
517 == NGX_ERROR)
518 {
519 return NGX_ERROR;
520 }
521
522 return NGX_OK;
523 }
524
525 if (rev->active && (rev->ready || (flags & NGX_CLOSE_EVENT))) {
526 if (ngx_del_event(rev, NGX_READ_EVENT, flags) == NGX_ERROR) {
527 return NGX_ERROR;
528 }
529
530 return NGX_OK;
531 }
532 }
533
534 /* aio, iocp, epoll, rtsig */
535
536 return NGX_OK;
537 }
538
539
540 ngx_inline static int ngx_handle_level_read_event(ngx_event_t *rev)
541 {
542 if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
543 if (!rev->active && !rev->ready) {
544 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
545 == NGX_ERROR)
546 {
547 return NGX_ERROR;
548 }
549
550 return NGX_OK;
551 }
552
553 if (rev->active && rev->ready) {
554 if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
555 return NGX_ERROR;
556 }
557
558 return NGX_OK;
559 }
560 }
561
562 return NGX_OK;
563 }
564
565
566 ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, u_int flags)
567 {
568 if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
569
570 /* kqueue */
571
572 if (!wev->active && !wev->ready) {
573 if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT|flags)
574 == NGX_ERROR)
575 {
576 return NGX_ERROR;
577 }
578 }
579
580 return NGX_OK;
581
582 } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
583
584 /* select, poll, /dev/poll */
585
586 if (!wev->active && !wev->ready) {
587 if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
588 == NGX_ERROR)
589 {
590 return NGX_ERROR;
591 }
592
593 return NGX_OK;
594 }
595
596 if (wev->active && wev->ready) {
597 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
598 return NGX_ERROR;
599 }
600
601 return NGX_OK;
602 }
603 }
604
605 /* aio, iocp, epoll, rtsig */
606
607 return NGX_OK;
608 }
609
610
611 ngx_inline static int ngx_handle_level_write_event(ngx_event_t *wev)
612 {
613 if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
614 if (!wev->active && !wev->ready) {
615 if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
616 == NGX_ERROR)
617 {
618 return NGX_ERROR;
619 }
620
621 return NGX_OK;
622 }
623
624 if (wev->active && wev->ready) {
625 if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
626 return NGX_ERROR;
627 }
628
629 return NGX_OK;
630 }
631 }
632
633 return NGX_OK;
634 }
635
636
637 #endif /* _NGX_EVENT_H_INCLUDED_ */