1
votes

My understanding of epoll and edge triggered behaviour was that you are notified when a state change occurs for a given file descriptor. Ie, when data becomes available on the fd, you get notified but you only get notified again after you drain all the data (you get EAGAIN) and data becomes present again.

Based on this understanding, I'd implemented a server which does the following:

  1. Listens for client connections
  2. For each connections, add fd into epoll
  3. When data available on fd, spawn a separate thread to read until EAGAIN
  4. Repeat until data reads are done

Semi pseudo-code:

n = epoll_wait(efd, events, MAXEVENTS, -1);

for (i = 0; i < n; ++i) {
    check for errors;
    if (server_sock == events[i].data.fd) {
        conn = accept( ... );
        make_nonblocking(conn);
        event.data.fd = conn;
        event.events = EPOLLIN | EPOLLRDHUP;
        epoll_ctl(efd, EPOLL_CTL_ADD, conn, &event);
    } else {
        spawn_reader(events[i].data.fd);
    }

With the above code, my expectation was that until the reader thread hits EAGAIN, epoll will not spawn another thread for this fd. This doesn't seem to be the case and I get many threads being spawned.

Am I using epoll incorrectly? I shouldn't need to remove the fd via EPOLL_CTL_DEL each time I spawn the reader thread, correct?

1

1 Answers

0
votes

Yes, its working as it should. epoll allows asynchronous IO programming in a single thread of control (event driven). Using a thread to process reads on an fd does not remove it from the list of monitored fds.