comparison src/event/modules/ngx_devpoll_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
29 u_int changes; 29 u_int changes;
30 u_int events; 30 u_int events;
31 } ngx_devpoll_conf_t; 31 } ngx_devpoll_conf_t;
32 32
33 33
34 static ngx_int_t ngx_devpoll_init(ngx_cycle_t *cycle); 34 static ngx_int_t ngx_devpoll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
35 static void ngx_devpoll_done(ngx_cycle_t *cycle); 35 static void ngx_devpoll_done(ngx_cycle_t *cycle);
36 static ngx_int_t ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags); 36 static ngx_int_t ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags);
37 static ngx_int_t ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags); 37 static ngx_int_t ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags);
38 static ngx_int_t ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags); 38 static ngx_int_t ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags);
39 static ngx_int_t ngx_devpoll_process_events(ngx_cycle_t *cycle); 39 static ngx_int_t ngx_devpoll_process_events(ngx_cycle_t *cycle,
40 ngx_msec_t timer, ngx_uint_t flags);
40 41
41 static void *ngx_devpoll_create_conf(ngx_cycle_t *cycle); 42 static void *ngx_devpoll_create_conf(ngx_cycle_t *cycle);
42 static char *ngx_devpoll_init_conf(ngx_cycle_t *cycle, void *conf); 43 static char *ngx_devpoll_init_conf(ngx_cycle_t *cycle, void *conf);
43 44
44 static int dp = -1; 45 static int dp = -1;
105 NGX_MODULE_V1_PADDING 106 NGX_MODULE_V1_PADDING
106 }; 107 };
107 108
108 109
109 static ngx_int_t 110 static ngx_int_t
110 ngx_devpoll_init(ngx_cycle_t *cycle) 111 ngx_devpoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
111 { 112 {
112 size_t n; 113 size_t n;
113 ngx_devpoll_conf_t *dpcf; 114 ngx_devpoll_conf_t *dpcf;
114 115
115 dpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_devpoll_module); 116 dpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_devpoll_module);
321 return NGX_OK; 322 return NGX_OK;
322 } 323 }
323 324
324 325
325 ngx_int_t 326 ngx_int_t
326 ngx_devpoll_process_events(ngx_cycle_t *cycle) 327 ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
328 ngx_uint_t flags)
327 { 329 {
328 int events, revents; 330 int events, revents;
329 size_t n; 331 size_t n;
330 ngx_err_t err; 332 ngx_err_t err;
331 ngx_int_t i; 333 ngx_int_t i;
332 ngx_uint_t lock, accept_lock; 334 ngx_uint_t level;
333 ngx_msec_t timer, delta; 335 ngx_msec_t delta;
334 #if 0 336 ngx_event_t *rev, *wev, **queue;
335 ngx_cycle_t **old_cycle;
336 #endif
337 ngx_event_t *rev, *wev;
338 ngx_connection_t *c; 337 ngx_connection_t *c;
339 struct dvpoll dvp; 338 struct dvpoll dvp;
340 struct timeval tv;
341
342 timer = ngx_event_find_timer();
343 339
344 /* NGX_TIMER_INFINITE == INFTIM */ 340 /* NGX_TIMER_INFINITE == INFTIM */
345
346 accept_lock = 0;
347
348 if (ngx_accept_mutex) {
349 if (ngx_accept_disabled > 0) {
350 ngx_accept_disabled--;
351
352 } else {
353 if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
354 return NGX_ERROR;
355 }
356
357 if (ngx_accept_mutex_held) {
358 accept_lock = 1;
359
360 } else if (timer == NGX_TIMER_INFINITE
361 || timer > ngx_accept_mutex_delay)
362 {
363 timer = ngx_accept_mutex_delay;
364 }
365 }
366 }
367 341
368 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 342 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
369 "devpoll timer: %M", timer); 343 "devpoll timer: %M", timer);
370 344
371 if (nchanges) { 345 if (nchanges) {
372 n = nchanges * sizeof(struct pollfd); 346 n = nchanges * sizeof(struct pollfd);
373 if (write(dp, change_list, n) != (ssize_t) n) { 347 if (write(dp, change_list, n) != (ssize_t) n) {
374 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, 348 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
375 "write(/dev/poll) failed"); 349 "write(/dev/poll) failed");
376 ngx_accept_mutex_unlock();
377 return NGX_ERROR; 350 return NGX_ERROR;
378 } 351 }
379 } 352 }
380 353
381 dvp.dp_fds = event_list; 354 dvp.dp_fds = event_list;
389 err = 0; 362 err = 0;
390 } 363 }
391 364
392 nchanges = 0; 365 nchanges = 0;
393 366
394 ngx_gettimeofday(&tv); 367 delta = ngx_current_msec;
395 ngx_time_update(tv.tv_sec); 368
396 369 if (flags & NGX_UPDATE_TIME) {
397 delta = ngx_current_time; 370 ngx_time_update(0, 0);
398 ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; 371 }
399 372
400 if (err) { 373 if (err) {
401 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, 374 if (err == NGX_EINTR) {
402 cycle->log, err, "ioctl(DP_POLL) failed"); 375
403 ngx_accept_mutex_unlock(); 376 if (ngx_event_timer_alarm) {
377 ngx_event_timer_alarm = 0;
378 return NGX_OK;
379 }
380
381 level = NGX_LOG_INFO;
382
383 } else {
384 level = NGX_LOG_ALERT;
385 }
386
387 ngx_log_error(level, cycle->log, err, "ioctl(DP_POLL) failed");
404 return NGX_ERROR; 388 return NGX_ERROR;
405 } 389 }
406 390
407 if (timer != NGX_TIMER_INFINITE) { 391 if (timer != NGX_TIMER_INFINITE) {
408 delta = ngx_current_time - delta; 392 delta = ngx_current_msec - delta;
409 393
410 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 394 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
411 "devpoll timer: %M, delta: %M", timer, delta); 395 "devpoll timer: %M, delta: %M", timer, delta);
412 } else { 396 } else {
413 if (events == 0) { 397 if (events == 0) {
414 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, 398 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
415 "ioctl(DP_POLL) returned no events without timeout"); 399 "ioctl(DP_POLL) returned no events without timeout");
416 ngx_accept_mutex_unlock(); 400 return NGX_ERROR;
417 return NGX_ERROR; 401 }
418 } 402 }
419 } 403
420 404 if (events == 0) {
421 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { 405 return NGX_OK;
422 ngx_accept_mutex_unlock(); 406 }
423 return NGX_ERROR; 407
424 } 408 ngx_mutex_lock(ngx_posted_events_mutex);
425
426 lock = 1;
427 409
428 for (i = 0; i < events; i++) { 410 for (i = 0; i < events; i++) {
429 c = ngx_cycle->files[event_list[i].fd]; 411 c = ngx_cycle->files[event_list[i].fd];
430 412
431 if (c->fd == -1) { 413 if (c->fd == -1) {
466 */ 448 */
467 449
468 revents |= POLLIN|POLLOUT; 450 revents |= POLLIN|POLLOUT;
469 } 451 }
470 452
453 rev = c->read;
454
455 if ((revents & POLLIN) && rev->active) {
456
457 if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
458 rev->posted_ready = 1;
459
460 } else {
461 rev->ready = 1;
462 }
463
464 if (flags & NGX_POST_EVENTS) {
465 queue = (ngx_event_t **) (rev->accept ?
466 &ngx_posted_accept_events : &ngx_posted_events);
467
468 ngx_locked_post_event(rev, queue);
469
470 } else {
471 rev->handler(rev);
472 }
473 }
474
471 wev = c->write; 475 wev = c->write;
472 476
473 if ((revents & POLLOUT) && wev->active) { 477 if ((revents & POLLOUT) && wev->active) {
474 wev->ready = 1; 478
475 479 if (flags & NGX_POST_THREAD_EVENTS) {
476 if (!ngx_threaded && !ngx_accept_mutex_held) { 480 wev->posted_ready = 1;
481
482 } else {
483 wev->ready = 1;
484 }
485
486 if (flags & NGX_POST_EVENTS) {
487 ngx_locked_post_event(wev, &ngx_posted_events);
488
489 } else {
477 wev->handler(wev); 490 wev->handler(wev);
478 491 }
479 } else { 492 }
480 ngx_post_event(wev); 493 }
481 } 494
482 } 495 ngx_mutex_unlock(ngx_posted_events_mutex);
483
484 /*
485 * POLLIN must be handled after POLLOUT because we use
486 * the optimization to avoid the unnecessary mutex locking/unlocking
487 * if the accept event is the last one.
488 */
489
490 rev = c->read;
491
492 if ((revents & POLLIN) && rev->active) {
493 rev->ready = 1;
494
495 if (!ngx_threaded && !ngx_accept_mutex_held) {
496 rev->handler(rev);
497
498 } else if (!rev->accept) {
499 ngx_post_event(rev);
500
501 } else if (ngx_accept_disabled <= 0) {
502 ngx_mutex_unlock(ngx_posted_events_mutex);
503
504 c->read->handler(rev);
505
506 if (ngx_accept_disabled > 0) {
507 ngx_accept_mutex_unlock();
508 accept_lock = 0;
509 }
510
511 if (i + 1 == events) {
512 lock = 0;
513 break;
514 }
515
516 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
517 if (accept_lock) {
518 ngx_accept_mutex_unlock();
519 }
520 return NGX_ERROR;
521 }
522 }
523 }
524 }
525
526 if (accept_lock) {
527 ngx_accept_mutex_unlock();
528 }
529
530 if (lock) {
531 ngx_mutex_unlock(ngx_posted_events_mutex);
532 }
533
534 ngx_event_expire_timers();
535
536 if (!ngx_threaded) {
537 ngx_event_process_posted(cycle);
538 }
539 496
540 return NGX_OK; 497 return NGX_OK;
541 } 498 }
542 499
543 500