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