Project

General

Profile

Bug #8636

recursive epoll should emit EPOLLRDNORM

Added by Patrick Mooney over 3 years ago. Updated over 3 years ago.

Status:
Closed
Priority:
Normal
Category:
kernel
Start date:
2017-09-07
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:

Description

This replicates downstream bug OS-5894

When polling on an epoll descriptor, it should emit EPOLLIN|EPOLLRDNORM when descriptors contained within have pending events. The current logic only yields EPOLLIN.

#1

Updated by Patrick Mooney over 3 years ago

Like #8634, this was tested using a program from the epoll test suite:

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

#include "common.h" 

int
main(int argc, char **argv)
{
        int efd, nefd, pipefd[2];
        struct epoll_event ev;

        test_init(argc, argv);

        if (pipe(pipefd) != 0) {
                test_fatal("pipe()");
        }

        if ((efd = epoll_create1(0)) < 0) {
                test_fatal("epoll_create1()");
        }
        ev.events = EPOLLIN;
        ev.data.fd = pipefd[0];
        if (epoll_ctl(efd, EPOLL_CTL_ADD, pipefd[0], &ev) < 0) {
                test_fatal("epoll_ctl(EPOLL_CTL_ADD)");
        }

        if ((nefd = epoll_create1(0)) < 0) {
                test_fatal("epoll_create1()");
        }
        /* cast a wide net */
        ev.events = EPOLLIN|EPOLLRDNORM|EPOLLRDBAND|EPOLLMSG;
        ev.events |= EPOLLOUT|EPOLLWRNORM|EPOLLWRBAND;
        ev.data.fd = efd;
        if (epoll_ctl(nefd, EPOLL_CTL_ADD, efd, &ev) < 0) {
                test_fatal("epoll_ctl(EPOLL_CTL_ADD)");
        }

        /* No events should be pending yet */
        test_equal(epoll_wait(efd, &ev, 1, 0), 0);
        test_equal(epoll_wait(nefd, &ev, 1, 0), 0);

        if (write(pipefd[1], "\0", 1) != 1) {
                test_fatal("write()");
        }

        test_equal(epoll_wait(efd, &ev, 1, 0), 1);
        test_equal(ev.events, EPOLLIN);
        test_equal(ev.data.fd, pipefd[0]);

        test_equal(epoll_wait(nefd, &ev, 1, 0), 1);
        test_equal(ev.events, EPOLLIN|EPOLLRDNORM);
        test_equal(ev.data.fd, efd);

        test_done();
}

Comparing results between unpatched and patched -gate builds showed correction of the EPOLLRDNORM behavior.

#2

Updated by Electric Monk over 3 years ago

  • Status changed from In Progress to Closed
  • % Done changed from 0 to 100

git commit 80d5689f5d4588adc071138e25e9d0d5252d9b55

commit  80d5689f5d4588adc071138e25e9d0d5252d9b55
Author: Patrick Mooney <pmooney@pfmooney.com>
Date:   2017-10-19T02:47:16.000Z

    8634 epoll fails to wake on certain edge-triggered conditions
    8635 epoll should not emit POLLNVAL
    8636 recursive epoll should emit EPOLLRDNORM
    Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
    Reviewed by: Robert Mustacchi <rm@joyent.com>
    Reviewed by: Toomas Soome <tsoome@me.com>
    Reviewed by: Igor Kozhukhov <igor@dilos.org>
    Approved by: Dan McDonald <danmcd@joyent.com>

Also available in: Atom PDF