|
@@ -478,7 +478,7 @@ again_devpoll:
|
|
check_io_again:
|
|
check_io_again:
|
|
while(e->type && ((n=poll(&pf, 1, 0))>0) &&
|
|
while(e->type && ((n=poll(&pf, 1, 0))>0) &&
|
|
(handle_io(e, pf.revents, idx)>0) &&
|
|
(handle_io(e, pf.revents, idx)>0) &&
|
|
- (pf.revents & e->events));
|
|
|
|
|
|
+ (pf.revents & (e->events|POLLERR|POLLHUP)));
|
|
if (unlikely(e->type && (n==-1))){
|
|
if (unlikely(e->type && (n==-1))){
|
|
if (errno==EINTR) goto check_io_again;
|
|
if (errno==EINTR) goto check_io_again;
|
|
LOG(L_ERR, "ERROR: io_watch_add: check_io poll: %s [%d]\n",
|
|
LOG(L_ERR, "ERROR: io_watch_add: check_io poll: %s [%d]\n",
|
|
@@ -891,8 +891,8 @@ again:
|
|
* IO and the fd is still watched for the triggering event */
|
|
* IO and the fd is still watched for the triggering event */
|
|
while(fm->type &&
|
|
while(fm->type &&
|
|
(handle_io(fm, h->fd_array[r].revents, r) > 0) &&
|
|
(handle_io(fm, h->fd_array[r].revents, r) > 0) &&
|
|
- repeat &&
|
|
|
|
- (fm->events & h->fd_array[r].revents) );
|
|
|
|
|
|
+ repeat && ((fm->events|POLLERR|POLLHUP) &
|
|
|
|
+ h->fd_array[r].revents));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
error:
|
|
error:
|
|
@@ -974,13 +974,14 @@ again:
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
for (r=0; r<n; r++){
|
|
for (r=0; r<n; r++){
|
|
- revents= (POLLIN & (!(h->ep_array[r].events & EPOLLIN)-1)) |
|
|
|
|
|
|
+ revents= (POLLIN & (!(h->ep_array[r].events & (EPOLLIN|EPOLLPRI))
|
|
|
|
+ -1)) |
|
|
(POLLOUT & (!(h->ep_array[r].events & EPOLLOUT)-1)) |
|
|
(POLLOUT & (!(h->ep_array[r].events & EPOLLOUT)-1)) |
|
|
(POLLERR & (!(h->ep_array[r].events & EPOLLERR)-1)) |
|
|
(POLLERR & (!(h->ep_array[r].events & EPOLLERR)-1)) |
|
|
(POLLHUP & (!(h->ep_array[r].events & EPOLLHUP)-1));
|
|
(POLLHUP & (!(h->ep_array[r].events & EPOLLHUP)-1));
|
|
if (likely(revents)){
|
|
if (likely(revents)){
|
|
fm=(struct fd_map*)h->ep_array[r].data.ptr;
|
|
fm=(struct fd_map*)h->ep_array[r].data.ptr;
|
|
- while(fm->type && (fm->events & revents) &&
|
|
|
|
|
|
+ while(fm->type && ((fm->events|POLLERR|POLLHUP) & revents) &&
|
|
(handle_io(fm, revents, -1)>0) && repeat);
|
|
(handle_io(fm, revents, -1)>0) && repeat);
|
|
}else{
|
|
}else{
|
|
LOG(L_ERR, "ERROR:io_wait_loop_epoll: unexpected event %x"
|
|
LOG(L_ERR, "ERROR:io_wait_loop_epoll: unexpected event %x"
|
|
@@ -1122,6 +1123,17 @@ again:
|
|
if (fm->type)
|
|
if (fm->type)
|
|
handle_io(fm, POLLIN|POLLOUT, -1);
|
|
handle_io(fm, POLLIN|POLLOUT, -1);
|
|
}else{
|
|
}else{
|
|
|
|
+ /* si_code contains the SIGPOLL reason: POLL_IN, POLL_OUT,
|
|
|
|
+ * POLL_MSG, POLL_ERR, POLL_PRI or POLL_HUP
|
|
|
|
+ * and si_band the translated poll event bitmap:
|
|
|
|
+ * POLLIN|POLLRDNORM (=POLL_IN),
|
|
|
|
+ * POLLOUT|POLLWRNORM|POLLWRBAND (=POLL_OUT),
|
|
|
|
+ * POLLIN|POLLRDNORM|POLLMSG (=POLL_MSG),
|
|
|
|
+ * POLLERR (=POLL_ERR),
|
|
|
|
+ * POLLPRI|POLLRDBAND (=POLL_PRI),
|
|
|
|
+ * POLLHUP|POLLERR (=POLL_HUP)
|
|
|
|
+ * [linux 2.6.22 fs/fcntl.c:447]
|
|
|
|
+ */
|
|
#ifdef EXTRA_DEBUG
|
|
#ifdef EXTRA_DEBUG
|
|
DBG("io_wait_loop_sigio_rt: siginfo: signal=%d (%d),"
|
|
DBG("io_wait_loop_sigio_rt: siginfo: signal=%d (%d),"
|
|
" si_code=%d, si_band=0x%x,"
|
|
" si_code=%d, si_band=0x%x,"
|
|
@@ -1131,23 +1143,24 @@ again:
|
|
sigio_fd);
|
|
sigio_fd);
|
|
#endif
|
|
#endif
|
|
/* on some errors (e.g. when receving TCP RST), sigio_band will
|
|
/* on some errors (e.g. when receving TCP RST), sigio_band will
|
|
- * be set to 0x08 (undocumented, no corresp. POLL_xx), so better
|
|
|
|
- * catch all events --andrei */
|
|
|
|
- if (likely(sigio_band)/*&(POLL_IN|POLL_ERR|POLL_HUP)*/){
|
|
|
|
|
|
+ * be set to 0x08 (POLLERR) or 0x18 (POLLERR|POLLHUP - on stream
|
|
|
|
+ * unix socket close) , so better catch all events --andrei */
|
|
|
|
+ if (likely(sigio_band)){
|
|
fm=get_fd_map(h, sigio_fd);
|
|
fm=get_fd_map(h, sigio_fd);
|
|
- revents=(POLLIN & (!(sigio_band & POLL_IN)-1)) |
|
|
|
|
- (POLLOUT & (!(sigio_band & POLL_OUT)-1)) |
|
|
|
|
- (POLLERR & (!(sigio_band & POLL_ERR)-1)) |
|
|
|
|
- (POLLHUP & (!(sigio_band & POLL_HUP)-1));
|
|
|
|
|
|
+ revents=sigio_band;
|
|
|
|
+ /* fix revents==POLLPRI case */
|
|
|
|
+ revents |= (!(revents & POLLPRI)-1) & POLLIN;
|
|
/* we can have queued signals generated by fds not watched
|
|
/* we can have queued signals generated by fds not watched
|
|
* any more, or by fds in transition, to a child
|
|
* any more, or by fds in transition, to a child
|
|
* => ignore them */
|
|
* => ignore them */
|
|
- if (fm->type && (fm->events & revents))
|
|
|
|
|
|
+ if (fm->type && ((fm->events|POLLERR|POLLHUP) & revents))
|
|
handle_io(fm, revents, -1);
|
|
handle_io(fm, revents, -1);
|
|
else
|
|
else
|
|
- LOG(L_ERR, "WARNING: io_wait_loop_sigio_rt: ignoring event"
|
|
|
|
- " %x on fd %d (fm->fd=%d, fm->data=%p)\n",
|
|
|
|
- sigio_band, sigio_fd, fm->fd, fm->data);
|
|
|
|
|
|
+ DBG("WARNING: io_wait_loop_sigio_rt: ignoring event"
|
|
|
|
+ " %x on fd %d, watching for %x, si_code=%x "
|
|
|
|
+ "(fm->type=%d, fm->fd=%d, fm->data=%p)\n",
|
|
|
|
+ sigio_band, sigio_fd, fm->events, siginfo.si_code,
|
|
|
|
+ fm->type, fm->fd, fm->data);
|
|
}else{
|
|
}else{
|
|
LOG(L_ERR, "ERROR: io_wait_loop_sigio_rt: unexpected event"
|
|
LOG(L_ERR, "ERROR: io_wait_loop_sigio_rt: unexpected event"
|
|
" on fd %d: %x\n", sigio_fd, sigio_band);
|
|
" on fd %d: %x\n", sigio_fd, sigio_band);
|