comparison src/event/modules/ngx_devpoll_module.c @ 332:3a91bfeffaba NGINX_0_6_10

nginx 0.6.10 *) Feature: the "open_file_cache", "open_file_cache_retest", and "open_file_cache_errors" directives. *) Bugfix: socket leak; bug appeared in 0.6.7. *) Bugfix: a charset set by the "charset" directive was not appended to the "Content-Type" header set by $r->send_http_header(). *) Bugfix: a segmentation fault might occur in worker process if /dev/poll method was used.
author Igor Sysoev <http://sysoev.ru>
date Mon, 03 Sep 2007 00:00:00 +0400
parents f7cd062ee035
children f39b9e29530d
comparison
equal deleted inserted replaced
331:b69d5e83bf82 332:3a91bfeffaba
11 11
12 #if (NGX_TEST_BUILD_DEVPOLL) 12 #if (NGX_TEST_BUILD_DEVPOLL)
13 13
14 /* Solaris declarations */ 14 /* Solaris declarations */
15 15
16 #define POLLREMOVE 0x0800 16 #define POLLREMOVE 0x0800
17 #define DP_POLL 0xD001 17 #define DP_POLL 0xD001
18 #define DP_ISPOLLED 0xD002
18 19
19 struct dvpoll { 20 struct dvpoll {
20 struct pollfd *dp_fds; 21 struct pollfd *dp_fds;
21 int dp_nfds; 22 int dp_nfds;
22 int dp_timeout; 23 int dp_timeout;
253 } 254 }
254 255
255 ev->active = 0; 256 ev->active = 0;
256 257
257 if (flags & NGX_CLOSE_EVENT) { 258 if (flags & NGX_CLOSE_EVENT) {
259 e = (event == POLLIN) ? c->write : c->read;
260
261 if (e) {
262 e->active = 0;
263 }
264
258 return NGX_OK; 265 return NGX_OK;
259 } 266 }
260 267
261 /* restore the paired event if it exists */ 268 /* restore the pair event if it exists */
262 269
263 if (event == POLLIN) { 270 if (event == POLLIN) {
264 e = c->write; 271 e = c->write;
265 event = POLLOUT; 272 event = POLLOUT;
266 273
328 335
329 ngx_int_t 336 ngx_int_t
330 ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, 337 ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
331 ngx_uint_t flags) 338 ngx_uint_t flags)
332 { 339 {
333 int events, revents; 340 int events, revents, rc;
334 size_t n; 341 size_t n;
342 ngx_fd_t fd;
335 ngx_err_t err; 343 ngx_err_t err;
336 ngx_int_t i; 344 ngx_int_t i;
337 ngx_uint_t level; 345 ngx_uint_t level;
338 ngx_event_t *rev, *wev, **queue; 346 ngx_event_t *rev, *wev, **queue;
339 ngx_connection_t *c; 347 ngx_connection_t *c;
348 struct pollfd pfd;
340 struct dvpoll dvp; 349 struct dvpoll dvp;
341 350
342 /* NGX_TIMER_INFINITE == INFTIM */ 351 /* NGX_TIMER_INFINITE == INFTIM */
343 352
344 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 353 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
399 } 408 }
400 409
401 ngx_mutex_lock(ngx_posted_events_mutex); 410 ngx_mutex_lock(ngx_posted_events_mutex);
402 411
403 for (i = 0; i < events; i++) { 412 for (i = 0; i < events; i++) {
404 c = ngx_cycle->files[event_list[i].fd]; 413
405 414 fd = event_list[i].fd;
406 if (c->fd == -1) { 415 revents = event_list[i].revents;
407 if (c->read->closed) { 416
408 continue; 417 c = ngx_cycle->files[fd];
409 } 418
410 419 if (c == NULL || c->fd == -1) {
411 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event"); 420
421 pfd.fd = fd;
422 pfd.events = 0;
423 pfd.revents = 0;
424
425 rc = ioctl(dp, DP_ISPOLLED, &pfd);
426
427 switch (rc) {
428
429 case -1:
430 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
431 "ioctl(DP_ISPOLLED) failed for socket %d, event",
432 fd, revents);
433 break;
434
435 case 0:
436 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
437 "phantom event %04Xd for closed and removed socket %d",
438 revents, fd);
439 break;
440
441 default:
442 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
443 "unexpected event %04Xd for closed and removed socket %d, ",
444 "ioctl(DP_ISPOLLED) returned rc:%d, fd:%d, event %04Xd",
445 revents, fd, rc, pfd.fd, pfd.revents);
446
447 pfd.fd = fd;
448 pfd.events = POLLREMOVE;
449 pfd.revents = 0;
450
451 if (write(dp, &pfd, sizeof(struct pollfd))
452 != (ssize_t) sizeof(struct pollfd))
453 {
454 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
455 "write(/dev/poll) for %d failed, fd");
456 }
457
458 if (close(fd) == -1) {
459 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
460 "close(%d) failed", fd);
461 }
462
463 break;
464 }
465
412 continue; 466 continue;
413 } 467 }
414
415 revents = event_list[i].revents;
416 468
417 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 469 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
418 "devpoll: fd:%d, ev:%04Xd, rev:%04Xd", 470 "devpoll: fd:%d, ev:%04Xd, rev:%04Xd",
419 event_list[i].fd, event_list[i].events, revents); 471 fd, event_list[i].events, revents);
420 472
421 if (revents & (POLLERR|POLLHUP|POLLNVAL)) { 473 if (revents & (POLLERR|POLLHUP|POLLNVAL)) {
422 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 474 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
423 "ioctl(DP_POLL) error fd:%d ev:%04Xd rev:%04Xd", 475 "ioctl(DP_POLL) error fd:%d ev:%04Xd rev:%04Xd",
424 event_list[i].fd, event_list[i].events, revents); 476 fd, event_list[i].events, revents);
425 } 477 }
426 478
427 if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { 479 if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) {
428 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, 480 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
429 "strange ioctl(DP_POLL) events " 481 "strange ioctl(DP_POLL) events "
430 "fd:%d ev:%04Xd rev:%04Xd", 482 "fd:%d ev:%04Xd rev:%04Xd",
431 event_list[i].fd, event_list[i].events, revents); 483 fd, event_list[i].events, revents);
432 } 484 }
433 485
434 if ((revents & (POLLERR|POLLHUP|POLLNVAL)) 486 if ((revents & (POLLERR|POLLHUP|POLLNVAL))
435 && (revents & (POLLIN|POLLOUT)) == 0) 487 && (revents & (POLLIN|POLLOUT)) == 0)
436 { 488 {