comparison src/event/modules/ngx_poll_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
7 #include <ngx_config.h> 7 #include <ngx_config.h>
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 static ngx_int_t ngx_poll_init(ngx_cycle_t *cycle); 12 static ngx_int_t ngx_poll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
13 static void ngx_poll_done(ngx_cycle_t *cycle); 13 static void ngx_poll_done(ngx_cycle_t *cycle);
14 static ngx_int_t ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags); 14 static ngx_int_t ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags);
15 static ngx_int_t ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags); 15 static ngx_int_t ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags);
16 static ngx_int_t ngx_poll_process_events(ngx_cycle_t *cycle); 16 static ngx_int_t ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
17 ngx_uint_t flags);
17 static char *ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf); 18 static char *ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf);
18 19
19 20
20 static struct pollfd *event_list; 21 static struct pollfd *event_list;
21 static int nevents; 22 static int nevents;
22
23 #if 0
24 static ngx_event_t **ready_index;
25 #endif
26
27 static ngx_event_t *accept_events;
28 23
29 24
30 static ngx_str_t poll_name = ngx_string("poll"); 25 static ngx_str_t poll_name = ngx_string("poll");
31 26
32 ngx_event_module_t ngx_poll_module_ctx = { 27 ngx_event_module_t ngx_poll_module_ctx = {
65 }; 60 };
66 61
67 62
68 63
69 static ngx_int_t 64 static ngx_int_t
70 ngx_poll_init(ngx_cycle_t *cycle) 65 ngx_poll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
71 { 66 {
72 struct pollfd *list; 67 struct pollfd *list;
73 68
74 if (event_list == NULL) { 69 if (event_list == NULL) {
75 nevents = 0; 70 nevents = 0;
89 ngx_memcpy(list, event_list, sizeof(ngx_event_t *) * nevents); 84 ngx_memcpy(list, event_list, sizeof(ngx_event_t *) * nevents);
90 ngx_free(event_list); 85 ngx_free(event_list);
91 } 86 }
92 87
93 event_list = list; 88 event_list = list;
94
95 #if 0
96 if (ready_index) {
97 ngx_free(ready_index);
98 }
99
100 ready_index = ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n,
101 cycle->log);
102 if (ready_index == NULL) {
103 return NGX_ERROR;
104 }
105 #endif
106 } 89 }
107 90
108 ngx_io = ngx_os_io; 91 ngx_io = ngx_os_io;
109 92
110 ngx_event_actions = ngx_poll_module_ctx.actions; 93 ngx_event_actions = ngx_poll_module_ctx.actions;
111 94
112 ngx_event_flags = NGX_USE_LEVEL_EVENT 95 ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_FD_EVENT;
113 |NGX_USE_ONESHOT_EVENT
114 |NGX_USE_FD_EVENT;
115 96
116 return NGX_OK; 97 return NGX_OK;
117 } 98 }
118 99
119 100
120 static void 101 static void
121 ngx_poll_done(ngx_cycle_t *cycle) 102 ngx_poll_done(ngx_cycle_t *cycle)
122 { 103 {
123 ngx_free(event_list); 104 ngx_free(event_list);
124 #if 0
125 ngx_free(ready_index);
126 #endif
127 105
128 event_list = NULL; 106 event_list = NULL;
129 #if 0
130 ready_index = NULL;
131 #endif
132 } 107 }
133 108
134 109
135 static ngx_int_t 110 static ngx_int_t
136 ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags) 111 ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
187 162
188 163
189 static ngx_int_t 164 static ngx_int_t
190 ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags) 165 ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
191 { 166 {
192 ngx_uint_t i; 167 ngx_event_t *e;
193 ngx_cycle_t **cycle; 168 ngx_connection_t *c;
194 ngx_event_t *e;
195 ngx_connection_t *c;
196 169
197 c = ev->data; 170 c = ev->data;
198 171
199 ev->active = 0; 172 ev->active = 0;
200 173
232 event_list[ev->index] = event_list[nevents]; 205 event_list[ev->index] = event_list[nevents];
233 206
234 c = ngx_cycle->files[event_list[nevents].fd]; 207 c = ngx_cycle->files[event_list[nevents].fd];
235 208
236 if (c->fd == -1) { 209 if (c->fd == -1) {
237 cycle = ngx_old_cycles.elts;
238 for (i = 0; i < ngx_old_cycles.nelts; i++) {
239 if (cycle[i] == NULL) {
240 continue;
241 }
242 c = cycle[i]->files[event_list[nevents].fd];
243 if (c->fd != -1) {
244 break;
245 }
246 }
247 }
248
249 if (c->fd == -1) {
250 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, 210 ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
251 "unexpected last event"); 211 "unexpected last event");
252 212
253 } else { 213 } else {
254 if (c->read->index == (u_int) nevents) { 214 if (c->read->index == (u_int) nevents) {
273 return NGX_OK; 233 return NGX_OK;
274 } 234 }
275 235
276 236
277 static ngx_int_t 237 static ngx_int_t
278 ngx_poll_process_events(ngx_cycle_t *cycle) 238 ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
279 { 239 {
280 int ready, revents; 240 int ready, revents;
281 ngx_err_t err; 241 ngx_err_t err;
282 ngx_int_t i, nready; 242 ngx_int_t i, nready;
283 ngx_uint_t n, found, lock; 243 ngx_uint_t found, level;
284 ngx_msec_t timer, delta; 244 ngx_msec_t delta;
285 ngx_cycle_t **old_cycle; 245 ngx_event_t *ev, **queue;
286 ngx_event_t *ev;
287 ngx_connection_t *c; 246 ngx_connection_t *c;
288 struct timeval tv;
289
290 timer = ngx_event_find_timer();
291 247
292 /* NGX_TIMER_INFINITE == INFTIM */ 248 /* NGX_TIMER_INFINITE == INFTIM */
293 249
294 #if (NGX_DEBUG0) 250 #if (NGX_DEBUG0)
295 if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) { 251 if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) {
299 i, event_list[i].fd, event_list[i].events); 255 i, event_list[i].fd, event_list[i].events);
300 } 256 }
301 } 257 }
302 #endif 258 #endif
303 259
304 if (ngx_accept_mutex) {
305 if (ngx_accept_disabled > 0) {
306 ngx_accept_disabled--;
307
308 } else {
309 if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
310 return NGX_ERROR;
311 }
312
313 if (ngx_accept_mutex_held == 0
314 && (timer == NGX_TIMER_INFINITE
315 || timer > ngx_accept_mutex_delay))
316 {
317 timer = ngx_accept_mutex_delay;
318 }
319 }
320 }
321
322 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll timer: %M", timer); 260 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll timer: %M", timer);
323 261
324 ready = poll(event_list, (u_int) nevents, (int) timer); 262 ready = poll(event_list, (u_int) nevents, (int) timer);
325 263
326 if (ready == -1) { 264 if (ready == -1) {
327 err = ngx_errno; 265 err = ngx_errno;
328 } else { 266 } else {
329 err = 0; 267 err = 0;
330 } 268 }
331 269
332 ngx_gettimeofday(&tv); 270 delta = ngx_current_msec;
333 ngx_time_update(tv.tv_sec); 271
334 272 if (flags & NGX_UPDATE_TIME) {
335 delta = ngx_current_time; 273 ngx_time_update(0, 0);
336 ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; 274 }
337 275
338 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 276 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
339 "poll ready %d of %d", ready, nevents); 277 "poll ready %d of %d", ready, nevents);
340 278
341 if (err) { 279 if (err) {
342 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, 280 if (err == NGX_EINTR) {
343 cycle->log, err, "poll() failed"); 281
344 ngx_accept_mutex_unlock(); 282 if (ngx_event_timer_alarm) {
283 ngx_event_timer_alarm = 0;
284 return NGX_OK;
285 }
286
287 level = NGX_LOG_INFO;
288
289 } else {
290 level = NGX_LOG_ALERT;
291 }
292
293 ngx_log_error(level, cycle->log, err, "poll() failed");
345 return NGX_ERROR; 294 return NGX_ERROR;
346 } 295 }
347 296
348 if (timer != NGX_TIMER_INFINITE) { 297 if (timer != NGX_TIMER_INFINITE) {
349 delta = ngx_current_time - delta; 298 delta = ngx_current_msec - delta;
350 299
351 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 300 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
352 "poll timer: %M, delta: %M", timer, delta); 301 "poll timer: %M, delta: %M", timer, delta);
353 } else { 302 } else {
354 if (ready == 0) { 303 if (ready == 0) {
355 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, 304 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
356 "poll() returned no events without timeout"); 305 "poll() returned no events without timeout");
357 ngx_accept_mutex_unlock();
358 return NGX_ERROR; 306 return NGX_ERROR;
359 } 307 }
360 } 308 }
361 309
362 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { 310 if (ready == 0) {
363 ngx_accept_mutex_unlock(); 311 return NGX_OK;
364 return NGX_ERROR; 312 }
365 } 313
366 314 ngx_mutex_lock(ngx_posted_events_mutex);
367 lock = 1; 315
368 nready = 0; 316 nready = 0;
369 317
370 for (i = 0; i < nevents && ready; i++) { 318 for (i = 0; i < nevents && ready; i++) {
371 319
372 revents = event_list[i].revents; 320 revents = event_list[i].revents;
373 321
374 #if 0 322 #if 1
375 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 323 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
376 "poll: %d: fd:%d ev:%04Xd rev:%04Xd", 324 "poll: %d: fd:%d ev:%04Xd rev:%04Xd",
377 i, event_list[i].fd, event_list[i].events, revents); 325 i, event_list[i].fd, event_list[i].events, revents);
378 #else 326 #else
379 if (revents) { 327 if (revents) {
404 } 352 }
405 353
406 c = ngx_cycle->files[event_list[i].fd]; 354 c = ngx_cycle->files[event_list[i].fd];
407 355
408 if (c->fd == -1) { 356 if (c->fd == -1) {
409 old_cycle = ngx_old_cycles.elts;
410 for (n = 0; n < ngx_old_cycles.nelts; n++) {
411 if (old_cycle[n] == NULL) {
412 continue;
413 }
414 c = old_cycle[n]->files[event_list[i].fd];
415 if (c->fd != -1) {
416 break;
417 }
418 }
419 }
420
421 if (c->fd == -1) {
422 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event"); 357 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event");
423 358
424 /* 359 /*
425 * it is certainly our fault and it should be investigated, 360 * it is certainly our fault and it should be investigated,
426 * in the meantime we disable this event to avoid a CPU spinning 361 * in the meantime we disable this event to avoid a CPU spinning
451 386
452 if (revents & POLLIN) { 387 if (revents & POLLIN) {
453 found = 1; 388 found = 1;
454 389
455 ev = c->read; 390 ev = c->read;
456 ev->ready = 1; 391
457 392 if ((flags & NGX_POST_THREAD_EVENTS) && !ev->accept) {
458 if (ev->oneshot) { 393 ev->posted_ready = 1;
459 if (ev->timer_set) { 394
460 ngx_del_timer(ev); 395 } else {
461 } 396 ev->ready = 1;
462 ngx_poll_del_event(ev, NGX_READ_EVENT, 0);
463 } 397 }
464 398
465 if (ev->accept) { 399 queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events:
466 ev->next = accept_events; 400 &ngx_posted_events);
467 accept_events = ev; 401 ngx_locked_post_event(ev, queue);
468 } else {
469 ngx_post_event(ev);
470 }
471
472 #if 0
473 ready_index[nready++] = c->read;
474 #endif
475 } 402 }
476 403
477 if (revents & POLLOUT) { 404 if (revents & POLLOUT) {
478 found = 1; 405 found = 1;
479 ev = c->write; 406 ev = c->write;
480 ev->ready = 1; 407
481 408 if (flags & NGX_POST_THREAD_EVENTS) {
482 if (ev->oneshot) { 409 ev->posted_ready = 1;
483 if (ev->timer_set) { 410
484 ngx_del_timer(ev); 411 } else {
485 } 412 ev->ready = 1;
486 ngx_poll_del_event(ev, NGX_WRITE_EVENT, 0);
487 } 413 }
488 414
489 ngx_post_event(ev); 415 ngx_locked_post_event(ev, &ngx_posted_events);
490 #if 0
491 ready_index[nready++] = c->write;
492 #endif
493 } 416 }
494 417
495 if (found) { 418 if (found) {
496 ready--; 419 ready--;
497 continue; 420 continue;
498 } 421 }
499 } 422 }
500 423
501 #if 0 424 ngx_mutex_unlock(ngx_posted_events_mutex);
502 for (i = 0; i < nready; i++) {
503 ev = ready_index[i];
504
505 if (!ev->active) {
506 continue;
507 }
508
509 ev->ready = 1;
510
511 if (ev->oneshot) {
512 if (ev->timer_set) {
513 ngx_del_timer(ev);
514 }
515
516 if (ev->write) {
517 ngx_poll_del_event(ev, NGX_WRITE_EVENT, 0);
518 } else {
519 ngx_poll_del_event(ev, NGX_READ_EVENT, 0);
520 }
521 }
522
523 ev->handler(ev);
524 }
525 #endif
526
527 ev = accept_events;
528
529 for ( ;; ) {
530
531 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
532 "accept event %p", ev);
533
534 if (ev == NULL) {
535 break;
536 }
537
538 ngx_mutex_unlock(ngx_posted_events_mutex);
539
540 ev->handler(ev);
541
542 if (ngx_accept_disabled > 0) {
543 lock = 0;
544 break;
545 }
546
547 ev = ev->next;
548
549 if (ev == NULL) {
550 lock = 0;
551 break;
552 }
553
554 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
555 ngx_accept_mutex_unlock();
556 return NGX_ERROR;
557 }
558
559 }
560
561 ngx_accept_mutex_unlock();
562 accept_events = NULL;
563
564 if (lock) {
565 ngx_mutex_unlock(ngx_posted_events_mutex);
566 }
567 425
568 if (ready != 0) { 426 if (ready != 0) {
569 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events"); 427 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events");
570 }
571
572 ngx_event_expire_timers();
573
574 if (!ngx_threaded) {
575 ngx_event_process_posted(cycle);
576 } 428 }
577 429
578 return nready; 430 return nready;
579 } 431 }
580 432