Mercurial > hg > nginx
comparison src/event/modules/ngx_devpoll_module.c @ 1516:43ea45d73093 stable-0.5
r1432, r1433, r1434 merge:
/dev/poll segfault fix and guard code
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 23 Sep 2007 18:57:26 +0000 |
parents | 2b16d3959c2b |
children | e2ab812358bd |
comparison
equal
deleted
inserted
replaced
1515:bb61a910e832 | 1516:43ea45d73093 |
---|---|
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; |
250 } | 251 } |
251 | 252 |
252 ev->active = 0; | 253 ev->active = 0; |
253 | 254 |
254 if (flags & NGX_CLOSE_EVENT) { | 255 if (flags & NGX_CLOSE_EVENT) { |
256 e = (event == POLLIN) ? c->write : c->read; | |
257 | |
258 if (e) { | |
259 e->active = 0; | |
260 } | |
261 | |
255 return NGX_OK; | 262 return NGX_OK; |
256 } | 263 } |
257 | 264 |
258 /* restore the paired event if it exists */ | 265 /* restore the pair event if it exists */ |
259 | 266 |
260 if (event == POLLIN) { | 267 if (event == POLLIN) { |
261 e = c->write; | 268 e = c->write; |
262 event = POLLOUT; | 269 event = POLLOUT; |
263 | 270 |
325 | 332 |
326 ngx_int_t | 333 ngx_int_t |
327 ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, | 334 ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, |
328 ngx_uint_t flags) | 335 ngx_uint_t flags) |
329 { | 336 { |
330 int events, revents; | 337 int events, revents, rc; |
331 size_t n; | 338 size_t n; |
339 ngx_fd_t fd; | |
332 ngx_err_t err; | 340 ngx_err_t err; |
333 ngx_int_t i; | 341 ngx_int_t i; |
334 ngx_uint_t level; | 342 ngx_uint_t level; |
335 ngx_event_t *rev, *wev, **queue; | 343 ngx_event_t *rev, *wev, **queue; |
336 ngx_connection_t *c; | 344 ngx_connection_t *c; |
345 struct pollfd pfd; | |
337 struct dvpoll dvp; | 346 struct dvpoll dvp; |
338 | 347 |
339 /* NGX_TIMER_INFINITE == INFTIM */ | 348 /* NGX_TIMER_INFINITE == INFTIM */ |
340 | 349 |
341 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 350 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
396 } | 405 } |
397 | 406 |
398 ngx_mutex_lock(ngx_posted_events_mutex); | 407 ngx_mutex_lock(ngx_posted_events_mutex); |
399 | 408 |
400 for (i = 0; i < events; i++) { | 409 for (i = 0; i < events; i++) { |
401 c = ngx_cycle->files[event_list[i].fd]; | 410 |
402 | 411 fd = event_list[i].fd; |
403 if (c->fd == -1) { | 412 revents = event_list[i].revents; |
404 if (c->read->closed) { | 413 |
405 continue; | 414 c = ngx_cycle->files[fd]; |
406 } | 415 |
407 | 416 if (c == NULL || c->fd == -1) { |
408 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event"); | 417 |
418 pfd.fd = fd; | |
419 pfd.events = 0; | |
420 pfd.revents = 0; | |
421 | |
422 rc = ioctl(dp, DP_ISPOLLED, &pfd); | |
423 | |
424 switch (rc) { | |
425 | |
426 case -1: | |
427 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
428 "ioctl(DP_ISPOLLED) failed for socket %d, event", | |
429 fd, revents); | |
430 break; | |
431 | |
432 case 0: | |
433 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
434 "phantom event %04Xd for closed and removed socket %d", | |
435 revents, fd); | |
436 break; | |
437 | |
438 default: | |
439 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
440 "unexpected event %04Xd for closed and removed socket %d, ", | |
441 "ioctl(DP_ISPOLLED) returned rc:%d, fd:%d, event %04Xd", | |
442 revents, fd, rc, pfd.fd, pfd.revents); | |
443 | |
444 pfd.fd = fd; | |
445 pfd.events = POLLREMOVE; | |
446 pfd.revents = 0; | |
447 | |
448 if (write(dp, &pfd, sizeof(struct pollfd)) | |
449 != (ssize_t) sizeof(struct pollfd)) | |
450 { | |
451 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
452 "write(/dev/poll) for %d failed, fd"); | |
453 } | |
454 | |
455 if (close(fd) == -1) { | |
456 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
457 "close(%d) failed", fd); | |
458 } | |
459 | |
460 break; | |
461 } | |
462 | |
409 continue; | 463 continue; |
410 } | 464 } |
411 | |
412 revents = event_list[i].revents; | |
413 | 465 |
414 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 466 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
415 "devpoll: fd:%d, ev:%04Xd, rev:%04Xd", | 467 "devpoll: fd:%d, ev:%04Xd, rev:%04Xd", |
416 event_list[i].fd, event_list[i].events, revents); | 468 fd, event_list[i].events, revents); |
417 | 469 |
418 if (revents & (POLLERR|POLLHUP|POLLNVAL)) { | 470 if (revents & (POLLERR|POLLHUP|POLLNVAL)) { |
419 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 471 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, |
420 "ioctl(DP_POLL) error fd:%d ev:%04Xd rev:%04Xd", | 472 "ioctl(DP_POLL) error fd:%d ev:%04Xd rev:%04Xd", |
421 event_list[i].fd, event_list[i].events, revents); | 473 fd, event_list[i].events, revents); |
422 } | 474 } |
423 | 475 |
424 if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { | 476 if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) { |
425 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | 477 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
426 "strange ioctl(DP_POLL) events " | 478 "strange ioctl(DP_POLL) events " |
427 "fd:%d ev:%04Xd rev:%04Xd", | 479 "fd:%d ev:%04Xd rev:%04Xd", |
428 event_list[i].fd, event_list[i].events, revents); | 480 fd, event_list[i].events, revents); |
429 } | 481 } |
430 | 482 |
431 if ((revents & (POLLERR|POLLHUP|POLLNVAL)) | 483 if ((revents & (POLLERR|POLLHUP|POLLNVAL)) |
432 && (revents & (POLLIN|POLLOUT)) == 0) | 484 && (revents & (POLLIN|POLLOUT)) == 0) |
433 { | 485 { |