implemented the control pipe for poll

This commit is contained in:
hyung-hwan 2021-07-21 13:43:10 +00:00
parent bb57c88d6e
commit dc5752a3ed

View File

@ -34,6 +34,9 @@
#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) # define MUX_INDEX_SUSPENDED (MUX_INDEX_INVALID - 1)
static int secure_poll_map_slot_for_hnd (mio_t* mio, mio_syshnd_t hnd);
static int secure_poll_data_slot_for_insert (mio_t* mio);
#endif #endif
int mio_sys_initmux (mio_t* mio) int mio_sys_initmux (mio_t* mio)
@ -63,8 +66,29 @@ int mio_sys_initmux (mio_t* mio)
#endif #endif
#if defined(USE_POLL)
if (secure_poll_map_slot_for_hnd(mio, mux->ctrlp[0]) <= -1 ||
secure_poll_data_slot_for_insert(mio) <= -1)
{
/* no control pipes if registration fails */
close (mux->ctrlp[1]);
mux->ctrlp[1] = MIO_SYSHND_INVALID;
close (mux->ctrlp[0]);
mux->ctrlp[0] = MIO_SYSHND_INVALID;
}
else
{
mio_oow_t idx;
idx = mux->pd.size++;
mux->pd.pfd[idx].fd = mux->ctrlp[0];
mux->pd.pfd[idx].events = POLLIN;
mux->pd.pfd[idx].revents = 0;
mux->pd.dptr[idx] = MIO_NULL;
mux->map.ptr[mux->ctrlp[0]] = idx;
}
#if defined(USE_EPOLL)
#elif defined(USE_EPOLL)
#if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC) #if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC)
mux->hnd = epoll_create1(EPOLL_CLOEXEC); mux->hnd = epoll_create1(EPOLL_CLOEXEC);
@ -99,7 +123,14 @@ epoll_create_done:
struct epoll_event ev; struct epoll_event ev;
ev.events = EPOLLIN | EPOLLHUP | EPOLLERR; ev.events = EPOLLIN | EPOLLHUP | EPOLLERR;
ev.data.ptr = MIO_NULL; ev.data.ptr = MIO_NULL;
epoll_ctl(mux->hnd, EPOLL_CTL_ADD, mux->ctrlp[0], &ev); if (epoll_ctl(mux->hnd, EPOLL_CTL_ADD, mux->ctrlp[0], &ev) == -1)
{
/* if ADD fails, close the control pipes and forget them */
close (mux->ctrlp[1]);
mux->ctrlp[1] = MIO_SYSHND_INVALID;
close (mux->ctrlp[0]);
mux->ctrlp[0] = MIO_SYSHND_INVALID;
}
} }
#endif /* USE_EPOLL */ #endif /* USE_EPOLL */
@ -162,6 +193,62 @@ void mio_sys_intrmux (mio_t* mio)
if (mux->ctrlp[1] != MIO_SYSHND_INVALID) write (mux->ctrlp[1], "Q", 1); if (mux->ctrlp[1] != MIO_SYSHND_INVALID) write (mux->ctrlp[1], "Q", 1);
} }
#if defined(USE_POLL)
static int secure_poll_map_slot_for_hnd (mio_t* mio, mio_syshnd_t hnd)
{
mio_sys_mux_t* mux = &mio->sysdep->mux;
if (hnd >= mux->map.capa)
{
mio_oow_t new_capa;
mio_oow_t* tmp;
mio_oow_t idx;
new_capa = MIO_ALIGN_POW2((hnd + 1), 256);
tmp = mio_reallocmem(mio, mux->map.ptr, new_capa * MIO_SIZEOF(*tmp));
if (MIO_UNLIKELY(!tmp)) return -1;
for (idx = mux->map.capa; idx < new_capa; idx++) tmp[idx] = MUX_INDEX_INVALID;
mux->map.ptr = tmp;
mux->map.capa = new_capa;
}
return 0;
}
static int secure_poll_data_slot_for_insert (mio_t* mio)
{
mio_sys_mux_t* mux = &mio->sysdep->mux;
if (mux->pd.size >= mux->pd.capa)
{
mio_oow_t new_capa;
struct pollfd* tmp1;
mio_dev_t** tmp2;
new_capa = MIO_ALIGN_POW2(mux->pd.size + 1, 256);
tmp1 = mio_reallocmem(mio, mux->pd.pfd, new_capa * MIO_SIZEOF(*tmp1));
if (MIO_UNLIKELY(!tmp1)) return -1;
tmp2 = mio_reallocmem(mio, mux->pd.dptr, new_capa * MIO_SIZEOF(*tmp2));
if (MIO_UNLIKELY(!tmp2))
{
mio_freemem (mio, tmp1);
return -1;
}
mux->pd.pfd = tmp1;
mux->pd.dptr = tmp2;
mux->pd.capa = new_capa;
}
return 0;
}
#endif
int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_cap) int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_cap)
{ {
#if defined(USE_POLL) #if defined(USE_POLL)
@ -171,6 +258,20 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_
hnd = dev->dev_mth->getsyshnd(dev); hnd = dev->dev_mth->getsyshnd(dev);
#if 1
if (cmd == MIO_SYS_MUX_CMD_INSERT)
{
if (secure_poll_map_slot_for_hnd(mio, hnd) <= -1) return -1;
}
else
{
if (hnd >= mux->map.capa)
{
mio_seterrnum (mio, MIO_ENOENT);
return -1;
}
}
#else
if (hnd >= mux->map.capa) if (hnd >= mux->map.capa)
{ {
mio_oow_t new_capa; mio_oow_t new_capa;
@ -185,14 +286,14 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_
new_capa = MIO_ALIGN_POW2((hnd + 1), 256); new_capa = MIO_ALIGN_POW2((hnd + 1), 256);
tmp = mio_reallocmem(mio, mux->map.ptr, new_capa * MIO_SIZEOF(*tmp)); tmp = mio_reallocmem(mio, mux->map.ptr, new_capa * MIO_SIZEOF(*tmp));
if (!tmp) return -1; if (MIO_UNLIKELY(!tmp)) return -1;
for (idx = mux->map.capa; idx < new_capa; idx++) for (idx = mux->map.capa; idx < new_capa; idx++) tmp[idx] = MUX_INDEX_INVALID;
tmp[idx] = MUX_INDEX_INVALID;
mux->map.ptr = tmp; mux->map.ptr = tmp;
mux->map.capa = new_capa; mux->map.capa = new_capa;
} }
#endif
idx = mux->map.ptr[hnd]; idx = mux->map.ptr[hnd];
@ -206,6 +307,10 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_
} }
do_insert: do_insert:
#if 1
if (MIO_UNLIKELY(secure_poll_data_slot_for_insert(mio) <= -1)) return -1;
#else
if (mux->pd.size >= mux->pd.capa) if (mux->pd.size >= mux->pd.capa)
{ {
mio_oow_t new_capa; mio_oow_t new_capa;
@ -215,10 +320,10 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_
new_capa = MIO_ALIGN_POW2(mux->pd.size + 1, 256); new_capa = MIO_ALIGN_POW2(mux->pd.size + 1, 256);
tmp1 = mio_reallocmem(mio, mux->pd.pfd, new_capa * MIO_SIZEOF(*tmp1)); tmp1 = mio_reallocmem(mio, mux->pd.pfd, new_capa * MIO_SIZEOF(*tmp1));
if (!tmp1) return -1; if (MIO_UNLIKELY(!tmp1)) return -1;
tmp2 = mio_reallocmem(mio, mux->pd.dptr, new_capa * MIO_SIZEOF(*tmp2)); tmp2 = mio_reallocmem(mio, mux->pd.dptr, new_capa * MIO_SIZEOF(*tmp2));
if (!tmp2) if (MIO_UNLIKELY(!tmp2))
{ {
mio_freemem (mio, tmp1); mio_freemem (mio, tmp1);
return -1; return -1;
@ -228,6 +333,7 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_
mux->pd.dptr = tmp2; mux->pd.dptr = tmp2;
mux->pd.capa = new_capa; mux->pd.capa = new_capa;
} }
#endif
idx = mux->pd.size++; idx = mux->pd.size++;
@ -422,7 +528,15 @@ int mio_sys_waitmux (mio_t* mio, const mio_ntime_t* tmout, mio_sys_mux_evtcb_t e
for (i = 0; i < mux->pd.size; i++) for (i = 0; i < mux->pd.size; i++)
{ {
if (mux->pd.pfd[i].fd >= 0 && mux->pd.pfd[i].revents) if (MIO_UNLIKELY(mux->ctrlp[0] != MIO_SYSHND_INVALID && mux->pd.pfd[i].fd == mux->ctrlp[0]))
{
/* internal pipe for signaling */
/* mux->pd.dptr[i] must be MIO_NULL */
mio_uint8_t tmp[16];
while (read(mux->ctrlp[0], tmp, MIO_SIZEOF(tmp)) > 0) ;
}
else if (mux->pd.pfd[i].fd >= 0 && mux->pd.pfd[i].revents)
{ {
int events = 0; int events = 0;
mio_dev_t* dev; mio_dev_t* dev;