Mercurial > hg > nginx-vendor-0-8
comparison src/event/modules/ngx_select_module.c @ 112:408f195b3482 NGINX_0_3_3
nginx 0.3.3
*) Change: the "bl" and "af" parameters of the "listen" directive was
renamed to the "backlog" and "accept_filter".
*) Feature: the "rcvbuf" and "sndbuf" parameters of the "listen"
directive.
*) Change: the "$msec" log parameter does not require now the
additional the gettimeofday() system call.
*) Feature: the -t switch now tests the "listen" directives.
*) Bugfix: if the invalid address was specified in the "listen"
directive, then after the -HUP signal nginx left an open socket in
the CLOSED state.
*) Bugfix: the mime type may be incorrectly set to default value for
index file with variable in the name; bug appeared in 0.3.0.
*) Feature: the "timer_resolution" directive.
*) Feature: the millisecond "$upstream_response_time" log parameter.
*) Bugfix: a temporary file with client request body now is removed
just after the response header was transferred to a client.
*) Bugfix: OpenSSL 0.9.6 compatibility.
*) Bugfix: the SSL certificate and key file paths could not be relative.
*) Bugfix: the "ssl_prefer_server_ciphers" directive did not work in
the ngx_imap_ssl_module.
*) Bugfix: the "ssl_protocols" directive allowed to specify the single
protocol only.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 19 Oct 2005 00:00:00 +0400 |
parents | 45f7329b4bd0 |
children | e38f51cd0905 |
comparison
equal
deleted
inserted
replaced
111:a175b609c76d | 112:408f195b3482 |
---|---|
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 | 10 |
11 | 11 |
12 | 12 |
13 static ngx_int_t ngx_select_init(ngx_cycle_t *cycle); | 13 static ngx_int_t ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer); |
14 static void ngx_select_done(ngx_cycle_t *cycle); | 14 static void ngx_select_done(ngx_cycle_t *cycle); |
15 static ngx_int_t ngx_select_add_event(ngx_event_t *ev, int event, u_int flags); | 15 static ngx_int_t ngx_select_add_event(ngx_event_t *ev, int event, u_int flags); |
16 static ngx_int_t ngx_select_del_event(ngx_event_t *ev, int event, u_int flags); | 16 static ngx_int_t ngx_select_del_event(ngx_event_t *ev, int event, u_int flags); |
17 static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle); | 17 static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, |
18 ngx_uint_t flags); | |
18 static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf); | 19 static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf); |
19 | 20 |
20 | 21 |
21 static fd_set master_read_fd_set; | 22 static fd_set master_read_fd_set; |
22 static fd_set master_write_fd_set; | 23 static fd_set master_write_fd_set; |
31 #endif | 32 #endif |
32 | 33 |
33 static ngx_uint_t nevents; | 34 static ngx_uint_t nevents; |
34 | 35 |
35 static ngx_event_t **event_index; | 36 static ngx_event_t **event_index; |
36 #if 0 | |
37 static ngx_event_t **ready_index; | |
38 #endif | |
39 | |
40 static ngx_event_t *accept_events; | |
41 | 37 |
42 | 38 |
43 static ngx_str_t select_name = ngx_string("select"); | 39 static ngx_str_t select_name = ngx_string("select"); |
44 | 40 |
45 ngx_event_module_t ngx_select_module_ctx = { | 41 ngx_event_module_t ngx_select_module_ctx = { |
77 NGX_MODULE_V1_PADDING | 73 NGX_MODULE_V1_PADDING |
78 }; | 74 }; |
79 | 75 |
80 | 76 |
81 static ngx_int_t | 77 static ngx_int_t |
82 ngx_select_init(ngx_cycle_t *cycle) | 78 ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer) |
83 { | 79 { |
84 ngx_event_t **index; | 80 ngx_event_t **index; |
85 | 81 |
86 if (event_index == NULL) { | 82 if (event_index == NULL) { |
87 FD_ZERO(&master_read_fd_set); | 83 FD_ZERO(&master_read_fd_set); |
101 | 97 |
102 if (event_index) { | 98 if (event_index) { |
103 ngx_memcpy(index, event_index, sizeof(ngx_event_t *) * nevents); | 99 ngx_memcpy(index, event_index, sizeof(ngx_event_t *) * nevents); |
104 ngx_free(event_index); | 100 ngx_free(event_index); |
105 } | 101 } |
102 | |
106 event_index = index; | 103 event_index = index; |
107 | |
108 #if 0 | |
109 if (ready_index) { | |
110 ngx_free(ready_index); | |
111 } | |
112 | |
113 ready_index = ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n, | |
114 cycle->log); | |
115 if (ready_index == NULL) { | |
116 return NGX_ERROR; | |
117 } | |
118 #endif | |
119 } | 104 } |
120 | 105 |
121 ngx_io = ngx_os_io; | 106 ngx_io = ngx_os_io; |
122 | 107 |
123 ngx_event_actions = ngx_select_module_ctx.actions; | 108 ngx_event_actions = ngx_select_module_ctx.actions; |
124 | 109 |
125 ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_ONESHOT_EVENT; | 110 ngx_event_flags = NGX_USE_LEVEL_EVENT; |
126 | 111 |
127 #if (NGX_WIN32) | 112 #if (NGX_WIN32) |
128 max_read = max_write = 0; | 113 max_read = max_write = 0; |
129 #else | 114 #else |
130 max_fd = -1; | 115 max_fd = -1; |
136 | 121 |
137 static void | 122 static void |
138 ngx_select_done(ngx_cycle_t *cycle) | 123 ngx_select_done(ngx_cycle_t *cycle) |
139 { | 124 { |
140 ngx_free(event_index); | 125 ngx_free(event_index); |
141 #if 0 | |
142 ngx_free(ready_index); | |
143 #endif | |
144 | 126 |
145 event_index = NULL; | 127 event_index = NULL; |
146 } | 128 } |
147 | 129 |
148 | 130 |
260 return NGX_OK; | 242 return NGX_OK; |
261 } | 243 } |
262 | 244 |
263 | 245 |
264 static ngx_int_t | 246 static ngx_int_t |
265 ngx_select_process_events(ngx_cycle_t *cycle) | 247 ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, |
266 { | 248 ngx_uint_t flags) |
267 int ready, nready; | 249 { |
268 ngx_uint_t i, found, lock; | 250 int ready, nready; |
269 ngx_err_t err; | 251 ngx_uint_t i, found; |
270 ngx_msec_t timer, delta; | 252 ngx_err_t err; |
271 ngx_event_t *ev; | 253 ngx_msec_t delta; |
272 ngx_connection_t *c; | 254 ngx_event_t *ev, **queue; |
273 struct timeval tv, *tp; | 255 ngx_connection_t *c; |
274 #if (NGX_HAVE_SELECT_CHANGE_TIMEOUT) | 256 struct timeval tv, *tp; |
275 static ngx_msec_t deltas = 0; | |
276 #endif | |
277 | |
278 timer = ngx_event_find_timer(); | |
279 | |
280 #if !(NGX_WIN32) | 257 #if !(NGX_WIN32) |
281 | 258 ngx_uint_t level; |
282 if (ngx_accept_mutex) { | 259 #endif |
283 if (ngx_accept_disabled > 0) { | 260 |
284 ngx_accept_disabled--; | 261 #if !(NGX_WIN32) |
285 | |
286 } else { | |
287 if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { | |
288 return NGX_ERROR; | |
289 } | |
290 | |
291 if (ngx_accept_mutex_held == 0 | |
292 && (timer == NGX_TIMER_INFINITE | |
293 || timer > ngx_accept_mutex_delay)) | |
294 { | |
295 timer = ngx_accept_mutex_delay; | |
296 } | |
297 } | |
298 } | |
299 | 262 |
300 if (max_fd == -1) { | 263 if (max_fd == -1) { |
301 for (i = 0; i < nevents; i++) { | 264 for (i = 0; i < nevents; i++) { |
302 c = event_index[i]->data; | 265 c = event_index[i]->data; |
303 if (max_fd < c->fd) { | 266 if (max_fd < c->fd) { |
351 "select read fd_set: %08Xd", | 314 "select read fd_set: %08Xd", |
352 *(int *) (void *) &work_read_fd_set); | 315 *(int *) (void *) &work_read_fd_set); |
353 #endif | 316 #endif |
354 | 317 |
355 #if (NGX_WIN32) | 318 #if (NGX_WIN32) |
319 | |
356 ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp); | 320 ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp); |
357 #else | 321 |
322 #else | |
323 | |
358 ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp); | 324 ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp); |
325 | |
359 #endif | 326 #endif |
360 | 327 |
361 if (ready == -1) { | 328 if (ready == -1) { |
362 err = ngx_socket_errno; | 329 err = ngx_socket_errno; |
363 } else { | 330 } else { |
364 err = 0; | 331 err = 0; |
365 } | 332 } |
366 | 333 |
367 #if (NGX_HAVE_SELECT_CHANGE_TIMEOUT) | 334 delta = ngx_current_msec; |
335 | |
336 if (flags & NGX_UPDATE_TIME) { | |
337 ngx_time_update(0, 0); | |
338 } | |
368 | 339 |
369 if (timer != NGX_TIMER_INFINITE) { | 340 if (timer != NGX_TIMER_INFINITE) { |
370 delta = timer - ((ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000); | 341 delta = ngx_current_msec - delta; |
371 | |
372 /* | |
373 * learn the real time and update the cached time | |
374 * if the sum of the last deltas overcomes 1 second | |
375 */ | |
376 | |
377 deltas += delta; | |
378 if (deltas > 1000) { | |
379 ngx_gettimeofday(&tv); | |
380 ngx_time_update(tv.tv_sec); | |
381 deltas = tv.tv_usec / 1000; | |
382 | |
383 ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 | |
384 + tv.tv_usec / 1000; | |
385 } else { | |
386 ngx_current_time += delta; | |
387 } | |
388 | |
389 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
390 "select timer: %M, delta: %M", timer, delta); | |
391 | |
392 } else { | |
393 deltas = 0; | |
394 | |
395 ngx_gettimeofday(&tv); | |
396 ngx_time_update(tv.tv_sec); | |
397 | |
398 delta = ngx_current_time; | |
399 ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; | |
400 | |
401 if (ready == 0) { | |
402 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
403 "select() returned no events without timeout"); | |
404 ngx_accept_mutex_unlock(); | |
405 return NGX_ERROR; | |
406 } | |
407 } | |
408 | |
409 #else /* !(NGX_HAVE_SELECT_CHANGE_TIMEOUT) */ | |
410 | |
411 ngx_gettimeofday(&tv); | |
412 ngx_time_update(tv.tv_sec); | |
413 | |
414 delta = ngx_current_time; | |
415 ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; | |
416 | |
417 if (timer != NGX_TIMER_INFINITE) { | |
418 delta = ngx_current_time - delta; | |
419 | 342 |
420 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 343 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
421 "select timer: %M, delta: %M", timer, delta); | 344 "select timer: %M, delta: %M", timer, delta); |
422 | 345 |
423 } else { | 346 } else { |
424 if (ready == 0) { | 347 if (ready == 0) { |
425 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | 348 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
426 "select() returned no events without timeout"); | 349 "select() returned no events without timeout"); |
427 ngx_accept_mutex_unlock(); | |
428 return NGX_ERROR; | 350 return NGX_ERROR; |
429 } | 351 } |
430 } | 352 } |
431 | |
432 #endif /* NGX_HAVE_SELECT_CHANGE_TIMEOUT */ | |
433 | 353 |
434 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 354 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
435 "select ready %d", ready); | 355 "select ready %d", ready); |
436 | 356 |
357 #if (NGX_WIN32) | |
358 | |
437 if (err) { | 359 if (err) { |
438 #if (NGX_WIN32) | |
439 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, "select() failed"); | 360 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, "select() failed"); |
440 #else | |
441 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, | |
442 cycle->log, err, "select() failed"); | |
443 #endif | |
444 ngx_accept_mutex_unlock(); | |
445 return NGX_ERROR; | 361 return NGX_ERROR; |
446 } | 362 } |
447 | 363 |
448 | 364 #else |
449 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { | 365 |
450 ngx_accept_mutex_unlock(); | 366 if (err) { |
367 if (err == NGX_EINTR) { | |
368 | |
369 if (ngx_event_timer_alarm) { | |
370 ngx_event_timer_alarm = 0; | |
371 return NGX_OK; | |
372 } | |
373 | |
374 level = NGX_LOG_INFO; | |
375 | |
376 } else { | |
377 level = NGX_LOG_ALERT; | |
378 } | |
379 | |
380 ngx_log_error(level, cycle->log, err, "select() failed"); | |
451 return NGX_ERROR; | 381 return NGX_ERROR; |
452 } | 382 } |
453 | 383 |
454 lock = 1; | 384 #endif |
385 | |
386 if (nevents == 0) { | |
387 return NGX_OK; | |
388 } | |
389 | |
390 ngx_mutex_lock(ngx_posted_events_mutex); | |
391 | |
455 nready = 0; | 392 nready = 0; |
456 | 393 |
457 for (i = 0; i < nevents; i++) { | 394 for (i = 0; i < nevents; i++) { |
458 ev = event_index[i]; | 395 ev = event_index[i]; |
459 c = ev->data; | 396 c = ev->data; |
475 } | 412 } |
476 | 413 |
477 if (found) { | 414 if (found) { |
478 ev->ready = 1; | 415 ev->ready = 1; |
479 | 416 |
480 if (ev->oneshot) { | 417 queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events: |
481 if (ev->timer_set) { | 418 &ngx_posted_events); |
482 ngx_del_timer(ev); | 419 ngx_locked_post_event(ev, queue); |
483 } | |
484 | |
485 if (ev->write) { | |
486 ngx_select_del_event(ev, NGX_WRITE_EVENT, 0); | |
487 } else { | |
488 ngx_select_del_event(ev, NGX_READ_EVENT, 0); | |
489 } | |
490 } | |
491 | |
492 if (ev->accept) { | |
493 ev->next = accept_events; | |
494 accept_events = ev; | |
495 } else { | |
496 ngx_post_event(ev); | |
497 } | |
498 | 420 |
499 nready++; | 421 nready++; |
500 | 422 } |
501 #if 0 | 423 } |
502 ready_index[nready++] = ev; | 424 |
503 #endif | 425 ngx_mutex_unlock(ngx_posted_events_mutex); |
504 } | |
505 } | |
506 | |
507 #if 0 | |
508 for (i = 0; i < nready; i++) { | |
509 ev = ready_index[i]; | |
510 ready--; | |
511 | |
512 if (!ev->active) { | |
513 continue; | |
514 } | |
515 | |
516 ev->ready = 1; | |
517 | |
518 if (ev->oneshot) { | |
519 if (ev->timer_set) { | |
520 ngx_del_timer(ev); | |
521 } | |
522 | |
523 if (ev->write) { | |
524 ngx_select_del_event(ev, NGX_WRITE_EVENT, 0); | |
525 } else { | |
526 ngx_select_del_event(ev, NGX_READ_EVENT, 0); | |
527 } | |
528 } | |
529 | |
530 ev->handler(ev); | |
531 } | |
532 #endif | |
533 | |
534 ev = accept_events; | |
535 | |
536 for ( ;; ) { | |
537 | |
538 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
539 "accept event %p", ev); | |
540 | |
541 if (ev == NULL) { | |
542 break; | |
543 } | |
544 | |
545 ngx_mutex_unlock(ngx_posted_events_mutex); | |
546 | |
547 ev->handler(ev); | |
548 | |
549 if (ngx_accept_disabled > 0) { | |
550 lock = 0; | |
551 break; | |
552 } | |
553 | |
554 ev = ev->next; | |
555 | |
556 if (ev == NULL) { | |
557 lock = 0; | |
558 break; | |
559 } | |
560 | |
561 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { | |
562 ngx_accept_mutex_unlock(); | |
563 return NGX_ERROR; | |
564 } | |
565 } | |
566 | |
567 ngx_accept_mutex_unlock(); | |
568 accept_events = NULL; | |
569 | |
570 if (lock) { | |
571 ngx_mutex_unlock(ngx_posted_events_mutex); | |
572 } | |
573 | 426 |
574 if (ready != nready) { | 427 if (ready != nready) { |
575 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "select ready != events"); | 428 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "select ready != events"); |
576 } | 429 } |
577 | 430 |
578 ngx_event_expire_timers(); | |
579 | |
580 if (!ngx_threaded) { | |
581 ngx_event_process_posted(cycle); | |
582 } | |
583 | |
584 return NGX_OK; | 431 return NGX_OK; |
585 } | 432 } |
586 | 433 |
587 | 434 |
588 static char * | 435 static char * |
597 } | 444 } |
598 | 445 |
599 /* disable warning: the default FD_SETSIZE is 1024U in FreeBSD 5.x */ | 446 /* disable warning: the default FD_SETSIZE is 1024U in FreeBSD 5.x */ |
600 | 447 |
601 #if !(NGX_WIN32) | 448 #if !(NGX_WIN32) |
449 | |
602 if ((unsigned) ecf->connections > FD_SETSIZE) { | 450 if ((unsigned) ecf->connections > FD_SETSIZE) { |
603 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, | 451 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, |
604 "the maximum number of files " | 452 "the maximum number of files " |
605 "supported by select() is " ngx_value(FD_SETSIZE)); | 453 "supported by select() is " ngx_value(FD_SETSIZE)); |
606 return NGX_CONF_ERROR; | 454 return NGX_CONF_ERROR; |
607 } | 455 } |
456 | |
608 #endif | 457 #endif |
609 | 458 |
610 #if (NGX_THREADS) && !(NGX_WIN32) | 459 #if (NGX_THREADS) && !(NGX_WIN32) |
460 | |
611 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, | 461 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, |
612 "select() is not supported in the threaded mode"); | 462 "select() is not supported in the threaded mode"); |
613 return NGX_CONF_ERROR; | 463 return NGX_CONF_ERROR; |
614 #else | 464 |
465 #else | |
466 | |
615 return NGX_CONF_OK; | 467 return NGX_CONF_OK; |
616 #endif | 468 |
617 } | 469 #endif |
470 } |