summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzmq810150896 <[email protected]>2023-09-06 11:22:16 +0800
committerGitHub <[email protected]>2023-09-06 11:22:16 +0800
commit722a5fc29d9d7b22af4e1967098505cebbc2fa32 (patch)
tree704b13f8ad97a3308e7b75494988837d9e0290f1
parent3602f891211904a27dcbd51e5ba72fefce7326b2 (diff)
Optimize the epoll code to remove restrictions on descriptors (#7951)
-rw-r--r--components/libc/posix/io/epoll/epoll.c83
1 files changed, 42 insertions, 41 deletions
diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c
index f5d4cbd938..24d3e376a3 100644
--- a/components/libc/posix/io/epoll/epoll.c
+++ b/components/libc/posix/io/epoll/epoll.c
@@ -36,6 +36,7 @@ struct rt_fd_list
rt_pollreq_t req;
struct rt_eventpoll *ep;
struct rt_wqueue_node wqn;
+ int fd;
struct rt_fd_list *next;
};
@@ -206,7 +207,7 @@ static int epoll_rdlist_add(struct rt_fd_list *fdl, rt_uint32_t revents)
while (rdlist->next != RT_NULL)
{
rdlist = rdlist->next;
- if (rdlist->rdl_event->epev.data.fd == fdl->epev.data.fd)
+ if (rdlist->rdl_event->fd == fdl->fd)
{
isexist = 1;
res = 0;
@@ -227,10 +228,6 @@ static int epoll_rdlist_add(struct rt_fd_list *fdl, rt_uint32_t revents)
ep->rdlist->next = rdlist;
ep->eventpoll_num ++;
res = 0;
- if (rdlist->rdl_event->revents & EPOLLONESHOT)
- {
- rdlist->rdl_event->revents = 0;
- }
}
}
@@ -282,6 +279,7 @@ static void epoll_ctl_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep
fdlist->req._key = fdlist->revents;
mask = epoll_get_event(fdlist, &fdlist->req);
+
if (mask & fdlist->revents)
{
epoll_rdlist_add(fdlist, mask);
@@ -328,7 +326,7 @@ static int epoll_epf_init(int fd)
if (ep->fdlist)
{
ep->fdlist->next = RT_NULL;
- ep->fdlist->epev.data.fd = fd;
+ ep->fdlist->fd = fd;
ep->fdlist->ep = ep;
dfs_vnode_init(df->vnode, FT_REGULAR, &epoll_fops);
df->vnode->data = ep;
@@ -387,7 +385,7 @@ static int epoll_do_create(int size)
return ret;
}
-static int epoll_ctl_add(struct dfs_file *df ,struct epoll_event *event)
+static int epoll_ctl_add(struct dfs_file *df, int fd, struct epoll_event *event)
{
struct rt_fd_list *fdlist;
struct rt_eventpoll *ep;
@@ -401,7 +399,7 @@ static int epoll_ctl_add(struct dfs_file *df ,struct epoll_event *event)
while (fdlist->next != RT_NULL)
{
- if (fdlist->next->epev.data.fd == event->data.fd)
+ if (fdlist->next->fd == fd)
{
return 0;
}
@@ -411,7 +409,8 @@ static int epoll_ctl_add(struct dfs_file *df ,struct epoll_event *event)
fdlist = (struct rt_fd_list *)rt_malloc(sizeof(struct rt_fd_list));
if (fdlist)
{
- fdlist->epev.data.fd = event->data.fd;
+ fdlist->fd = fd;
+ memcpy(&fdlist->epev.data, &event->data, sizeof(event->data));
fdlist->epev.events = event->events;
fdlist->ep = ep;
fdlist->req._proc = epoll_wqueue_add_callback;
@@ -430,7 +429,7 @@ static int epoll_ctl_add(struct dfs_file *df ,struct epoll_event *event)
return ret;
}
-static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event)
+static int epoll_ctl_del(struct dfs_file *df, int fd)
{
struct rt_fd_list *fdlist, *fre_fd;
struct rt_eventpoll *ep = RT_NULL;
@@ -444,7 +443,7 @@ static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event)
fdlist = ep->fdlist;
while (fdlist->next != RT_NULL)
{
- if (fdlist->next->epev.data.fd == event->data.fd)
+ if (fdlist->next->fd == fd)
{
fre_fd = fdlist->next;
fdlist->next = fdlist->next->next;
@@ -466,7 +465,7 @@ static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event)
rdlist = ep->rdlist;
while (rdlist->next != RT_NULL)
{
- if (rdlist->next->rdl_event->epev.data.fd == event->data.fd)
+ if (rdlist->next->rdl_event->fd == fd)
{
fre_rdl = rdlist->next;
rdlist->next = rdlist->next->next;
@@ -487,7 +486,7 @@ static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event)
return ret;
}
-static int epoll_ctl_mod(struct dfs_file *df ,struct epoll_event *event)
+static int epoll_ctl_mod(struct dfs_file *df, int fd, struct epoll_event *event)
{
struct rt_fd_list *fdlist;
struct rt_eventpoll *ep = RT_NULL;
@@ -500,9 +499,9 @@ static int epoll_ctl_mod(struct dfs_file *df ,struct epoll_event *event)
fdlist = ep->fdlist;
while (fdlist->next != RT_NULL)
{
- if (fdlist->next->epev.data.fd == event->data.fd)
+ if (fdlist->next->fd == fd)
{
- fdlist->next->epev.events = event->events;
+ memcpy(&fdlist->next->epev.data, &event->data, sizeof(event->data));
fdlist->next->revents = event->events;
rt_wqueue_remove(&fdlist->next->wqn);
epoll_ctl_install(fdlist->next, ep);
@@ -530,7 +529,7 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event)
return -1;
}
- if ((epfd == fd) || (epfd < 0) || (fd < 0) || (event->data.fd != fd))
+ if ((epfd == fd) || (epfd < 0))
{
rt_set_errno(EINVAL);
return -1;
@@ -542,6 +541,12 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event)
return -1;
}
+ if (!fd_get(fd))
+ {
+ rt_set_errno(EBADF);
+ return -1;
+ }
+
epdf = fd_get(epfd);
if (epdf->vnode->data)
@@ -553,13 +558,13 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event)
switch (op)
{
case EPOLL_CTL_ADD:
- ret = epoll_ctl_add(epdf, event);
+ ret = epoll_ctl_add(epdf, fd, event);
break;
case EPOLL_CTL_DEL:
- ret = epoll_ctl_del(epdf, event);
+ ret = epoll_ctl_del(epdf, fd);
break;
case EPOLL_CTL_MOD:
- ret = epoll_ctl_mod(epdf, event);
+ ret = epoll_ctl_mod(epdf, fd, event);
break;
default:
rt_set_errno(EINVAL);
@@ -623,7 +628,7 @@ static int epoll_get_event(struct rt_fd_list *fl, rt_pollreq_t *req)
int mask = 0;
int fd = 0;
- fd = fl->epev.data.fd;
+ fd = fl->fd;
if (fd >= 0)
{
df = fd_get(fd);
@@ -667,37 +672,34 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max
rdlist = rdlist->next;
if (event_num < maxevents)
{
- if (rdlist->rdl_event->revents == 0)
+ rt_wqueue_remove(&rdlist->rdl_event->wqn);
+ mask = epoll_get_event(rdlist->rdl_event, &rdlist->rdl_event->req);
+
+ if (mask & rdlist->rdl_event->revents)
+ {
+ rdlist->rdl_event->epev.events = mask & rdlist->rdl_event->revents;
+ }
+ else
{
isfree = 1;
+ isn_add = 1;
+ }
+
+ if (rdlist->rdl_event->revents & EPOLLONESHOT)
+ {
+ rdlist->rdl_event->revents = 0;
+ isfree = 1;
rt_wqueue_remove(&rdlist->rdl_event->wqn);
}
else
{
if (rdlist->rdl_event->revents & EPOLLET)
{
- rt_wqueue_remove(&rdlist->rdl_event->wqn);
- mask = epoll_get_event(rdlist->rdl_event, &rdlist->rdl_event->req);
- rdlist->rdl_event->epev.events = mask & rdlist->rdl_event->revents;
isfree = 1;
}
else
{
- if (rdlist->exclusive)
- {
- rt_wqueue_remove(&rdlist->rdl_event->wqn);
- mask = epoll_get_event(rdlist->rdl_event, &rdlist->rdl_event->req);
- if (mask & rdlist->rdl_event->revents)
- {
- rdlist->rdl_event->epev.events = mask;
- }
- else
- {
- isfree = 1;
- isn_add = 1;
- }
- }
- else
+ if (rdlist->exclusive != 1)
{
rdlist->exclusive = 1;
}
@@ -706,8 +708,7 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max
if (!isn_add)
{
- events[event_num].data.fd = rdlist->rdl_event->epev.data.fd;
- events[event_num].events = rdlist->rdl_event->epev.events;
+ memcpy(&events[event_num], &rdlist->rdl_event->epev, sizeof(rdlist->rdl_event->epev));
event_num ++;
}