3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
12 #define DEFAULT_CONNECTIONS 512
15 extern ngx_module_t ngx_kqueue_module
;
16 extern ngx_module_t ngx_eventport_module
;
17 extern ngx_module_t ngx_devpoll_module
;
18 extern ngx_module_t ngx_epoll_module
;
19 extern ngx_module_t ngx_rtsig_module
;
20 extern ngx_module_t ngx_select_module
;
23 static ngx_int_t
ngx_event_module_init(ngx_cycle_t
*cycle
);
24 static ngx_int_t
ngx_event_process_init(ngx_cycle_t
*cycle
);
25 static char *ngx_events_block(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
);
27 static char *ngx_event_connections(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
29 static char *ngx_event_use(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
);
30 static char *ngx_event_debug_connection(ngx_conf_t
*cf
, ngx_command_t
*cmd
,
33 static void *ngx_event_create_conf(ngx_cycle_t
*cycle
);
34 static char *ngx_event_init_conf(ngx_cycle_t
*cycle
, void *conf
);
37 static ngx_uint_t ngx_timer_resolution
;
38 sig_atomic_t ngx_event_timer_alarm
;
40 static ngx_uint_t ngx_event_max_module
;
42 ngx_uint_t ngx_event_flags
;
43 ngx_event_actions_t ngx_event_actions
;
46 ngx_atomic_t connection_counter
= 1;
47 ngx_atomic_t
*ngx_connection_counter
= &connection_counter
;
50 ngx_atomic_t
*ngx_accept_mutex_ptr
;
51 ngx_shmtx_t ngx_accept_mutex
;
52 ngx_uint_t ngx_use_accept_mutex
;
53 ngx_uint_t ngx_accept_events
;
54 ngx_uint_t ngx_accept_mutex_held
;
55 ngx_msec_t ngx_accept_mutex_delay
;
56 ngx_int_t ngx_accept_disabled
;
57 ngx_file_t ngx_accept_mutex_lock_file
;
62 ngx_atomic_t ngx_stat_accepted0
;
63 ngx_atomic_t
*ngx_stat_accepted
= &ngx_stat_accepted0
;
64 ngx_atomic_t ngx_stat_handled0
;
65 ngx_atomic_t
*ngx_stat_handled
= &ngx_stat_handled0
;
66 ngx_atomic_t ngx_stat_requests0
;
67 ngx_atomic_t
*ngx_stat_requests
= &ngx_stat_requests0
;
68 ngx_atomic_t ngx_stat_active0
;
69 ngx_atomic_t
*ngx_stat_active
= &ngx_stat_active0
;
70 ngx_atomic_t ngx_stat_reading0
;
71 ngx_atomic_t
*ngx_stat_reading
= &ngx_stat_reading0
;
72 ngx_atomic_t ngx_stat_writing0
;
73 ngx_atomic_t
*ngx_stat_writing
= &ngx_stat_writing0
;
79 static ngx_command_t ngx_events_commands
[] = {
81 { ngx_string("events"),
82 NGX_MAIN_CONF
|NGX_CONF_BLOCK
|NGX_CONF_NOARGS
,
92 static ngx_core_module_t ngx_events_module_ctx
= {
99 ngx_module_t ngx_events_module
= {
101 &ngx_events_module_ctx
, /* module context */
102 ngx_events_commands
, /* module directives */
103 NGX_CORE_MODULE
, /* module type */
104 NULL
, /* init master */
105 NULL
, /* init module */
106 NULL
, /* init process */
107 NULL
, /* init thread */
108 NULL
, /* exit thread */
109 NULL
, /* exit process */
110 NULL
, /* exit master */
111 NGX_MODULE_V1_PADDING
115 static ngx_str_t event_core_name
= ngx_string("event_core");
118 static ngx_command_t ngx_event_core_commands
[] = {
120 { ngx_string("worker_connections"),
121 NGX_EVENT_CONF
|NGX_CONF_TAKE1
,
122 ngx_event_connections
,
127 { ngx_string("connections"),
128 NGX_EVENT_CONF
|NGX_CONF_TAKE1
,
129 ngx_event_connections
,
135 NGX_EVENT_CONF
|NGX_CONF_TAKE1
,
141 { ngx_string("multi_accept"),
142 NGX_EVENT_CONF
|NGX_CONF_FLAG
,
143 ngx_conf_set_flag_slot
,
145 offsetof(ngx_event_conf_t
, multi_accept
),
148 { ngx_string("accept_mutex"),
149 NGX_EVENT_CONF
|NGX_CONF_FLAG
,
150 ngx_conf_set_flag_slot
,
152 offsetof(ngx_event_conf_t
, accept_mutex
),
155 { ngx_string("accept_mutex_delay"),
156 NGX_EVENT_CONF
|NGX_CONF_TAKE1
,
157 ngx_conf_set_msec_slot
,
159 offsetof(ngx_event_conf_t
, accept_mutex_delay
),
162 { ngx_string("debug_connection"),
163 NGX_EVENT_CONF
|NGX_CONF_TAKE1
,
164 ngx_event_debug_connection
,
173 ngx_event_module_t ngx_event_core_module_ctx
= {
175 ngx_event_create_conf
, /* create configuration */
176 ngx_event_init_conf
, /* init configuration */
178 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
182 ngx_module_t ngx_event_core_module
= {
184 &ngx_event_core_module_ctx
, /* module context */
185 ngx_event_core_commands
, /* module directives */
186 NGX_EVENT_MODULE
, /* module type */
187 NULL
, /* init master */
188 ngx_event_module_init
, /* init module */
189 ngx_event_process_init
, /* init process */
190 NULL
, /* init thread */
191 NULL
, /* exit thread */
192 NULL
, /* exit process */
193 NULL
, /* exit master */
194 NGX_MODULE_V1_PADDING
199 ngx_process_events_and_timers(ngx_cycle_t
*cycle
)
202 ngx_msec_t timer
, delta
;
204 if (ngx_timer_resolution
) {
205 timer
= NGX_TIMER_INFINITE
;
209 timer
= ngx_event_find_timer();
210 flags
= NGX_UPDATE_TIME
;
214 if (timer
== NGX_TIMER_INFINITE
|| timer
> 500) {
221 if (ngx_use_accept_mutex
) {
222 if (ngx_accept_disabled
> 0) {
223 ngx_accept_disabled
--;
226 if (ngx_trylock_accept_mutex(cycle
) == NGX_ERROR
) {
230 if (ngx_accept_mutex_held
) {
231 flags
|= NGX_POST_EVENTS
;
234 if (timer
== NGX_TIMER_INFINITE
235 || timer
> ngx_accept_mutex_delay
)
237 timer
= ngx_accept_mutex_delay
;
243 delta
= ngx_current_msec
;
245 (void) ngx_process_events(cycle
, timer
, flags
);
247 delta
= ngx_current_msec
- delta
;
249 ngx_log_debug1(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0,
250 "timer delta: %M", delta
);
252 if (ngx_posted_accept_events
) {
253 ngx_event_process_posted(cycle
, &ngx_posted_accept_events
);
256 if (ngx_accept_mutex_held
) {
257 ngx_shmtx_unlock(&ngx_accept_mutex
);
261 ngx_event_expire_timers();
264 ngx_log_debug1(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0,
265 "posted events %p", ngx_posted_events
);
267 if (ngx_posted_events
) {
269 ngx_wakeup_worker_thread(cycle
);
272 ngx_event_process_posted(cycle
, &ngx_posted_events
);
279 ngx_handle_read_event(ngx_event_t
*rev
, ngx_uint_t flags
)
281 if (ngx_event_flags
& NGX_USE_CLEAR_EVENT
) {
285 if (!rev
->active
&& !rev
->ready
) {
286 if (ngx_add_event(rev
, NGX_READ_EVENT
, NGX_CLEAR_EVENT
)
295 } else if (ngx_event_flags
& NGX_USE_LEVEL_EVENT
) {
297 /* select, poll, /dev/poll */
299 if (!rev
->active
&& !rev
->ready
) {
300 if (ngx_add_event(rev
, NGX_READ_EVENT
, NGX_LEVEL_EVENT
)
309 if (rev
->active
&& (rev
->ready
|| (flags
& NGX_CLOSE_EVENT
))) {
310 if (ngx_del_event(rev
, NGX_READ_EVENT
, NGX_LEVEL_EVENT
| flags
)
319 } else if (ngx_event_flags
& NGX_USE_EVENTPORT_EVENT
) {
323 if (!rev
->active
&& !rev
->ready
) {
324 if (ngx_add_event(rev
, NGX_READ_EVENT
, 0) == NGX_ERROR
) {
331 if (rev
->oneshot
&& !rev
->ready
) {
332 if (ngx_del_event(rev
, NGX_READ_EVENT
, 0) == NGX_ERROR
) {
340 /* aio, iocp, rtsig */
347 ngx_handle_write_event(ngx_event_t
*wev
, size_t lowat
)
354 if (ngx_send_lowat(c
, lowat
) == NGX_ERROR
) {
359 if (ngx_event_flags
& NGX_USE_CLEAR_EVENT
) {
363 if (!wev
->active
&& !wev
->ready
) {
364 if (ngx_add_event(wev
, NGX_WRITE_EVENT
,
365 NGX_CLEAR_EVENT
| (lowat
? NGX_LOWAT_EVENT
: 0))
374 } else if (ngx_event_flags
& NGX_USE_LEVEL_EVENT
) {
376 /* select, poll, /dev/poll */
378 if (!wev
->active
&& !wev
->ready
) {
379 if (ngx_add_event(wev
, NGX_WRITE_EVENT
, NGX_LEVEL_EVENT
)
388 if (wev
->active
&& wev
->ready
) {
389 if (ngx_del_event(wev
, NGX_WRITE_EVENT
, NGX_LEVEL_EVENT
)
398 } else if (ngx_event_flags
& NGX_USE_EVENTPORT_EVENT
) {
402 if (!wev
->active
&& !wev
->ready
) {
403 if (ngx_add_event(wev
, NGX_WRITE_EVENT
, 0) == NGX_ERROR
) {
410 if (wev
->oneshot
&& wev
->ready
) {
411 if (ngx_del_event(wev
, NGX_WRITE_EVENT
, 0) == NGX_ERROR
) {
419 /* aio, iocp, rtsig */
426 ngx_event_module_init(ngx_cycle_t
*cycle
)
432 ngx_core_conf_t
*ccf
;
433 ngx_event_conf_t
*ecf
;
435 cf
= ngx_get_conf(cycle
->conf_ctx
, ngx_events_module
);
438 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, 0,
439 "no \"events\" section in configuration");
443 ecf
= (*cf
)[ngx_event_core_module
.ctx_index
];
445 if (!ngx_test_config
) {
446 ngx_log_error(NGX_LOG_NOTICE
, cycle
->log
, 0,
447 "using the \"%s\" event method", ecf
->name
);
450 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
452 ngx_timer_resolution
= ccf
->timer_resolution
;
459 if (getrlimit(RLIMIT_NOFILE
, &rlmt
) == -1) {
460 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
461 "getrlimit(RLIMIT_NOFILE) failed, ignored");
464 if (ecf
->connections
> (ngx_uint_t
) rlmt
.rlim_cur
465 && (ccf
->rlimit_nofile
== NGX_CONF_UNSET
466 || ecf
->connections
> (ngx_uint_t
) ccf
->rlimit_nofile
))
468 limit
= (ccf
->rlimit_nofile
== NGX_CONF_UNSET
) ?
469 (ngx_int_t
) rlmt
.rlim_cur
: ccf
->rlimit_nofile
;
471 ngx_log_error(NGX_LOG_WARN
, cycle
->log
, 0,
472 "%ui worker_connections are more than "
473 "open file resource limit: %i",
474 ecf
->connections
, limit
);
478 #endif /* !(NGX_WIN32) */
481 if (ccf
->master
== 0) {
485 if (ngx_accept_mutex_ptr
) {
490 /* cl should be equal or bigger than cache line size */
494 size
= cl
/* ngx_accept_mutex */
495 + cl
; /* ngx_connection_counter */
499 size
+= cl
/* ngx_stat_accepted */
500 + cl
/* ngx_stat_handled */
501 + cl
/* ngx_stat_requests */
502 + cl
/* ngx_stat_active */
503 + cl
/* ngx_stat_reading */
504 + cl
; /* ngx_stat_writing */
509 shm
.log
= cycle
->log
;
511 if (ngx_shm_alloc(&shm
) != NGX_OK
) {
517 ngx_accept_mutex_ptr
= (ngx_atomic_t
*) shared
;
519 if (ngx_shmtx_create(&ngx_accept_mutex
, shared
, cycle
->lock_file
.data
)
525 ngx_connection_counter
= (ngx_atomic_t
*) (shared
+ 1 * cl
);
529 ngx_stat_accepted
= (ngx_atomic_t
*) (shared
+ 2 * cl
);
530 ngx_stat_handled
= (ngx_atomic_t
*) (shared
+ 3 * cl
);
531 ngx_stat_requests
= (ngx_atomic_t
*) (shared
+ 4 * cl
);
532 ngx_stat_active
= (ngx_atomic_t
*) (shared
+ 5 * cl
);
533 ngx_stat_reading
= (ngx_atomic_t
*) (shared
+ 6 * cl
);
534 ngx_stat_writing
= (ngx_atomic_t
*) (shared
+ 7 * cl
);
538 *ngx_connection_counter
= 1;
540 ngx_log_debug2(NGX_LOG_DEBUG_EVENT
, cycle
->log
, 0,
542 ngx_connection_counter
, *ngx_connection_counter
);
551 ngx_timer_signal_handler(int signo
)
553 ngx_event_timer_alarm
= 1;
555 ngx_time_update(0, 0);
558 ngx_log_debug0(NGX_LOG_DEBUG_EVENT
, ngx_cycle
->log
, 0, "timer signal");
566 ngx_event_process_init(ngx_cycle_t
*cycle
)
569 ngx_event_t
*rev
, *wev
;
571 ngx_connection_t
*c
, *next
, *old
;
572 ngx_core_conf_t
*ccf
;
573 ngx_event_conf_t
*ecf
;
574 ngx_event_module_t
*module
;
576 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
577 ecf
= ngx_event_get_conf(cycle
->conf_ctx
, ngx_event_core_module
);
579 if (ccf
->master
&& ccf
->worker_processes
> 1 && ecf
->accept_mutex
) {
580 ngx_use_accept_mutex
= 1;
581 ngx_accept_mutex_held
= 0;
582 ngx_accept_mutex_delay
= ecf
->accept_mutex_delay
;
585 ngx_use_accept_mutex
= 0;
589 ngx_posted_events_mutex
= ngx_mutex_init(cycle
->log
, 0);
590 if (ngx_posted_events_mutex
== NULL
) {
595 if (ngx_event_timer_init(cycle
->log
) == NGX_ERROR
) {
599 for (m
= 0; ngx_modules
[m
]; m
++) {
600 if (ngx_modules
[m
]->type
!= NGX_EVENT_MODULE
) {
604 if (ngx_modules
[m
]->ctx_index
!= ecf
->use
) {
608 module
= ngx_modules
[m
]->ctx
;
610 if (module
->actions
.init(cycle
, ngx_timer_resolution
) != NGX_OK
) {
620 if (ngx_timer_resolution
&& !(ngx_event_flags
& NGX_USE_TIMER_EVENT
)) {
622 struct itimerval itv
;
624 ngx_memzero(&sa
, sizeof(struct sigaction
));
625 sa
.sa_handler
= ngx_timer_signal_handler
;
626 sigemptyset(&sa
.sa_mask
);
628 if (sigaction(SIGALRM
, &sa
, NULL
) == -1) {
629 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
630 "sigaction(SIGALRM) failed");
634 itv
.it_interval
.tv_sec
= ngx_timer_resolution
/ 1000;
635 itv
.it_interval
.tv_usec
= (ngx_timer_resolution
% 1000) * 1000;
636 itv
.it_value
.tv_sec
= ngx_timer_resolution
/ 1000;
637 itv
.it_value
.tv_usec
= (ngx_timer_resolution
% 1000 ) * 1000;
639 if (setitimer(ITIMER_REAL
, &itv
, NULL
) == -1) {
640 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
641 "setitimer() failed");
645 if (ngx_event_flags
& NGX_USE_FD_EVENT
) {
648 if (getrlimit(RLIMIT_NOFILE
, &rlmt
) == -1) {
649 ngx_log_error(NGX_LOG_ALERT
, cycle
->log
, ngx_errno
,
650 "getrlimit(RLIMIT_NOFILE) failed");
654 cycle
->files_n
= (ngx_uint_t
) rlmt
.rlim_cur
;
656 cycle
->files
= ngx_calloc(sizeof(ngx_connection_t
*) * cycle
->files_n
,
658 if (cycle
->files
== NULL
) {
666 ngx_alloc(sizeof(ngx_connection_t
) * cycle
->connection_n
, cycle
->log
);
667 if (cycle
->connections
== NULL
) {
671 c
= cycle
->connections
;
673 cycle
->read_events
= ngx_alloc(sizeof(ngx_event_t
) * cycle
->connection_n
,
675 if (cycle
->read_events
== NULL
) {
679 rev
= cycle
->read_events
;
680 for (i
= 0; i
< cycle
->connection_n
; i
++) {
684 rev
[i
].lock
= &c
[i
].lock
;
685 rev
[i
].own_lock
= &c
[i
].lock
;
689 cycle
->write_events
= ngx_alloc(sizeof(ngx_event_t
) * cycle
->connection_n
,
691 if (cycle
->write_events
== NULL
) {
695 wev
= cycle
->write_events
;
696 for (i
= 0; i
< cycle
->connection_n
; i
++) {
699 wev
[i
].lock
= &c
[i
].lock
;
700 wev
[i
].own_lock
= &c
[i
].lock
;
704 i
= cycle
->connection_n
;
711 c
[i
].read
= &cycle
->read_events
[i
];
712 c
[i
].write
= &cycle
->write_events
[i
];
713 c
[i
].fd
= (ngx_socket_t
) -1;
722 cycle
->free_connections
= next
;
723 cycle
->free_connection_n
= cycle
->connection_n
;
725 /* for each listening socket */
727 ls
= cycle
->listening
.elts
;
728 for (i
= 0; i
< cycle
->listening
.nelts
; i
++) {
730 c
= ngx_get_connection(ls
[i
].fd
, cycle
->log
);
738 c
->listening
= &ls
[i
];
739 ls
[i
].connection
= c
;
746 #if (NGX_HAVE_DEFERRED_ACCEPT)
747 rev
->deferred_accept
= ls
[i
].deferred_accept
;
750 if (!(ngx_event_flags
& NGX_USE_IOCP_EVENT
)) {
751 if (ls
[i
].previous
) {
754 * delete the old accept events that were bound to
755 * the old cycle read events array
758 old
= ls
[i
].previous
->connection
;
760 if (ngx_del_event(old
->read
, NGX_READ_EVENT
, NGX_CLOSE_EVENT
)
766 old
->fd
= (ngx_socket_t
) -1;
772 if (ngx_event_flags
& NGX_USE_IOCP_EVENT
) {
773 ngx_iocp_conf_t
*iocpcf
;
775 rev
->handler
= ngx_event_acceptex
;
777 if (ngx_add_event(rev
, 0, NGX_IOCP_ACCEPT
) == NGX_ERROR
) {
781 ls
[i
].log
.handler
= ngx_acceptex_log_error
;
783 iocpcf
= ngx_event_get_conf(cycle
->conf_ctx
, ngx_iocp_module
);
784 if (ngx_event_post_acceptex(&ls
[i
], iocpcf
->post_acceptex
)
791 rev
->handler
= ngx_event_accept
;
793 if (ngx_add_event(rev
, NGX_READ_EVENT
, 0) == NGX_ERROR
) {
800 rev
->handler
= ngx_event_accept
;
802 if (ngx_use_accept_mutex
) {
806 if (ngx_event_flags
& NGX_USE_RTSIG_EVENT
) {
807 if (ngx_add_conn(c
) == NGX_ERROR
) {
812 if (ngx_add_event(rev
, NGX_READ_EVENT
, 0) == NGX_ERROR
) {
826 ngx_send_lowat(ngx_connection_t
*c
, size_t lowat
)
830 #if (NGX_HAVE_LOWAT_EVENT)
832 if (ngx_event_flags
& NGX_USE_KQUEUE_EVENT
) {
833 c
->write
->available
= lowat
;
839 if (lowat
== 0 || c
->sndlowat
) {
843 sndlowat
= (int) lowat
;
845 if (setsockopt(c
->fd
, SOL_SOCKET
, SO_SNDLOWAT
,
846 (const void *) &sndlowat
, sizeof(int))
849 ngx_connection_error(c
, ngx_socket_errno
,
850 "setsockopt(SO_SNDLOWAT) failed");
861 ngx_events_block(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
867 ngx_event_module_t
*m
;
869 /* count the number of the event modules and set up their indices */
871 ngx_event_max_module
= 0;
872 for (i
= 0; ngx_modules
[i
]; i
++) {
873 if (ngx_modules
[i
]->type
!= NGX_EVENT_MODULE
) {
877 ngx_modules
[i
]->ctx_index
= ngx_event_max_module
++;
880 ctx
= ngx_pcalloc(cf
->pool
, sizeof(void *));
882 return NGX_CONF_ERROR
;
885 *ctx
= ngx_pcalloc(cf
->pool
, ngx_event_max_module
* sizeof(void *));
887 return NGX_CONF_ERROR
;
890 *(void **) conf
= ctx
;
892 for (i
= 0; ngx_modules
[i
]; i
++) {
893 if (ngx_modules
[i
]->type
!= NGX_EVENT_MODULE
) {
897 m
= ngx_modules
[i
]->ctx
;
899 if (m
->create_conf
) {
900 (*ctx
)[ngx_modules
[i
]->ctx_index
] = m
->create_conf(cf
->cycle
);
901 if ((*ctx
)[ngx_modules
[i
]->ctx_index
] == NULL
) {
902 return NGX_CONF_ERROR
;
909 cf
->module_type
= NGX_EVENT_MODULE
;
910 cf
->cmd_type
= NGX_EVENT_CONF
;
912 rv
= ngx_conf_parse(cf
, NULL
);
916 if (rv
!= NGX_CONF_OK
)
919 for (i
= 0; ngx_modules
[i
]; i
++) {
920 if (ngx_modules
[i
]->type
!= NGX_EVENT_MODULE
) {
924 m
= ngx_modules
[i
]->ctx
;
927 rv
= m
->init_conf(cf
->cycle
, (*ctx
)[ngx_modules
[i
]->ctx_index
]);
928 if (rv
!= NGX_CONF_OK
) {
939 ngx_event_connections(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
941 ngx_event_conf_t
*ecf
= conf
;
945 if (ecf
->connections
!= NGX_CONF_UNSET_UINT
) {
946 return "is duplicate";
949 if (ngx_strcmp(cmd
->name
.data
, "connections") == 0) {
950 ngx_conf_log_error(NGX_LOG_WARN
, cf
, 0,
951 "the \"connections\" directive is deprecated, "
952 "use the \"worker_connections\" directive instead");
955 value
= cf
->args
->elts
;
956 ecf
->connections
= ngx_atoi(value
[1].data
, value
[1].len
);
957 if (ecf
->connections
== (ngx_uint_t
) NGX_ERROR
) {
958 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
959 "invalid number \"%V\"", &value
[1]);
961 return NGX_CONF_ERROR
;
964 cf
->cycle
->connection_n
= ecf
->connections
;
971 ngx_event_use(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
973 ngx_event_conf_t
*ecf
= conf
;
977 ngx_event_conf_t
*old_ecf
;
978 ngx_event_module_t
*module
;
980 if (ecf
->use
!= NGX_CONF_UNSET_UINT
) {
981 return "is duplicate";
984 value
= cf
->args
->elts
;
986 if (cf
->cycle
->old_cycle
->conf_ctx
) {
987 old_ecf
= ngx_event_get_conf(cf
->cycle
->old_cycle
->conf_ctx
,
988 ngx_event_core_module
);
994 for (m
= 0; ngx_modules
[m
]; m
++) {
995 if (ngx_modules
[m
]->type
!= NGX_EVENT_MODULE
) {
999 module
= ngx_modules
[m
]->ctx
;
1000 if (module
->name
->len
== value
[1].len
) {
1001 if (ngx_strcmp(module
->name
->data
, value
[1].data
) == 0) {
1002 ecf
->use
= ngx_modules
[m
]->ctx_index
;
1003 ecf
->name
= module
->name
->data
;
1005 if (ngx_process
== NGX_PROCESS_SINGLE
1007 && old_ecf
->use
!= ecf
->use
)
1009 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1010 "when the server runs without a master process "
1011 "the \"%V\" event type must be the same as "
1012 "in previous configuration - \"%s\" "
1013 "and it can not be changed on the fly, "
1014 "to change it you need to stop server "
1015 "and start it again",
1016 &value
[1], old_ecf
->name
);
1018 return NGX_CONF_ERROR
;
1026 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1027 "invalid event type \"%V\"", &value
[1]);
1029 return NGX_CONF_ERROR
;
1034 ngx_event_debug_connection(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
1037 ngx_event_conf_t
*ecf
= conf
;
1041 ngx_event_debug_t
*dc
;
1043 ngx_inet_cidr_t in_cidr
;
1045 value
= cf
->args
->elts
;
1049 dc
= ngx_array_push(&ecf
->debug_connection
);
1051 return NGX_CONF_ERROR
;
1054 dc
->addr
= inet_addr((char *) value
[1].data
);
1056 if (dc
->addr
!= INADDR_NONE
) {
1057 dc
->mask
= 0xffffffff;
1061 rc
= ngx_ptocidr(&value
[1], &in_cidr
);
1063 if (rc
== NGX_DONE
) {
1064 ngx_conf_log_error(NGX_LOG_WARN
, cf
, 0,
1065 "low address bits of %V are meaningless", &value
[1]);
1070 dc
->mask
= in_cidr
.mask
;
1071 dc
->addr
= in_cidr
.addr
;
1075 h
= gethostbyname((char *) value
[1].data
);
1077 if (h
== NULL
|| h
->h_addr_list
[0] == NULL
) {
1078 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1079 "host \"%s\" not found", value
[1].data
);
1080 return NGX_CONF_ERROR
;
1083 dc
->mask
= 0xffffffff;
1084 dc
->addr
= *(in_addr_t
*)(h
->h_addr_list
[0]);
1088 ngx_conf_log_error(NGX_LOG_WARN
, cf
, 0,
1089 "\"debug_connection\" is ignored, you need to rebuild "
1090 "nginx using --with-debug option to enable it");
1099 ngx_event_create_conf(ngx_cycle_t
*cycle
)
1101 ngx_event_conf_t
*ecf
;
1103 ecf
= ngx_palloc(cycle
->pool
, sizeof(ngx_event_conf_t
));
1105 return NGX_CONF_ERROR
;
1108 ecf
->connections
= NGX_CONF_UNSET_UINT
;
1109 ecf
->use
= NGX_CONF_UNSET_UINT
;
1110 ecf
->multi_accept
= NGX_CONF_UNSET
;
1111 ecf
->accept_mutex
= NGX_CONF_UNSET
;
1112 ecf
->accept_mutex_delay
= NGX_CONF_UNSET_MSEC
;
1113 ecf
->name
= (void *) NGX_CONF_UNSET
;
1117 if (ngx_array_init(&ecf
->debug_connection
, cycle
->pool
, 4,
1118 sizeof(ngx_event_debug_t
)) == NGX_ERROR
)
1120 return NGX_CONF_ERROR
;
1130 ngx_event_init_conf(ngx_cycle_t
*cycle
, void *conf
)
1132 ngx_event_conf_t
*ecf
= conf
;
1134 #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
1137 #if (NGX_HAVE_RTSIG)
1139 ngx_core_conf_t
*ccf
;
1142 ngx_module_t
*module
;
1143 ngx_event_module_t
*event_module
;
1147 #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
1149 fd
= epoll_create(100);
1153 module
= &ngx_epoll_module
;
1155 } else if (ngx_errno
!= NGX_ENOSYS
) {
1156 module
= &ngx_epoll_module
;
1161 #if (NGX_HAVE_RTSIG)
1163 if (module
== NULL
) {
1164 module
= &ngx_rtsig_module
;
1173 #if (NGX_HAVE_DEVPOLL)
1175 module
= &ngx_devpoll_module
;
1179 #if (NGX_HAVE_KQUEUE)
1181 module
= &ngx_kqueue_module
;
1185 #if (NGX_HAVE_SELECT)
1187 if (module
== NULL
) {
1188 module
= &ngx_select_module
;
1193 if (module
== NULL
) {
1194 for (i
= 0; ngx_modules
[i
]; i
++) {
1196 if (ngx_modules
[i
]->type
!= NGX_EVENT_MODULE
) {
1200 event_module
= ngx_modules
[i
]->ctx
;
1202 if (ngx_strcmp(event_module
->name
->data
, event_core_name
.data
) == 0)
1207 module
= ngx_modules
[i
];
1212 if (module
== NULL
) {
1213 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, 0, "no events module found");
1214 return NGX_CONF_ERROR
;
1217 ngx_conf_init_uint_value(ecf
->connections
, DEFAULT_CONNECTIONS
);
1218 cycle
->connection_n
= ecf
->connections
;
1220 ngx_conf_init_uint_value(ecf
->use
, module
->ctx_index
);
1222 event_module
= module
->ctx
;
1223 ngx_conf_init_ptr_value(ecf
->name
, event_module
->name
->data
);
1225 ngx_conf_init_value(ecf
->multi_accept
, 0);
1226 ngx_conf_init_value(ecf
->accept_mutex
, 1);
1227 ngx_conf_init_msec_value(ecf
->accept_mutex_delay
, 500);
1230 #if (NGX_HAVE_RTSIG)
1236 if (ecf
->accept_mutex
) {
1240 ccf
= (ngx_core_conf_t
*) ngx_get_conf(cycle
->conf_ctx
, ngx_core_module
);
1242 if (ccf
->worker_processes
== 0) {
1246 ngx_log_error(NGX_LOG_EMERG
, cycle
->log
, 0,
1247 "the \"rtsig\" method requires \"accept_mutex\" to be on");
1249 return NGX_CONF_ERROR
;