summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2007-08-29 11:26:42 +0000
committerIgor Sysoev <igor@sysoev.ru>2007-08-29 11:26:42 +0000
commit7f789168efa15810264c1990ef867f980e5039d3 (patch)
tree01c4cb5662efd5d1ef9ac80151adb580904fba04
parentbb3799d89f26346e149045a34634bcafac60d3fb (diff)
downloadnginx-7f789168efa15810264c1990ef867f980e5039d3.tar.gz
add guard code
-rw-r--r--src/event/modules/ngx_devpoll_module.c72
1 files changed, 59 insertions, 13 deletions
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c
index 4c72356c5..903efe6b5 100644
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -13,8 +13,9 @@
/* Solaris declarations */
-#define POLLREMOVE 0x0800
-#define DP_POLL 0xD001
+#define POLLREMOVE 0x0800
+#define DP_POLL 0xD001
+#define DP_ISPOLLED 0xD002
struct dvpoll {
struct pollfd *dp_fds;
@@ -336,13 +337,15 @@ ngx_int_t
ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags)
{
- int events, revents;
+ int events, revents, rc;
size_t n;
+ ngx_fd_t fd;
ngx_err_t err;
ngx_int_t i;
ngx_uint_t level;
ngx_event_t *rev, *wev, **queue;
ngx_connection_t *c;
+ struct pollfd pfd;
struct dvpoll dvp;
/* NGX_TIMER_INFINITE == INFTIM */
@@ -407,34 +410,77 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_mutex_lock(ngx_posted_events_mutex);
for (i = 0; i < events; i++) {
- c = ngx_cycle->files[event_list[i].fd];
- if (c->fd == -1) {
- if (c->read->closed) {
- continue;
+ fd = event_list[i].fd;
+ revents = event_list[i].revents;
+
+ c = ngx_cycle->files[fd];
+
+ if (c == NULL || c->fd == -1) {
+
+ pfd.fd = fd;
+ pfd.events = 0;
+ pfd.revents = 0;
+
+ rc = ioctl(dp, DP_ISPOLLED, &pfd);
+
+ switch (rc) {
+
+ case -1:
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "ioctl(DP_ISPOLLED) failed for socket %d, event",
+ fd, revents);
+ break;
+
+ case 0:
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "phantom event %04Xd for closed and removed socket %d",
+ revents, fd);
+ break;
+
+ default:
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "unexpected event %04Xd for closed and removed socket %d, ",
+ "ioctl(DP_ISPOLLED) returned rc:%d, fd:%d, event %04Xd",
+ revents, fd, rc, pfd.fd, pfd.revents);
+
+ pfd.fd = fd;
+ pfd.events = POLLREMOVE;
+ pfd.revents = 0;
+
+ if (write(dp, &pfd, sizeof(struct pollfd))
+ != (ssize_t) sizeof(struct pollfd))
+ {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "write(/dev/poll) for %d failed, fd");
+ }
+
+ if (close(fd) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "close(%d) failed", fd);
+ }
+
+ break;
}
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event");
continue;
}
- revents = event_list[i].revents;
-
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"devpoll: fd:%d, ev:%04Xd, rev:%04Xd",
- event_list[i].fd, event_list[i].events, revents);
+ fd, event_list[i].events, revents);
if (revents & (POLLERR|POLLHUP|POLLNVAL)) {
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"ioctl(DP_POLL) error fd:%d ev:%04Xd rev:%04Xd",
- event_list[i].fd, event_list[i].events, revents);
+ fd, event_list[i].events, revents);
}
if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"strange ioctl(DP_POLL) events "
"fd:%d ev:%04Xd rev:%04Xd",
- event_list[i].fd, event_list[i].events, revents);
+ fd, event_list[i].events, revents);
}
if ((revents & (POLLERR|POLLHUP|POLLNVAL))