Page MenuHomeFreeBSD

Linux epoll: Don't deregister file descriptor after EPOLLONESHOT is fired
ClosedPublic

Authored by wulf on Nov 23 2019, 11:58 AM.
Tags
None
Referenced Files
F103103196: D22513.id.diff
Thu, Nov 21, 1:00 AM
Unknown Object (File)
Tue, Nov 12, 11:43 AM
Unknown Object (File)
Mon, Nov 11, 12:15 AM
Unknown Object (File)
Tue, Nov 5, 5:05 PM
Unknown Object (File)
Tue, Nov 5, 12:17 PM
Unknown Object (File)
Thu, Oct 31, 3:57 PM
Unknown Object (File)
Oct 9 2024, 12:10 AM
Unknown Object (File)
Oct 2 2024, 9:56 AM
Subscribers

Details

Summary

Linux epoll does not remove descriptor after one-shot event has been triggered.
Set EV_DISPATCH kqueue flag rather then EV_ONESHOT to get the same behavior.

Required for Linux Steam client.

PR/240590

Test Plan
/* Sample testcase */

#include <sys/epoll.h>
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int
main(int argc, char *argv[])
{
        struct epoll_event event, events[1];
        int epfd, err, n;

        epfd = epoll_create1(EPOLL_CLOEXEC);
        assert(epfd);

        event.events = EPOLLOUT | EPOLLONESHOT;

        err = epoll_ctl(epfd, EPOLL_CTL_ADD, STDOUT_FILENO, &event);
        assert(err == 0);

        n = epoll_wait(epfd, events, 1, -1);
        assert(n > 0);

        if (epoll_ctl(epfd, EPOLL_CTL_MOD, STDOUT_FILENO, &event) != 0) {
                perror("EPOLL_CTL_MOD failed");
                exit(EXIT_FAILURE);
        }

        n = epoll_wait(epfd, events, 1, -1);
        assert(n > 0);

        if (epoll_ctl(epfd, EPOLL_CTL_DEL, STDOUT_FILENO, &event) != 0) {
                perror("EPOLL_CTL_DEL failed");
                exit(EXIT_FAILURE);
        }

        printf("ok\n");
        return (EXIT_SUCCESS);
}

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable