Mercurial > hg > nginx
comparison src/event/modules/ngx_epoll_module.c @ 306:6b91bfbc4123
nginx-0.0.3-2004-04-05-00:32:09 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 04 Apr 2004 20:32:09 +0000 |
parents | 4b1a3a4acc60 |
children | 2e899477243a |
comparison
equal
deleted
inserted
replaced
305:4b1a3a4acc60 | 306:6b91bfbc4123 |
---|---|
166 ngx_io = ngx_os_io; | 166 ngx_io = ngx_os_io; |
167 | 167 |
168 ngx_event_actions = ngx_epoll_module_ctx.actions; | 168 ngx_event_actions = ngx_epoll_module_ctx.actions; |
169 | 169 |
170 #if (HAVE_CLEAR_EVENT) | 170 #if (HAVE_CLEAR_EVENT) |
171 ngx_event_flags = NGX_USE_CLEAR_EVENT; | 171 ngx_event_flags = NGX_USE_CLEAR_EVENT |
172 #else | 172 #else |
173 ngx_event_flags = NGX_USE_LEVEL_EVENT; | 173 ngx_event_flags = NGX_USE_LEVEL_EVENT |
174 #endif | 174 #endif |
175 |NGX_HAVE_INSTANCE_EVENT; | |
175 | 176 |
176 return NGX_OK; | 177 return NGX_OK; |
177 } | 178 } |
178 | 179 |
179 | 180 |
255 struct epoll_event ee; | 256 struct epoll_event ee; |
256 | 257 |
257 /* | 258 /* |
258 * when the file descriptor is closed the epoll automatically deletes | 259 * when the file descriptor is closed the epoll automatically deletes |
259 * it from its queue so we do not need to delete explicity the event | 260 * it from its queue so we do not need to delete explicity the event |
260 * before the closing the file descriptor. | 261 * before the closing the file descriptor |
261 */ | 262 */ |
262 | 263 |
263 if (flags & NGX_CLOSE_EVENT) { | 264 if (flags & NGX_CLOSE_EVENT) { |
264 ev->active = 0; | 265 ev->active = 0; |
265 return NGX_OK; | 266 return NGX_OK; |
337 #endif | 338 #endif |
338 | 339 |
339 | 340 |
340 int ngx_epoll_process_events(ngx_cycle_t *cycle) | 341 int ngx_epoll_process_events(ngx_cycle_t *cycle) |
341 { | 342 { |
342 int events; | 343 int events; |
343 ngx_int_t instance, i; | 344 ngx_int_t instance, i; |
344 size_t n; | 345 ngx_uint_t lock, expire; |
345 ngx_msec_t timer; | 346 size_t n; |
346 ngx_err_t err; | 347 ngx_msec_t timer; |
347 struct timeval tv; | 348 ngx_err_t err; |
348 ngx_connection_t *c; | 349 struct timeval tv; |
349 ngx_epoch_msec_t delta; | 350 ngx_connection_t *c; |
350 | 351 ngx_epoch_msec_t delta; |
351 | 352 |
352 timer = ngx_event_find_timer(); | 353 timer = ngx_event_find_timer(); |
353 ngx_old_elapsed_msec = ngx_elapsed_msec; | 354 ngx_old_elapsed_msec = ngx_elapsed_msec; |
354 | 355 |
355 if (timer == 0) { | 356 if (timer == 0) { |
356 timer = (ngx_msec_t) -1; | 357 timer = (ngx_msec_t) -1; |
358 expire = 0; | |
359 | |
360 } else { | |
361 expire = 1; | |
362 } | |
363 | |
364 if (ngx_accept_mutex) { | |
365 if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { | |
366 return NGX_ERROR; | |
367 } | |
368 | |
369 if (ngx_accept_mutex_held == 0 && timer > ngx_accept_mutex_delay) { | |
370 timer = ngx_accept_mutex_delay; | |
371 expire = 0; | |
372 } | |
357 } | 373 } |
358 | 374 |
359 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 375 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
360 "epoll timer: %d", timer); | 376 "epoll timer: %d", timer); |
361 | 377 |
380 "epoll timer: %d, delta: %d", timer, (int) delta); | 396 "epoll timer: %d, delta: %d", timer, (int) delta); |
381 } else { | 397 } else { |
382 if (events == 0) { | 398 if (events == 0) { |
383 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | 399 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
384 "epoll_wait() returned no events without timeout"); | 400 "epoll_wait() returned no events without timeout"); |
401 ngx_accept_mutex_unlock(); | |
385 return NGX_ERROR; | 402 return NGX_ERROR; |
386 } | 403 } |
387 } | 404 } |
388 | 405 |
389 if (err) { | 406 if (err) { |
390 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, | 407 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, |
391 cycle->log, err, "epoll_wait() failed"); | 408 cycle->log, err, "epoll_wait() failed"); |
409 ngx_accept_mutex_unlock(); | |
392 return NGX_ERROR; | 410 return NGX_ERROR; |
393 } | 411 } |
412 | |
413 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { | |
414 ngx_accept_mutex_unlock(); | |
415 return NGX_ERROR; | |
416 } | |
417 | |
418 lock = 1; | |
394 | 419 |
395 for (i = 0; i < events; i++) { | 420 for (i = 0; i < events; i++) { |
396 c = event_list[i].data.ptr; | 421 c = event_list[i].data.ptr; |
397 | 422 |
398 instance = (uintptr_t) c & 1; | 423 instance = (uintptr_t) c & 1; |
432 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | 457 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
433 "strange epoll_wait() events fd:%d ev:%04X", | 458 "strange epoll_wait() events fd:%d ev:%04X", |
434 c->fd, event_list[i].events); | 459 c->fd, event_list[i].events); |
435 } | 460 } |
436 | 461 |
462 if ((event_list[i].events & (EPOLLOUT|EPOLLERR|EPOLLHUP)) | |
463 && c->write->active) | |
464 { | |
465 c->write->ready = 1; | |
466 | |
467 if (!ngx_threaded && !ngx_accept_mutex_held) { | |
468 c->write->event_handler(c->write); | |
469 | |
470 } else { | |
471 ngx_post_event(c->write); | |
472 } | |
473 } | |
474 | |
475 /* | |
476 * EPOLLIN must be handled after EPOLLOUT because we use | |
477 * the optimization to avoid the unnecessary mutex locking/unlocking | |
478 * if the accept event is the last one. | |
479 */ | |
480 | |
437 if ((event_list[i].events & (EPOLLIN|EPOLLERR|EPOLLHUP)) | 481 if ((event_list[i].events & (EPOLLIN|EPOLLERR|EPOLLHUP)) |
438 && c->read->active) | 482 && c->read->active) |
439 { | 483 { |
440 c->read->ready = 1; | 484 c->read->ready = 1; |
441 c->read->event_handler(c->read); | 485 |
442 } | 486 if (!ngx_threaded && !ngx_accept_mutex_held) { |
443 | 487 c->read->event_handler(c->read); |
444 if ((event_list[i].events & (EPOLLOUT|EPOLLERR|EPOLLHUP)) | 488 |
445 && c->write->active) | 489 } else if (!c->read->accept) { |
446 { | 490 ngx_post_event(c->read); |
447 c->write->ready = 1; | 491 |
448 c->write->event_handler(c->write); | 492 } else { |
449 } | 493 ngx_mutex_unlock(ngx_posted_events_mutex); |
450 } | 494 |
451 | 495 c->read->event_handler(c->read); |
452 if (timer != (ngx_msec_t) -1 && delta) { | 496 |
497 if (i + 1 == events) { | |
498 lock = 0; | |
499 break; | |
500 } | |
501 | |
502 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { | |
503 ngx_accept_mutex_unlock(); | |
504 return NGX_ERROR; | |
505 } | |
506 } | |
507 } | |
508 } | |
509 | |
510 if (lock) { | |
511 ngx_mutex_unlock(ngx_posted_events_mutex); | |
512 } | |
513 | |
514 ngx_accept_mutex_unlock(); | |
515 | |
516 if (expire && delta) { | |
453 ngx_event_expire_timers((ngx_msec_t) delta); | 517 ngx_event_expire_timers((ngx_msec_t) delta); |
518 } | |
519 | |
520 if (!ngx_threaded) { | |
521 ngx_event_process_posted(cycle); | |
454 } | 522 } |
455 | 523 |
456 return NGX_OK; | 524 return NGX_OK; |
457 } | 525 } |
458 | 526 |