Mercurial > hg > nginx
comparison src/event/modules/ngx_poll_module.c @ 313:98f1a8028067
nginx-0.0.3-2004-04-13-19:08:48 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 13 Apr 2004 15:08:48 +0000 |
parents | 4b1a3a4acc60 |
children | d71c87d11b16 |
comparison
equal
deleted
inserted
replaced
312:f5431a4bbc7d | 313:98f1a8028067 |
---|---|
17 | 17 |
18 | 18 |
19 static struct pollfd *event_list; | 19 static struct pollfd *event_list; |
20 static int nevents; | 20 static int nevents; |
21 | 21 |
22 #if 0 | |
22 static ngx_event_t **ready_index; | 23 static ngx_event_t **ready_index; |
24 #endif | |
25 | |
26 static ngx_event_t *accept_events; | |
23 | 27 |
24 | 28 |
25 static ngx_str_t poll_name = ngx_string("poll"); | 29 static ngx_str_t poll_name = ngx_string("poll"); |
26 | 30 |
27 ngx_event_module_t ngx_poll_module_ctx = { | 31 ngx_event_module_t ngx_poll_module_ctx = { |
75 ngx_free(event_list); | 79 ngx_free(event_list); |
76 } | 80 } |
77 | 81 |
78 event_list = list; | 82 event_list = list; |
79 | 83 |
84 #if 0 | |
80 if (ready_index) { | 85 if (ready_index) { |
81 ngx_free(ready_index); | 86 ngx_free(ready_index); |
82 } | 87 } |
83 | 88 |
84 ngx_test_null(ready_index, | 89 ngx_test_null(ready_index, |
85 ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n, | 90 ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n, |
86 cycle->log), | 91 cycle->log), |
87 NGX_ERROR); | 92 NGX_ERROR); |
93 #endif | |
88 } | 94 } |
89 | 95 |
90 ngx_io = ngx_os_io; | 96 ngx_io = ngx_os_io; |
91 | 97 |
92 ngx_event_actions = ngx_poll_module_ctx.actions; | 98 ngx_event_actions = ngx_poll_module_ctx.actions; |
98 | 104 |
99 | 105 |
100 static void ngx_poll_done(ngx_cycle_t *cycle) | 106 static void ngx_poll_done(ngx_cycle_t *cycle) |
101 { | 107 { |
102 ngx_free(event_list); | 108 ngx_free(event_list); |
109 #if 0 | |
103 ngx_free(ready_index); | 110 ngx_free(ready_index); |
111 #endif | |
104 | 112 |
105 event_list = NULL; | 113 event_list = NULL; |
114 #if 0 | |
106 ready_index = NULL; | 115 ready_index = NULL; |
116 #endif | |
107 } | 117 } |
108 | 118 |
109 | 119 |
110 static int ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags) | 120 static int ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags) |
111 { | 121 { |
165 ngx_cycle_t **cycle; | 175 ngx_cycle_t **cycle; |
166 ngx_event_t *e; | 176 ngx_event_t *e; |
167 ngx_connection_t *c; | 177 ngx_connection_t *c; |
168 | 178 |
169 c = ev->data; | 179 c = ev->data; |
180 | |
181 ev->active = 0; | |
182 ev->posted = 0; | |
170 | 183 |
171 if (ev->index == NGX_INVALID_INDEX) { | 184 if (ev->index == NGX_INVALID_INDEX) { |
172 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, | 185 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, |
173 "poll event fd:%d ev:%d is already deleted", | 186 "poll event fd:%d ev:%d is already deleted", |
174 c->fd, event); | 187 c->fd, event); |
236 "poll del index: %d", e->index); | 249 "poll del index: %d", e->index); |
237 | 250 |
238 event_list[e->index].events &= ~event; | 251 event_list[e->index].events &= ~event; |
239 } | 252 } |
240 | 253 |
241 ev->active = 0; | |
242 ev->index = NGX_INVALID_INDEX; | 254 ev->index = NGX_INVALID_INDEX; |
243 | 255 |
244 return NGX_OK; | 256 return NGX_OK; |
245 } | 257 } |
246 | 258 |
247 | 259 |
248 int ngx_poll_process_events(ngx_cycle_t *cycle) | 260 int ngx_poll_process_events(ngx_cycle_t *cycle) |
249 { | 261 { |
250 int ready; | 262 int ready; |
251 ngx_int_t i, nready; | 263 ngx_int_t i, nready; |
252 ngx_uint_t n, found; | 264 ngx_uint_t n, found, lock, expire; |
253 ngx_msec_t timer; | 265 ngx_msec_t timer; |
254 ngx_err_t err; | 266 ngx_err_t err; |
255 ngx_cycle_t **old_cycle; | 267 ngx_cycle_t **old_cycle; |
256 ngx_event_t *ev; | 268 ngx_event_t *ev; |
257 ngx_epoch_msec_t delta; | 269 ngx_epoch_msec_t delta; |
258 ngx_connection_t *c; | 270 ngx_connection_t *c; |
259 struct timeval tv; | 271 struct timeval tv; |
260 | 272 |
261 if (ngx_event_flags & NGX_OVERFLOW_EVENT) { | 273 if (ngx_event_flags & NGX_OVERFLOW_EVENT) { |
262 timer = 0; | 274 timer = 0; |
275 expire = 0; | |
263 | 276 |
264 } else { | 277 } else { |
265 timer = ngx_event_find_timer(); | 278 timer = ngx_event_find_timer(); |
266 | 279 |
267 if (timer == 0) { | 280 if (timer == 0) { |
268 timer = (ngx_msec_t) INFTIM; | 281 timer = (ngx_msec_t) INFTIM; |
282 expire = 0; | |
283 | |
284 } else { | |
285 expire = 1; | |
269 } | 286 } |
270 } | 287 } |
271 | 288 |
272 ngx_old_elapsed_msec = ngx_elapsed_msec; | 289 ngx_old_elapsed_msec = ngx_elapsed_msec; |
273 | 290 |
275 for (i = 0; i < nevents; i++) { | 292 for (i = 0; i < nevents; i++) { |
276 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 293 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
277 "poll: %d: fd:%d ev:%04X", | 294 "poll: %d: fd:%d ev:%04X", |
278 i, event_list[i].fd, event_list[i].events); | 295 i, event_list[i].fd, event_list[i].events); |
279 } | 296 } |
297 #endif | |
298 | |
299 if (ngx_accept_mutex) { | |
300 if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { | |
301 return NGX_ERROR; | |
302 } | |
303 | |
304 if (ngx_accept_mutex_held == 0 && timer > ngx_accept_mutex_delay) { | |
305 timer = ngx_accept_mutex_delay; | |
306 expire = 0; | |
307 } | |
308 } | |
280 | 309 |
281 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll timer: %d", timer); | 310 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll timer: %d", timer); |
282 #endif | |
283 | 311 |
284 ready = poll(event_list, (u_int) nevents, (int) timer); | 312 ready = poll(event_list, (u_int) nevents, (int) timer); |
285 | 313 |
286 if (ready == -1) { | 314 if (ready == -1) { |
287 err = ngx_errno; | 315 err = ngx_errno; |
299 "poll ready %d of %d", ready, nevents); | 327 "poll ready %d of %d", ready, nevents); |
300 | 328 |
301 if (err) { | 329 if (err) { |
302 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, | 330 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, |
303 cycle->log, err, "poll() failed"); | 331 cycle->log, err, "poll() failed"); |
332 ngx_accept_mutex_unlock(); | |
304 return NGX_ERROR; | 333 return NGX_ERROR; |
305 } | 334 } |
306 | 335 |
307 if (timer != (ngx_msec_t) INFTIM) { | 336 if (timer != (ngx_msec_t) INFTIM) { |
308 delta = ngx_elapsed_msec - delta; | 337 delta = ngx_elapsed_msec - delta; |
311 "poll timer: %d, delta: %d", timer, (int) delta); | 340 "poll timer: %d, delta: %d", timer, (int) delta); |
312 } else { | 341 } else { |
313 if (ready == 0) { | 342 if (ready == 0) { |
314 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | 343 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
315 "poll() returned no events without timeout"); | 344 "poll() returned no events without timeout"); |
345 ngx_accept_mutex_unlock(); | |
316 return NGX_ERROR; | 346 return NGX_ERROR; |
317 } | 347 } |
318 } | 348 } |
319 | 349 |
320 if (timer == 0 && ready == 0) { | 350 if (timer == 0 && ready == 0) { |
321 /* the overflowed rt signals queue has been drained */ | 351 /* the overflowed rt signals queue has been drained */ |
322 return NGX_OK; | 352 return NGX_OK; |
323 } | 353 } |
324 | 354 |
355 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { | |
356 ngx_accept_mutex_unlock(); | |
357 return NGX_ERROR; | |
358 } | |
359 | |
360 lock = 1; | |
325 nready = 0; | 361 nready = 0; |
326 | 362 |
327 for (i = 0; i < nevents && ready; i++) { | 363 for (i = 0; i < nevents && ready; i++) { |
328 | 364 |
329 #if 0 | 365 #if 0 |
338 i, event_list[i].fd, | 374 i, event_list[i].fd, |
339 event_list[i].events, event_list[i].revents); | 375 event_list[i].events, event_list[i].revents); |
340 } | 376 } |
341 #endif | 377 #endif |
342 | 378 |
343 if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) { | 379 if (event_list[i].revents & (POLLERR|POLLNVAL)) { |
344 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | 380 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
345 "poll() error fd:%d ev:%04X rev:%04X", | 381 "poll() error fd:%d ev:%04X rev:%04X", |
346 event_list[i].fd, | 382 event_list[i].fd, |
347 event_list[i].events, event_list[i].revents); | 383 event_list[i].events, event_list[i].revents); |
348 } | 384 } |
354 event_list[i].fd, | 390 event_list[i].fd, |
355 event_list[i].events, event_list[i].revents); | 391 event_list[i].events, event_list[i].revents); |
356 } | 392 } |
357 | 393 |
358 if (event_list[i].fd == -1) { | 394 if (event_list[i].fd == -1) { |
359 | 395 /* |
360 /* the disabled event, workaround for our possible bug */ | 396 * the disabled event, a workaround for our possible bug, see below |
361 | 397 */ |
362 continue; | 398 continue; |
363 } | 399 } |
364 | 400 |
365 c = &ngx_cycle->connections[event_list[i].fd]; | 401 c = &ngx_cycle->connections[event_list[i].fd]; |
366 | 402 |
396 | 432 |
397 found = 0; | 433 found = 0; |
398 | 434 |
399 if (event_list[i].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL)) { | 435 if (event_list[i].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL)) { |
400 found = 1; | 436 found = 1; |
437 | |
438 ev = c->read; | |
439 ev->ready = 1; | |
440 | |
441 if (ev->oneshot) { | |
442 if (ev->timer_set) { | |
443 ngx_del_timer(ev); | |
444 } | |
445 ngx_poll_del_event(ev, NGX_READ_EVENT, 0); | |
446 } | |
447 | |
448 if (ev->accept) { | |
449 ev->next = accept_events; | |
450 accept_events = ev; | |
451 } else { | |
452 ngx_post_event(ev); | |
453 } | |
454 | |
455 #if 0 | |
401 ready_index[nready++] = c->read; | 456 ready_index[nready++] = c->read; |
457 #endif | |
402 } | 458 } |
403 | 459 |
404 if (event_list[i].revents & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { | 460 if (event_list[i].revents & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { |
405 found = 1; | 461 found = 1; |
462 ev = c->write; | |
463 ev->ready = 1; | |
464 | |
465 if (ev->oneshot) { | |
466 if (ev->timer_set) { | |
467 ngx_del_timer(ev); | |
468 } | |
469 ngx_poll_del_event(ev, NGX_WRITE_EVENT, 0); | |
470 } | |
471 | |
472 ngx_post_event(ev); | |
473 #if 0 | |
406 ready_index[nready++] = c->write; | 474 ready_index[nready++] = c->write; |
475 #endif | |
407 } | 476 } |
408 | 477 |
409 if (found) { | 478 if (found) { |
410 ready--; | 479 ready--; |
411 continue; | 480 continue; |
412 } | 481 } |
413 } | 482 } |
414 | 483 |
484 #if 0 | |
415 for (i = 0; i < nready; i++) { | 485 for (i = 0; i < nready; i++) { |
416 ev = ready_index[i]; | 486 ev = ready_index[i]; |
417 | 487 |
418 if (!ev->active) { | 488 if (!ev->active) { |
419 continue; | 489 continue; |
433 } | 503 } |
434 } | 504 } |
435 | 505 |
436 ev->event_handler(ev); | 506 ev->event_handler(ev); |
437 } | 507 } |
508 #endif | |
509 | |
510 ev = accept_events; | |
511 | |
512 for ( ;; ) { | |
513 | |
514 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
515 "accept event " PTR_FMT, ev); | |
516 | |
517 if (ev == NULL) { | |
518 break; | |
519 } | |
520 | |
521 ngx_mutex_unlock(ngx_posted_events_mutex); | |
522 | |
523 ev->event_handler(ev); | |
524 | |
525 ev = ev->next; | |
526 | |
527 if (ev == NULL) { | |
528 lock = 0; | |
529 break; | |
530 } | |
531 | |
532 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { | |
533 ngx_accept_mutex_unlock(); | |
534 return NGX_ERROR; | |
535 } | |
536 | |
537 } | |
538 | |
539 if (lock) { | |
540 ngx_mutex_unlock(ngx_posted_events_mutex); | |
541 } | |
542 | |
543 ngx_accept_mutex_unlock(); | |
544 accept_events = NULL; | |
438 | 545 |
439 if (ready != 0) { | 546 if (ready != 0) { |
440 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events"); | 547 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events"); |
441 } | 548 } |
442 | 549 |
443 if (timer != (ngx_msec_t) INFTIM && delta) { | 550 if (expire && delta) { |
444 ngx_event_expire_timers((ngx_msec_t) delta); | 551 ngx_event_expire_timers((ngx_msec_t) delta); |
552 } | |
553 | |
554 if (!ngx_threaded) { | |
555 ngx_event_process_posted(cycle); | |
445 } | 556 } |
446 | 557 |
447 return nready; | 558 return nready; |
448 } | 559 } |