fs/fs_epoll: add oneshot list to handle the EPOLLONESHOT correctly
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
This commit is contained in:
parent
e317af0a84
commit
5d53c8299e
@ -69,6 +69,12 @@ struct epoll_head_s
|
||||
* these epoll node should be setup again
|
||||
* to check the pending poll notification.
|
||||
*/
|
||||
struct list_node oneshot; /* The oneshot list, store all the epoll
|
||||
* node notified after epoll_wait and with
|
||||
* EPOLLONESHOT events, these oneshot epoll
|
||||
* nodes can be reset by epoll_ctl (Move
|
||||
* from oneshot list to the setup list).
|
||||
*/
|
||||
struct list_node free; /* The free list, store all the freed epoll
|
||||
* node.
|
||||
*/
|
||||
@ -232,6 +238,7 @@ static int epoll_do_create(int size, int flags)
|
||||
|
||||
list_initialize(&eph->setup);
|
||||
list_initialize(&eph->teardown);
|
||||
list_initialize(&eph->oneshot);
|
||||
list_initialize(&eph->extend);
|
||||
list_initialize(&eph->free);
|
||||
for (i = 0; i < size; i++)
|
||||
@ -307,7 +314,7 @@ static int epoll_teardown(FAR epoll_head_t *eph, FAR struct epoll_event *evs,
|
||||
list_delete(&epn->node);
|
||||
if ((epn->pfd.events & EPOLLONESHOT) != 0)
|
||||
{
|
||||
list_add_tail(&eph->free, &epn->node);
|
||||
list_add_tail(&eph->oneshot, &epn->node);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -428,6 +435,15 @@ int epoll_ctl(int epfd, int op, int fd, FAR struct epoll_event *ev)
|
||||
}
|
||||
}
|
||||
|
||||
list_for_every_entry(&eph->oneshot, epn, epoll_node_t, node)
|
||||
{
|
||||
if (epn->pfd.fd == fd)
|
||||
{
|
||||
ret = -EEXIST;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (list_is_empty(&eph->free))
|
||||
{
|
||||
/* Malloc new epoll node, insert the first list_node to the
|
||||
@ -494,6 +510,16 @@ int epoll_ctl(int epfd, int op, int fd, FAR struct epoll_event *ev)
|
||||
}
|
||||
}
|
||||
|
||||
list_for_every_entry(&eph->oneshot, epn, epoll_node_t, node)
|
||||
{
|
||||
if (epn->pfd.fd == fd)
|
||||
{
|
||||
list_delete(&epn->node);
|
||||
list_add_tail(&eph->free, &epn->node);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EPOLL_CTL_MOD:
|
||||
@ -543,6 +569,27 @@ int epoll_ctl(int epfd, int op, int fd, FAR struct epoll_event *ev)
|
||||
list_add_tail(&eph->setup, &epn->node);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_every_entry(&eph->oneshot, epn, epoll_node_t, node)
|
||||
{
|
||||
if (epn->pfd.fd == fd)
|
||||
{
|
||||
epn->data = ev->data;
|
||||
epn->pfd.events = ev->events;
|
||||
epn->pfd.fd = fd;
|
||||
epn->pfd.revents = 0;
|
||||
|
||||
ret = poll_fdsetup(fd, &epn->pfd, true);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
list_delete(&epn->node);
|
||||
list_add_tail(&eph->setup, &epn->node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user