epoll_ctl() 事件参数的生命周期
Lifetime of the epoll_ctl() event parameter
man
page for epoll_ctl()
给出了这个签名:
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
是否应该保存 epoll_event
参数,直到我们完成所有 epoll_wait()
处理?
换句话说,这个基于epoll
man page sample的代码是否正确?
int listen_sock, nfds, epollfd;
/* Code to set up listening socket, 'listen_sock', (socket(), bind(), listen()) omitted. */
epollfd = epoll_create1(0);
if (epollfd == -1) {
perror("epoll_create1");
exit(EXIT_FAILURE);
}
{
/* limit ev's scope */
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = listen_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
perror("epoll_ctl: listen_sock");
exit(EXIT_FAILURE);
}
}
struct epoll_event events[MAX_EVENTS];
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
我认为 epoll_event 在我们完成所有 epoll_wait() 处理之前不需要保存
因为 linux 在调用系统调用 epoll_ctl
后立即使用 copy_from_user
SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
struct epoll_event __user *, event)
{
struct epoll_event epds;
if (ep_op_has_event(op) &&
copy_from_user(&epds, event, sizeof(struct epoll_event)))
return -EFAULT;
return do_epoll_ctl(epfd, op, fd, &epds, false);
}
这里有详细信息:https://elixir.bootlin.com/linux/latest/source/fs/eventpoll.c#L2176
man
page for epoll_ctl()
给出了这个签名:
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
是否应该保存 epoll_event
参数,直到我们完成所有 epoll_wait()
处理?
换句话说,这个基于epoll
man page sample的代码是否正确?
int listen_sock, nfds, epollfd;
/* Code to set up listening socket, 'listen_sock', (socket(), bind(), listen()) omitted. */
epollfd = epoll_create1(0);
if (epollfd == -1) {
perror("epoll_create1");
exit(EXIT_FAILURE);
}
{
/* limit ev's scope */
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = listen_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
perror("epoll_ctl: listen_sock");
exit(EXIT_FAILURE);
}
}
struct epoll_event events[MAX_EVENTS];
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
我认为 epoll_event 在我们完成所有 epoll_wait() 处理之前不需要保存
因为 linux 在调用系统调用 epoll_ctl
SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
struct epoll_event __user *, event)
{
struct epoll_event epds;
if (ep_op_has_event(op) &&
copy_from_user(&epds, event, sizeof(struct epoll_event)))
return -EFAULT;
return do_epoll_ctl(epfd, op, fd, &epds, false);
}
这里有详细信息:https://elixir.bootlin.com/linux/latest/source/fs/eventpoll.c#L2176