changed mux-poll implementation

This commit is contained in:
hyung-hwan 2020-05-24 17:25:27 +00:00
parent 7613f09bed
commit 829267edd7
3 changed files with 46 additions and 36 deletions

View File

@ -33,6 +33,7 @@
/* ========================================================================= */ /* ========================================================================= */
#if defined(USE_POLL) #if defined(USE_POLL)
# define MUX_INDEX_INVALID MIO_TYPE_MAX(mio_oow_t) # define MUX_INDEX_INVALID MIO_TYPE_MAX(mio_oow_t)
# define MUX_INDEX_SUSPENDED (MUX_INDEX_INVALID - 1)
#endif #endif
int mio_sys_initmux (mio_t* mio) int mio_sys_initmux (mio_t* mio)
@ -123,27 +124,17 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_
} }
idx = mux->map.ptr[hnd]; idx = mux->map.ptr[hnd];
if (idx != MUX_INDEX_INVALID)
{
if (cmd == MIO_SYS_MUX_CMD_INSERT)
{
mio_seterrnum (mio, MIO_EEXIST);
return -1;
}
}
else
{
if (cmd != MIO_SYS_MUX_CMD_INSERT)
{
mio_seterrnum (mio, MIO_ENOENT);
return -1;
}
}
switch (cmd) switch (cmd)
{ {
case MIO_SYS_MUX_CMD_INSERT: case MIO_SYS_MUX_CMD_INSERT:
if (idx != MUX_INDEX_INVALID || idex != MUX_INDEX_SUSPENDED)
{
mio_seterrnum (mio, MIO_EEXIST);
return -1;
}
do_insert:
if (mux->pd.size >= mux->pd.capa) if (mux->pd.size >= mux->pd.capa)
{ {
mio_oow_t new_capa; mio_oow_t new_capa;
@ -181,32 +172,49 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_
return 0; return 0;
case MIO_SYS_MUX_CMD_UPDATE: case MIO_SYS_MUX_CMD_UPDATE:
MIO_ASSERT (mio, mux->pd.dptr[idx] == dev); {
mux->pd.pfd[idx].events = 0; int events = 0;
if (dev_cap & MIO_DEV_CAP_IN_WATCHED) mux->pd.pfd[idx].events |= POLLIN; if (dev_cap & MIO_DEV_CAP_IN_WATCHED) events |= POLLIN;
if (dev_cap & MIO_DEV_CAP_OUT_WATCHED) mux->pd.pfd[idx].events |= POLLOUT; if (dev_cap & MIO_DEV_CAP_OUT_WATCHED) events |= POLLOUT;
/* On NetBSD 7.1.2 (GENERIC.201803151611Z) i386, the following happened. if (idx == MIO_INDEX_INVALID)
* There is still pending data to read on the file descriptor. {
* Disable input and output watching. mio_seterrnum (mio, MIO_ENOENT);
* The other end of file descriptor closes it (EOF). return -1;
* Because input and output watching is disabled, the file descriptor is }
* included into the pollfd watch set with the following values. else if (idx == MIO_INDEX_SUSPENDED)
* pollfd.events - 0 {
* pollfd.fd - hnd if (!events) return 0; /* no change. keep suspended */
* However, poll() watches for POLLHUP regardless of the watch event mask. goto do_insert;
* On NetBSD (or probably on other systems), EOF was reported despite }
* the pending data to read.
* if (!events)
* I just use /dev/null to avoid receiving premature EOF. Alternatively, {
* using a pipe is possible whereas it will create two file descriptors. */ mux->map.ptr[hnd] = MUX_INDEX_SUSPENDED;
mux->pd.pfd[idx].fd = mux->pd.pfd[idx].events? hnd: mux->devnull; goto do_delete;
}
MIO_ASSERT (mio, mux->pd.dptr[idx] == dev);
mux->pd.pfd[idx].events = events;
return 0; return 0;
case MIO_SYS_MUX_CMD_DELETE: case MIO_SYS_MUX_CMD_DELETE:
if (idx == MIO_INDEX_INVALID)
{
mio_seterrnum (mio, MIO_ENOENT);
return -1;
}
else if (idx == MUX_INDEX_SUSPENDED)
{
mux->map.ptr[hnd] = MUX_INDEX_INVALID;
return 0;
}
MIO_ASSERT (mio, mux->pd.dptr[idx] == dev); MIO_ASSERT (mio, mux->pd.dptr[idx] == dev);
mux->map.ptr[hnd] = MUX_INDEX_INVALID; mux->map.ptr[hnd] = MUX_INDEX_INVALID;
do_delete:
/* TODO: speed up deletion. allow a hole in the array. /* TODO: speed up deletion. allow a hole in the array.
* delay array compaction if there is a hole. * delay array compaction if there is a hole.
* set fd for the hole to -1 such that poll() * set fd for the hole to -1 such that poll()

View File

@ -6,4 +6,6 @@ echo
printenv printenv
exec cat /home/hyung-hwan/projects/hawk/lib/run.c exec cat /home/hyung-hwan/projects/hawk/lib/run.c
##exec cat /home/hyung-hwan/projects/hawk/lib/uch-prop.h
##exec cat /tmp/qq

View File

@ -14,6 +14,6 @@ Connection: close\r\n\r\n";
sys::write (x, msg); sys::write (x, msg);
while (sys::read (x, buf) > 0) printf ("%s", buf); while (sys::read (x, buf) > 0) { printf ("%s", buf); }
sys::close (x); sys::close (x);
} }