diff --git a/mio/lib/http-svr.c b/mio/lib/http-svr.c index 46381ab..5f58257 100644 --- a/mio/lib/http-svr.c +++ b/mio/lib/http-svr.c @@ -670,13 +670,21 @@ static MIO_INLINE void cgi_state_mark_over (cgi_state_t* cgi_state, int over_bit if (!(old_over & CGI_STATE_OVER_READ_FROM_PEER) && (cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER)) { - if (cgi_state->peer && mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 0) <= -1) mio_dev_pro_halt (cgi_state->peer); + if (cgi_state->peer && mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 0) <= -1) + { + MIO_DEBUG2 (cgi_state->htts->mio, "HTTS(%p) - halting peer(%p) for failure to disable input watching\n", cgi_state->htts, cgi_state->peer); + mio_dev_pro_halt (cgi_state->peer); + } } if (old_over != CGI_STATE_OVER_ALL && cgi_state->over == CGI_STATE_OVER_ALL) { /* ready to stop */ - if (cgi_state->peer) mio_dev_pro_halt (cgi_state->peer); + if (cgi_state->peer) + { + MIO_DEBUG2 (cgi_state->htts->mio, "HTTS(%p) - halting peer(%p) as it is unneeded\n", cgi_state->htts, cgi_state->peer); + mio_dev_pro_halt (cgi_state->peer); + } if (cgi_state->keep_alive) { diff --git a/mio/lib/sys-mux.c b/mio/lib/sys-mux.c index cd10537..1c886ca 100644 --- a/mio/lib/sys-mux.c +++ b/mio/lib/sys-mux.c @@ -39,7 +39,14 @@ int mio_sys_initmux (mio_t* mio) { mio_sys_mux_t* mux = &mio->sysdep->mux; -#if defined(USE_EPOLL) +#if defined(POLL) + mux->devnull = open("/dev/null", O_RDONLY); + if (mux->devnull == -1) + { + mio_seterrwithsyserr (mio, 0, errno); + return -1; + } +#elif defined(USE_EPOLL) mux->hnd = epoll_create(1000); /* TODO: choose proper initial size? */ if (mux->hnd == -1) { @@ -73,6 +80,10 @@ void mio_sys_finimux (mio_t* mio) mux->pd.dptr = MIO_NULL; } mux->pd.capa = 0; + + close (mux->devnull); + mux->devnull = MIO_SYSHND_INVALID; + #elif defined(USE_EPOLL) close (mux->hnd); mux->hnd = MIO_SYSHND_INVALID; @@ -174,6 +185,22 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_ mux->pd.pfd[idx].events = 0; if (dev_cap & MIO_DEV_CAP_IN_WATCHED) mux->pd.pfd[idx].events |= POLLIN; if (dev_cap & MIO_DEV_CAP_OUT_WATCHED) mux->pd.pfd[idx].events |= POLLOUT; + + /* On NetBSD 7.1.2 (GENERIC.201803151611Z) i386, the following happened. + * There is still pending data to read on the file descriptor. + * Disable input and output watching. + * The other end of file descriptor closes it (EOF). + * Because input and output watching is disabled, the file descriptor is + * included into the pollfd watch set with the following values. + * pollfd.events - 0 + * pollfd.fd - hnd + * However, poll() watches for POLLHUP regardless of the watch event mask. + * On NetBSD (or probably on other systems), EOF was reported despite + * the pending data to read. + * + * I just use /dev/null to avoid receiving premature EOF. Alternatively, + * using a pipe is possible whereas it will create two file descriptors. */ + mux->pd.pfd[idx].fd = mux->pd.pfd[idx].events? hnd: mux->devnull; return 0; case MIO_SYS_MUX_CMD_DELETE: diff --git a/mio/lib/sys-prv.h b/mio/lib/sys-prv.h index 7d1dde6..907f6cc 100644 --- a/mio/lib/sys-prv.h +++ b/mio/lib/sys-prv.h @@ -61,6 +61,9 @@ struct mio_sys_mux_t mio_oow_t size; mio_oow_t capa; } pd; /* poll data */ + + + int devnull; }; #elif defined(USE_EPOLL)