changed mux-poll implementation
This commit is contained in:
parent
7613f09bed
commit
829267edd7
@ -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()
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user