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