blob: b3f6a5620a41fb573526a072e602e2f150f77877 [file] [log] [blame]
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00001
2#include <ngx_config.h>
Igor Sysoev31f88182002-09-27 15:05:29 +00003#include <ngx_core.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00004#include <ngx_event.h>
Igor Sysoev1c13c662003-05-20 15:37:55 +00005
6
Igor Sysoev340b03b2003-07-04 15:10:33 +00007#define DEFAULT_CONNECTIONS 512
Igor Sysoev1c13c662003-05-20 15:37:55 +00008
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00009
Igor Sysoev13933252003-05-29 13:02:09 +000010extern ngx_module_t ngx_select_module;
Igor Sysoev3b30a902003-12-25 20:26:58 +000011extern ngx_event_module_t ngx_select_module_ctx;
Igor Sysoev73009772003-02-06 17:21:13 +000012
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000013#if (HAVE_KQUEUE)
14#include <ngx_kqueue_module.h>
15#endif
16
Igor Sysoev1c13c662003-05-20 15:37:55 +000017#if (HAVE_DEVPOLL)
Igor Sysoev6253ca12003-05-27 12:18:54 +000018extern ngx_module_t ngx_devpoll_module;
Igor Sysoev25b36fe2004-02-03 16:43:54 +000019extern ngx_event_module_t ngx_devpoll_module_ctx;
Igor Sysoev1c13c662003-05-20 15:37:55 +000020#endif
21
Igor Sysoev54498db2004-02-11 17:08:49 +000022#if (HAVE_EPOLL)
23extern ngx_module_t ngx_epoll_module;
24extern ngx_event_module_t ngx_epoll_module_ctx;
25#endif
26
Igor Sysoevff148df2003-02-26 20:21:43 +000027#if (HAVE_AIO)
28#include <ngx_aio_module.h>
29#endif
30
Igor Sysoevdbb27762004-04-01 16:20:53 +000031static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle);
32static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle);
Igor Sysoev6253ca12003-05-27 12:18:54 +000033static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
Igor Sysoev2b58fbf2003-12-09 15:08:11 +000034
35static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd,
36 void *conf);
Igor Sysoev6253ca12003-05-27 12:18:54 +000037static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
Igor Sysoevfff32322004-04-08 15:58:25 +000038static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd,
39 void *conf);
Igor Sysoev2b58fbf2003-12-09 15:08:11 +000040
Igor Sysoev9d639522003-07-07 06:11:50 +000041static void *ngx_event_create_conf(ngx_cycle_t *cycle);
42static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf);
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000043
44
Igor Sysoevdbb27762004-04-01 16:20:53 +000045static ngx_uint_t ngx_event_max_module;
46
47ngx_uint_t ngx_event_flags;
48ngx_event_actions_t ngx_event_actions;
Igor Sysoeva9830112003-05-19 16:39:14 +000049
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000050
Igor Sysoev407b0de2004-04-09 16:03:04 +000051ngx_atomic_t connection_counter;
52ngx_atomic_t *ngx_connection_counter = &connection_counter;
53
54
Igor Sysoevdbb27762004-04-01 16:20:53 +000055ngx_atomic_t *ngx_accept_mutex_ptr;
56ngx_atomic_t *ngx_accept_mutex;
57ngx_uint_t ngx_accept_mutex_held;
Igor Sysoev9a864bd2004-04-04 20:32:09 +000058ngx_msec_t ngx_accept_mutex_delay;
Igor Sysoev732a2712004-04-21 18:54:33 +000059ngx_int_t ngx_accept_disabled;
Igor Sysoevdbb27762004-04-01 16:20:53 +000060
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000061
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000062
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000063static ngx_command_t ngx_events_commands[] = {
64
Igor Sysoev2b58fbf2003-12-09 15:08:11 +000065 { ngx_string("events"),
66 NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
67 ngx_events_block,
68 0,
69 0,
70 NULL },
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000071
Igor Sysoev2b58fbf2003-12-09 15:08:11 +000072 ngx_null_command
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000073};
74
Igor Sysoev43f13192004-04-12 16:38:09 +000075
76static ngx_core_module_t ngx_events_module_ctx = {
77 ngx_string("events"),
78 NULL,
79 NULL
80};
81
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000082
83ngx_module_t ngx_events_module = {
Igor Sysoev6253ca12003-05-27 12:18:54 +000084 NGX_MODULE,
Igor Sysoev43f13192004-04-12 16:38:09 +000085 &ngx_events_module_ctx, /* module context */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000086 ngx_events_commands, /* module directives */
Igor Sysoev6253ca12003-05-27 12:18:54 +000087 NGX_CORE_MODULE, /* module type */
Igor Sysoev340b03b2003-07-04 15:10:33 +000088 NULL, /* init module */
89 NULL /* init child */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000090};
91
92
Igor Sysoev6abfde62003-07-01 15:00:03 +000093static ngx_str_t event_core_name = ngx_string("event_core");
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000094
Igor Sysoev6abfde62003-07-01 15:00:03 +000095static ngx_command_t ngx_event_core_commands[] = {
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +000096
Igor Sysoev2b58fbf2003-12-09 15:08:11 +000097 { ngx_string("connections"),
98 NGX_EVENT_CONF|NGX_CONF_TAKE1,
99 ngx_event_connections,
100 0,
101 0,
102 NULL },
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000103
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000104 { ngx_string("use"),
105 NGX_EVENT_CONF|NGX_CONF_TAKE1,
106 ngx_event_use,
107 0,
108 0,
109 NULL },
Igor Sysoeva9830112003-05-19 16:39:14 +0000110
Igor Sysoeva4b16df2004-02-02 21:19:52 +0000111 { ngx_string("multi_accept"),
112 NGX_EVENT_CONF|NGX_CONF_TAKE1,
113 ngx_conf_set_flag_slot,
114 0,
115 offsetof(ngx_event_conf_t, multi_accept),
116 NULL },
117
Igor Sysoevdbb27762004-04-01 16:20:53 +0000118 { ngx_string("accept_mutex"),
119 NGX_EVENT_CONF|NGX_CONF_TAKE1,
120 ngx_conf_set_flag_slot,
121 0,
122 offsetof(ngx_event_conf_t, accept_mutex),
123 NULL },
124
Igor Sysoev9a864bd2004-04-04 20:32:09 +0000125 { ngx_string("accept_mutex_delay"),
126 NGX_EVENT_CONF|NGX_CONF_TAKE1,
127 ngx_conf_set_msec_slot,
128 0,
129 offsetof(ngx_event_conf_t, accept_mutex_delay),
130 NULL },
131
Igor Sysoevfff32322004-04-08 15:58:25 +0000132 { ngx_string("debug_connection"),
133 NGX_EVENT_CONF|NGX_CONF_TAKE1,
134 ngx_event_debug_connection,
135 0,
136 0,
137 NULL },
138
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000139 ngx_null_command
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000140};
141
142
Igor Sysoev6abfde62003-07-01 15:00:03 +0000143ngx_event_module_t ngx_event_core_module_ctx = {
144 &event_core_name,
Igor Sysoeva9830112003-05-19 16:39:14 +0000145 ngx_event_create_conf, /* create configuration */
146 ngx_event_init_conf, /* init configuration */
147
148 { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
149};
150
151
Igor Sysoev6abfde62003-07-01 15:00:03 +0000152ngx_module_t ngx_event_core_module = {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000153 NGX_MODULE,
Igor Sysoev6abfde62003-07-01 15:00:03 +0000154 &ngx_event_core_module_ctx, /* module context */
155 ngx_event_core_commands, /* module directives */
Igor Sysoev6253ca12003-05-27 12:18:54 +0000156 NGX_EVENT_MODULE, /* module type */
Igor Sysoevdbb27762004-04-01 16:20:53 +0000157 ngx_event_module_init, /* init module */
158 ngx_event_process_init /* init process */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000159};
160
161
Igor Sysoevdbb27762004-04-01 16:20:53 +0000162static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle)
163{
Igor Sysoevdebb39e2004-04-02 05:14:40 +0000164#if !(WIN32)
Igor Sysoev407b0de2004-04-09 16:03:04 +0000165
166 size_t size;
167 char *shared;
Igor Sysoevdbb27762004-04-01 16:20:53 +0000168 ngx_core_conf_t *ccf;
169 ngx_event_conf_t *ecf;
170
171 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
172
Igor Sysoeva040f002004-04-23 16:50:51 +0000173 if (ccf->master == 0 || ngx_accept_mutex_ptr) {
Igor Sysoevdbb27762004-04-01 16:20:53 +0000174 return NGX_OK;
175 }
176
177 ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
178
Igor Sysoevdbb27762004-04-01 16:20:53 +0000179
Igor Sysoev407b0de2004-04-09 16:03:04 +0000180 /* TODO: 128 is cache line size */
Igor Sysoevdbb27762004-04-01 16:20:53 +0000181
Igor Sysoev407b0de2004-04-09 16:03:04 +0000182 size = 128 /* ngx_accept_mutex */
183 + 128; /* ngx_connection_counter */
184
185 shared = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
186
187 if (shared == NULL) {
Igor Sysoevdbb27762004-04-01 16:20:53 +0000188 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
189 "mmap(MAP_ANON|MAP_SHARED) failed");
190 return NGX_ERROR;
191 }
Igor Sysoev407b0de2004-04-09 16:03:04 +0000192
193 if (ecf->accept_mutex) {
194 ngx_accept_mutex_ptr = (ngx_atomic_t *) shared;
195 }
196
197 ngx_connection_counter = (ngx_atomic_t *) (shared + 128);
198
Igor Sysoeva040f002004-04-23 16:50:51 +0000199 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
200 "counter: " PTR_FMT ", %d",
201 ngx_connection_counter, *ngx_connection_counter);
202
Igor Sysoevdebb39e2004-04-02 05:14:40 +0000203#endif
Igor Sysoevdbb27762004-04-01 16:20:53 +0000204
205 return NGX_OK;
206}
207
208
209static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000210{
Igor Sysoev10a543a2004-03-16 07:10:12 +0000211 ngx_uint_t m, i;
212 ngx_socket_t fd;
Igor Sysoev239baac2003-06-11 15:28:34 +0000213 ngx_event_t *rev, *wev;
214 ngx_listening_t *s;
Igor Sysoev13933252003-05-29 13:02:09 +0000215 ngx_connection_t *c;
Igor Sysoevdbb27762004-04-01 16:20:53 +0000216 ngx_core_conf_t *ccf;
Igor Sysoev13933252003-05-29 13:02:09 +0000217 ngx_event_conf_t *ecf;
Igor Sysoeva9830112003-05-19 16:39:14 +0000218 ngx_event_module_t *module;
Igor Sysoev239baac2003-06-11 15:28:34 +0000219#if (WIN32)
220 ngx_iocp_conf_t *iocpcf;
221#endif
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000222
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000223
Igor Sysoevdbb27762004-04-01 16:20:53 +0000224 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
Igor Sysoev9a864bd2004-04-04 20:32:09 +0000225 ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
Igor Sysoevdbb27762004-04-01 16:20:53 +0000226
227 if (ccf->worker_processes > 1 && ngx_accept_mutex_ptr) {
228 ngx_accept_mutex = ngx_accept_mutex_ptr;
229 ngx_accept_mutex_held = 1;
Igor Sysoev9a864bd2004-04-04 20:32:09 +0000230 ngx_accept_mutex_delay = ecf->accept_mutex_delay;
Igor Sysoevdbb27762004-04-01 16:20:53 +0000231 }
232
Igor Sysoevea17edc2004-03-02 21:14:37 +0000233#if (NGX_THREADS)
234 if (!(ngx_posted_events_mutex = ngx_mutex_init(cycle->log, 0))) {
235 return NGX_ERROR;
236 }
237#endif
238
Igor Sysoevf2334412004-02-25 20:16:15 +0000239 if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
240 return NGX_ERROR;
241 }
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000242
Igor Sysoev9d639522003-07-07 06:11:50 +0000243 cycle->connection_n = ecf->connections;
244
Igor Sysoeva9830112003-05-19 16:39:14 +0000245 for (m = 0; ngx_modules[m]; m++) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000246 if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
Igor Sysoeva9830112003-05-19 16:39:14 +0000247 continue;
248 }
249
Igor Sysoev6253ca12003-05-27 12:18:54 +0000250 if (ngx_modules[m]->ctx_index == ecf->use) {
251 module = ngx_modules[m]->ctx;
Igor Sysoev340b03b2003-07-04 15:10:33 +0000252 if (module->actions.init(cycle) == NGX_ERROR) {
Igor Sysoev10318a22004-01-29 21:45:01 +0000253 /* fatal */
254 exit(2);
Igor Sysoeva9830112003-05-19 16:39:14 +0000255 }
256 break;
257 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000258 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000259
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000260 cycle->connections = ngx_alloc(sizeof(ngx_connection_t) * ecf->connections,
261 cycle->log);
262 if (cycle->connections == NULL) {
263 return NGX_ERROR;
Igor Sysoevbe3c2b62003-07-04 06:03:52 +0000264 }
265
Igor Sysoev9d639522003-07-07 06:11:50 +0000266 c = cycle->connections;
267 for (i = 0; i < cycle->connection_n; i++) {
Igor Sysoev10a543a2004-03-16 07:10:12 +0000268 c[i].fd = (ngx_socket_t) -1;
Igor Sysoev9d639522003-07-07 06:11:50 +0000269 }
270
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000271 cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections,
272 cycle->log);
273 if (cycle->read_events == NULL) {
274 return NGX_ERROR;
275 }
Igor Sysoeva9830112003-05-19 16:39:14 +0000276
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000277 cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections,
278 cycle->log);
279 if (cycle->write_events == NULL) {
280 return NGX_ERROR;
281 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000282
283 /* for each listening socket */
Igor Sysoev239baac2003-06-11 15:28:34 +0000284
Igor Sysoev9d639522003-07-07 06:11:50 +0000285 s = cycle->listening.elts;
286 for (i = 0; i < cycle->listening.nelts; i++) {
Igor Sysoev2b542382002-08-20 14:48:28 +0000287
288 fd = s[i].fd;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000289
Igor Sysoev239baac2003-06-11 15:28:34 +0000290#if (WIN32)
291 /*
292 * Winsock assignes a socket number divisible by 4
293 * so to find a connection we divide a socket number by 4.
294 */
295
Igor Sysoev9d639522003-07-07 06:11:50 +0000296 fd /= 4;
Igor Sysoev239baac2003-06-11 15:28:34 +0000297#endif
Igor Sysoeva6717c42002-12-23 06:29:22 +0000298
Igor Sysoev9d639522003-07-07 06:11:50 +0000299 c = &cycle->connections[fd];
300 rev = &cycle->read_events[fd];
301 wev = &cycle->write_events[fd];
302
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000303 ngx_memzero(c, sizeof(ngx_connection_t));
Igor Sysoev239baac2003-06-11 15:28:34 +0000304 ngx_memzero(rev, sizeof(ngx_event_t));
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000305
Igor Sysoev9d639522003-07-07 06:11:50 +0000306 c->fd = s[i].fd;
Igor Sysoev239baac2003-06-11 15:28:34 +0000307 c->listening = &s[i];
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000308
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000309 c->ctx = s[i].ctx;
310 c->servers = s[i].servers;
311 c->log = s[i].log;
Igor Sysoev9d639522003-07-07 06:11:50 +0000312 c->read = rev;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000313
Igor Sysoev9d639522003-07-07 06:11:50 +0000314 /* required by iocp in "c->write->active = 1" */
315 c->write = wev;
316
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000317 /* required by poll */
318 wev->index = NGX_INVALID_INDEX;
319
Igor Sysoev9d639522003-07-07 06:11:50 +0000320 rev->log = c->log;
Igor Sysoev239baac2003-06-11 15:28:34 +0000321 rev->data = c;
322 rev->index = NGX_INVALID_INDEX;
Igor Sysoev9d639522003-07-07 06:11:50 +0000323
Igor Sysoev239baac2003-06-11 15:28:34 +0000324 rev->available = 0;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000325
Igor Sysoev709405b2004-03-31 15:26:46 +0000326 rev->accept = 1;
327
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000328#if (HAVE_DEFERRED_ACCEPT)
Igor Sysoev239baac2003-06-11 15:28:34 +0000329 rev->deferred_accept = s[i].deferred_accept;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000330#endif
Igor Sysoev73009772003-02-06 17:21:13 +0000331
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000332 if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
Igor Sysoev9d639522003-07-07 06:11:50 +0000333 if (s[i].remain) {
334
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000335 /*
336 * delete the old accept events that were bound to
337 * the old cycle read events array
338 */
339
Igor Sysoev9d639522003-07-07 06:11:50 +0000340 if (ngx_del_event(&cycle->old_cycle->read_events[fd],
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000341 NGX_READ_EVENT, NGX_CLOSE_EVENT) == NGX_ERROR)
342 {
Igor Sysoev9d639522003-07-07 06:11:50 +0000343 return NGX_ERROR;
344 }
345
Igor Sysoev10a543a2004-03-16 07:10:12 +0000346 cycle->old_cycle->connections[fd].fd = (ngx_socket_t) -1;
Igor Sysoev9d639522003-07-07 06:11:50 +0000347 }
348 }
349
Igor Sysoev239baac2003-06-11 15:28:34 +0000350#if (WIN32)
Igor Sysoev73009772003-02-06 17:21:13 +0000351
Igor Sysoev0a280a32003-10-12 16:49:16 +0000352 if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
Igor Sysoev239baac2003-06-11 15:28:34 +0000353 rev->event_handler = &ngx_event_acceptex;
Igor Sysoev73009772003-02-06 17:21:13 +0000354
Igor Sysoev239baac2003-06-11 15:28:34 +0000355 if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {
Igor Sysoev73009772003-02-06 17:21:13 +0000356 return NGX_ERROR;
357 }
358
Igor Sysoev9d639522003-07-07 06:11:50 +0000359 iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
Igor Sysoev3646a162004-03-14 20:46:25 +0000360 if (ngx_event_post_acceptex(&s[i], iocpcf->post_acceptex)
361 == NGX_ERROR)
362 {
Igor Sysoev239baac2003-06-11 15:28:34 +0000363 return NGX_ERROR;
364 }
Igor Sysoev73009772003-02-06 17:21:13 +0000365
366 } else {
Igor Sysoev239baac2003-06-11 15:28:34 +0000367 rev->event_handler = &ngx_event_accept;
Igor Sysoev709405b2004-03-31 15:26:46 +0000368 if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
369 return NGX_ERROR;
370 }
Igor Sysoev73009772003-02-06 17:21:13 +0000371 }
372
373#else
374
Igor Sysoev239baac2003-06-11 15:28:34 +0000375 rev->event_handler = &ngx_event_accept;
Igor Sysoev9139cd22004-02-17 17:53:12 +0000376
377 if (ngx_event_flags & NGX_USE_SIGIO_EVENT) {
Igor Sysoev709405b2004-03-31 15:26:46 +0000378 if (ngx_add_conn(c) == NGX_ERROR) {
379 return NGX_ERROR;
380 }
Igor Sysoev9139cd22004-02-17 17:53:12 +0000381 } else {
Igor Sysoev709405b2004-03-31 15:26:46 +0000382 if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
383 return NGX_ERROR;
384 }
Igor Sysoev9139cd22004-02-17 17:53:12 +0000385 }
Igor Sysoev73009772003-02-06 17:21:13 +0000386
387#endif
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000388 }
Igor Sysoeva9830112003-05-19 16:39:14 +0000389
390 return NGX_OK;
Igor Sysoev2b542382002-08-20 14:48:28 +0000391}
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000392
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000393
Igor Sysoev6253ca12003-05-27 12:18:54 +0000394static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000395{
Igor Sysoeva9830112003-05-19 16:39:14 +0000396 int m;
397 char *rv;
398 void ***ctx;
399 ngx_conf_t pcf;
Igor Sysoeva9830112003-05-19 16:39:14 +0000400 ngx_event_module_t *module;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000401
Igor Sysoeva9830112003-05-19 16:39:14 +0000402 /* count the number of the event modules and set up their indices */
403
404 ngx_event_max_module = 0;
405 for (m = 0; ngx_modules[m]; m++) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000406 if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
Igor Sysoeva9830112003-05-19 16:39:14 +0000407 continue;
408 }
409
Igor Sysoev6253ca12003-05-27 12:18:54 +0000410 ngx_modules[m]->ctx_index = ngx_event_max_module++;
Igor Sysoeva9830112003-05-19 16:39:14 +0000411 }
412
413 ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(void *)), NGX_CONF_ERROR);
414
415 ngx_test_null(*ctx,
416 ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *)),
417 NGX_CONF_ERROR);
418
419 *(void **) conf = ctx;
420
421 for (m = 0; ngx_modules[m]; m++) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000422 if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
Igor Sysoeva9830112003-05-19 16:39:14 +0000423 continue;
424 }
425
426 module = ngx_modules[m]->ctx;
427
428 if (module->create_conf) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000429 ngx_test_null((*ctx)[ngx_modules[m]->ctx_index],
Igor Sysoev9d639522003-07-07 06:11:50 +0000430 module->create_conf(cf->cycle),
Igor Sysoeva9830112003-05-19 16:39:14 +0000431 NGX_CONF_ERROR);
432 }
433 }
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000434
435 pcf = *cf;
Igor Sysoeva9830112003-05-19 16:39:14 +0000436 cf->ctx = ctx;
Igor Sysoev6253ca12003-05-27 12:18:54 +0000437 cf->module_type = NGX_EVENT_MODULE;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000438 cf->cmd_type = NGX_EVENT_CONF;
439 rv = ngx_conf_parse(cf, NULL);
440 *cf = pcf;
441
442 if (rv != NGX_CONF_OK)
443 return rv;
444
Igor Sysoeva9830112003-05-19 16:39:14 +0000445 for (m = 0; ngx_modules[m]; m++) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000446 if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
Igor Sysoeva9830112003-05-19 16:39:14 +0000447 continue;
448 }
449
450 module = ngx_modules[m]->ctx;
451
452 if (module->init_conf) {
Igor Sysoev9d639522003-07-07 06:11:50 +0000453 rv = module->init_conf(cf->cycle,
454 (*ctx)[ngx_modules[m]->ctx_index]);
Igor Sysoeva9830112003-05-19 16:39:14 +0000455 if (rv != NGX_CONF_OK) {
456 return rv;
457 }
458 }
459 }
460
461 return NGX_CONF_OK;
462}
463
464
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000465static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd,
466 void *conf)
467{
468 ngx_event_conf_t *ecf = conf;
469
470 ngx_str_t *value;
471
Igor Sysoev732a2712004-04-21 18:54:33 +0000472 if (ecf->connections != NGX_CONF_UNSET_UINT) {
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000473 return "is duplicate" ;
474 }
475
476 value = cf->args->elts;
477 ecf->connections = ngx_atoi(value[1].data, value[1].len);
Igor Sysoev732a2712004-04-21 18:54:33 +0000478 if (ecf->connections == (ngx_uint_t) NGX_ERROR) {
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000479 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
480 "invalid number \"%s\"", value[1].data);
481
482 return NGX_CONF_ERROR;
483 }
484
485 cf->cycle->connection_n = ecf->connections;
486
487 return NGX_CONF_OK;
488}
489
490
Igor Sysoev6253ca12003-05-27 12:18:54 +0000491static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoeva9830112003-05-19 16:39:14 +0000492{
Igor Sysoev6253ca12003-05-27 12:18:54 +0000493 ngx_event_conf_t *ecf = conf;
Igor Sysoeva9830112003-05-19 16:39:14 +0000494
Igor Sysoeve9b2cb12004-02-09 20:47:18 +0000495 ngx_int_t m;
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000496 ngx_str_t *value;
497 ngx_event_conf_t *old_ecf;
Igor Sysoeva9830112003-05-19 16:39:14 +0000498 ngx_event_module_t *module;
499
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000500 if (ecf->use != NGX_CONF_UNSET) {
501 return "is duplicate" ;
Igor Sysoeva9830112003-05-19 16:39:14 +0000502 }
503
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000504 value = cf->args->elts;
505
Igor Sysoev0911f772004-01-14 18:19:42 +0000506 if (cf->cycle->old_cycle->conf_ctx) {
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000507 old_ecf = ngx_event_get_conf(cf->cycle->old_cycle->conf_ctx,
508 ngx_event_core_module);
509 } else {
510 old_ecf = NULL;
511 }
Igor Sysoeva9830112003-05-19 16:39:14 +0000512
Igor Sysoev25b36fe2004-02-03 16:43:54 +0000513
Igor Sysoeva9830112003-05-19 16:39:14 +0000514 for (m = 0; ngx_modules[m]; m++) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000515 if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
Igor Sysoeva9830112003-05-19 16:39:14 +0000516 continue;
517 }
518
519 module = ngx_modules[m]->ctx;
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000520 if (module->name->len == value[1].len) {
521 if (ngx_strcmp(module->name->data, value[1].data) == 0) {
Igor Sysoev6253ca12003-05-27 12:18:54 +0000522 ecf->use = ngx_modules[m]->ctx_index;
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000523 ecf->name = module->name->data;
524
Igor Sysoev25b36fe2004-02-03 16:43:54 +0000525 if (ngx_process == NGX_PROCESS_SINGLE
526 && old_ecf
527 && old_ecf->use != ecf->use)
528 {
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000529 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev25b36fe2004-02-03 16:43:54 +0000530 "when the server runs without a master process "
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000531 "the \"%s\" event type must be the same as "
532 "in previous configuration - \"%s\" "
533 "and it can not be changed on the fly, "
534 "to change it you need to stop server "
535 "and start it again",
536 value[1].data, old_ecf->name);
Igor Sysoev25b36fe2004-02-03 16:43:54 +0000537
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000538 return NGX_CONF_ERROR;
539 }
540
Igor Sysoeva9830112003-05-19 16:39:14 +0000541 return NGX_CONF_OK;
542 }
543 }
544 }
545
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000546 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
547 "invalid event type \"%s\"", value[1].data);
548
549 return NGX_CONF_ERROR;
Igor Sysoeva9830112003-05-19 16:39:14 +0000550}
551
552
Igor Sysoevfff32322004-04-08 15:58:25 +0000553static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd,
554 void *conf)
555{
556#if (NGX_DEBUG)
557 ngx_event_conf_t *ecf = conf;
558
559 in_addr_t *addr;
560 ngx_str_t *value;
561 struct hostent *h;
562
563 value = cf->args->elts;
564
565 /* AF_INET only */
566
567 if (!(addr = ngx_push_array(&ecf->debug_connection))) {
568 return NGX_CONF_ERROR;
569 }
570
571 *addr = inet_addr((char *) value[1].data);
572
573 if (*addr != INADDR_NONE) {
574 return NGX_OK;
575 }
576
577 h = gethostbyname((char *) value[1].data);
578
579 if (h == NULL || h->h_addr_list[0] == NULL) {
580 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
581 "host %s not found", value[1].data);
582 return NGX_CONF_ERROR;
583 }
584
585 *addr = *(in_addr_t *)(h->h_addr_list[0]);
586
587#else
588
589 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
590 "\"debug_connection\" is ignored, you need to rebuild "
591 "nginx using --with-debug option to enable it");
592
593#endif
594
595 return NGX_OK;
596}
597
598
Igor Sysoev9d639522003-07-07 06:11:50 +0000599static void *ngx_event_create_conf(ngx_cycle_t *cycle)
Igor Sysoeva9830112003-05-19 16:39:14 +0000600{
601 ngx_event_conf_t *ecf;
602
Igor Sysoev9d639522003-07-07 06:11:50 +0000603 ngx_test_null(ecf, ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t)),
Igor Sysoeva9830112003-05-19 16:39:14 +0000604 NGX_CONF_ERROR);
605
Igor Sysoev732a2712004-04-21 18:54:33 +0000606 ecf->connections = NGX_CONF_UNSET_UINT;
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000607 ecf->use = NGX_CONF_UNSET;
Igor Sysoeva4b16df2004-02-02 21:19:52 +0000608 ecf->multi_accept = NGX_CONF_UNSET;
Igor Sysoevdbb27762004-04-01 16:20:53 +0000609 ecf->accept_mutex = NGX_CONF_UNSET;
Igor Sysoev9a864bd2004-04-04 20:32:09 +0000610 ecf->accept_mutex_delay = NGX_CONF_UNSET_MSEC;
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000611 ecf->name = (void *) NGX_CONF_UNSET;
Igor Sysoeva9830112003-05-19 16:39:14 +0000612
Igor Sysoevfff32322004-04-08 15:58:25 +0000613#if (NGX_DEBUG)
614 ngx_init_array(ecf->debug_connection, cycle->pool, 5, sizeof(in_addr_t),
615 NGX_CONF_ERROR);
616#endif
617
Igor Sysoeva9830112003-05-19 16:39:14 +0000618 return ecf;
619}
620
621
Igor Sysoev9d639522003-07-07 06:11:50 +0000622static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
Igor Sysoeva9830112003-05-19 16:39:14 +0000623{
624 ngx_event_conf_t *ecf = conf;
625
626#if (HAVE_KQUEUE)
627
Igor Sysoev732a2712004-04-21 18:54:33 +0000628 ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS);
Igor Sysoev6253ca12003-05-27 12:18:54 +0000629 ngx_conf_init_value(ecf->use, ngx_kqueue_module.ctx_index);
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000630 ngx_conf_init_ptr_value(ecf->name, ngx_kqueue_module_ctx.name->data);
Igor Sysoeva9830112003-05-19 16:39:14 +0000631
Igor Sysoev1c13c662003-05-20 15:37:55 +0000632#elif (HAVE_DEVPOLL)
633
Igor Sysoev732a2712004-04-21 18:54:33 +0000634 ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS);
Igor Sysoev6253ca12003-05-27 12:18:54 +0000635 ngx_conf_init_value(ecf->use, ngx_devpoll_module.ctx_index);
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000636 ngx_conf_init_ptr_value(ecf->name, ngx_devpoll_module_ctx.name->data);
Igor Sysoev1c13c662003-05-20 15:37:55 +0000637
Igor Sysoev7af6b162004-02-09 07:46:43 +0000638#elif (HAVE_EPOLL)
639
Igor Sysoev732a2712004-04-21 18:54:33 +0000640 ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS);
Igor Sysoev7af6b162004-02-09 07:46:43 +0000641 ngx_conf_init_value(ecf->use, ngx_epoll_module.ctx_index);
642 ngx_conf_init_ptr_value(ecf->name, ngx_epoll_module_ctx.name->data);
643
Igor Sysoeve9b2cb12004-02-09 20:47:18 +0000644#elif (HAVE_SELECT)
Igor Sysoeva9830112003-05-19 16:39:14 +0000645
Igor Sysoev732a2712004-04-21 18:54:33 +0000646 ngx_conf_init_unsigned_value(ecf->connections,
Igor Sysoev340b03b2003-07-04 15:10:33 +0000647 FD_SETSIZE < DEFAULT_CONNECTIONS ? FD_SETSIZE : DEFAULT_CONNECTIONS);
Igor Sysoeva9830112003-05-19 16:39:14 +0000648
Igor Sysoev6253ca12003-05-27 12:18:54 +0000649 ngx_conf_init_value(ecf->use, ngx_select_module.ctx_index);
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000650 ngx_conf_init_ptr_value(ecf->name, ngx_select_module_ctx.name->data);
Igor Sysoeva9830112003-05-19 16:39:14 +0000651
Igor Sysoeve9b2cb12004-02-09 20:47:18 +0000652#else
653
654 ngx_int_t i, m;
655 ngx_event_module_t *module;
656
657 m = -1;
658 module = NULL;
659
660 for (i = 0; ngx_modules[i]; i++) {
661 if (ngx_modules[i]->type == NGX_EVENT_MODULE) {
662 module = ngx_modules[i]->ctx;
663
664 if (ngx_strcmp(module->name->data, event_core_name.data) == 0) {
665 continue;
666 }
667
668 m = ngx_modules[i]->ctx_index;
669 break;
670 }
671 }
672
673 if (m == -1) {
674 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "no events module found");
675 return NGX_CONF_ERROR;
676 }
677
678 ngx_conf_init_value(ecf->connections, DEFAULT_CONNECTIONS);
679
680 ngx_conf_init_value(ecf->use, m);
681 ngx_conf_init_ptr_value(ecf->name, module->name->data);
682
Igor Sysoeva9830112003-05-19 16:39:14 +0000683#endif
684
Igor Sysoev2b58fbf2003-12-09 15:08:11 +0000685 cycle->connection_n = ecf->connections;
686
Igor Sysoevaf579222004-02-03 20:27:11 +0000687 ngx_conf_init_value(ecf->multi_accept, 0);
Igor Sysoevdbb27762004-04-01 16:20:53 +0000688 ngx_conf_init_value(ecf->accept_mutex, 1);
Igor Sysoev9a864bd2004-04-04 20:32:09 +0000689 ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);
Igor Sysoeva9830112003-05-19 16:39:14 +0000690
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +0000691 return NGX_CONF_OK;
692}