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)
# define MUX_INDEX_INVALID MIO_TYPE_MAX(mio_oow_t)
# define MUX_INDEX_SUSPENDED (MUX_INDEX_INVALID - 1)
#endif
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];
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)
{
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)
{
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;
case MIO_SYS_MUX_CMD_UPDATE:
MIO_ASSERT (mio, mux->pd.dptr[idx] == 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;
{
int events = 0;
if (dev_cap & MIO_DEV_CAP_IN_WATCHED) events |= POLLIN;
if (dev_cap & MIO_DEV_CAP_OUT_WATCHED) 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;
if (idx == MIO_INDEX_INVALID)
{
mio_seterrnum (mio, MIO_ENOENT);
return -1;
}
else if (idx == MIO_INDEX_SUSPENDED)
{
if (!events) return 0; /* no change. keep suspended */
goto do_insert;
}
if (!events)
{
mux->map.ptr[hnd] = MUX_INDEX_SUSPENDED;
goto do_delete;
}
MIO_ASSERT (mio, mux->pd.dptr[idx] == dev);
mux->pd.pfd[idx].events = events;
return 0;
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);
mux->map.ptr[hnd] = MUX_INDEX_INVALID;
do_delete:
/* TODO: speed up deletion. allow a hole in the array.
* delay array compaction if there is a hole.
* set fd for the hole to -1 such that poll()

View File

@ -6,4 +6,6 @@ echo
printenv
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);
while (sys::read (x, buf) > 0) printf ("%s", buf);
while (sys::read (x, buf) > 0) { printf ("%s", buf); }
sys::close (x);
}