Questions tagged [epoll]

epoll is a Linux 2.6 readiness notification API for sockets, pipes, and special event-, signal-, and timer descriptors which can operate both in level- and edge-triggered mode, although presently only level-triggered behaviour is in accordance with the documentation. As opposed to poll or select, epoll scales O(1) in respect to the number of descriptors and O(N) in respect realized events.

The epoll API is built around 3 functions:

  • epoll_create creates a new epoll instance and returns a file descriptor that refers to it. This descriptor can be operated on with the other epoll functions and can be added to a different epoll instance
  • epoll_ctl allows file descriptors (sockets, pipes, eventfd, timerfd, signalfd, and epoll) being added and removed to an epoll's set of monitored descriptors, as well as flags of existing descriptors being modified
  • epoll_wait will return up to maxevents queued events. If no events are available, it will return zero. If a timeout is provided and no events are available, epoll_wait will block for the duration of the timeout (a value of -1 means forever).

The conceptual idea behind the API is that applications usually have a certain set of descriptors that changes rarely if ever, but which needs to be observed for readiness many times. Also, typically a lot fewer descriptors are ready than open. epoll therefore separates copying the list of descriptors to watch from the actual watching and notifies registered listeners instead of iterating a list of descriptors.

The operation of level-triggered mode (default) is easy, since it is identical of how poll/select works. As long as the resource is ready (e.g. as long as there remains data to be read), every call to epoll_wait will return an event.

The operation of edge-triggered mode (EPOLLET flag) is more complicated, more error-prone, inconsistenly documented, and inconsistently implemented. In epoll(7), it is explained in terms of reading partial data causing the next call to epoll_wait to block until new data arrives, but not while some data remains in the buffers. It is therefore recommended to use non-blocking descriptors and reading until EAGAIN is received.
According to The Linux Programming Interface, edge-triggered mode only reports events that happened since the last call to epoll_wait.
In reality, it does a mixture of both (i.e. both reads and epoll_wait reset the status to "not ready"), and it does not work as indicated in respect of several epoll instances listening to the same socket or several threads waiting on the same epoll instance (observed under kernel 2.6.38 with timerfd and eventfd). Although epoll is supposed to signal all waiters upon arrival of an event, in edge-triggered mode it only ever signals a single waiter.

792 questions
7
votes
2 answers

why is NON-BLOCKING sockets recommended in epoll

I'm trying to learn how to use epoll() for tcp server application, 'cause i'm expecting many connections. i tried checking samples and tutorials, they always recommend using/setting sockets that are added in epoll() to be NON-BLOCKING sockets. why?
7
votes
2 answers

What is "urgent data"?

The man page of epoll_ctl() says about EPOLLPRI: There is urgent data available for read(2) operations. How exactly is "urgent data" defined and who decides which data has priority?
user206268
  • 908
  • 2
  • 8
  • 23
7
votes
1 answer

Edge Triggered epoll c

On an edge triggered epoll event I read a socket (or multiple sockets, if required) until there is no more data (EAGAIN or EWOULDBLOCK) then loop back to epoll_wait. What happens if, while processing that read, another socket (one that is not…
jayjay
  • 1,017
  • 1
  • 11
  • 23
7
votes
1 answer

Does epoll preserve the order in which fd's was registered?

I'm playing around with Linux system call and I found some aspect of epoll, that is not clear to me. Say, I create a epoll instance: epollfd = epoll_create(50); Next, I register 50 file descriptors in for-loop: for(i=0; i<50; i++){ // open file…
Artem Mezhenin
  • 5,539
  • 6
  • 32
  • 51
7
votes
3 answers

Why having to use non-blocking fd in a edge triggered epoll function?

I read document abount edge triggered epoll function in web as follows: 1. The file descriptor that represents the read side of a pipe (rfd) is registered on the epoll instance. 2. A pipe writer writes 2 kB of data on the write side of the pipe. 3.…
user1804694
  • 121
  • 1
  • 5
7
votes
1 answer

how to use epoll with data->ptr, instead of data.fd?

I'm writing an application using epoll and large amount of fd's. in order to improve the searches of fd to application relevant DB, I want to pass to epoll application info, such as index in DB array. I thought of using the data->ptr (epoll_data_t…
user1927740
  • 73
  • 1
  • 4
7
votes
1 answer

General explanation of how epoll works?

I'm doing a technical write-up on switching from a database-polling (via synchronous stored procedure call) to a message queue (via pub/sub). I'd like to be able to explain how polling a database is vastly different and much heavier than setting up…
bitcycle
  • 7,632
  • 16
  • 70
  • 121
6
votes
2 answers

What is the order in which File Descriptors in epoll are returned?

Let's say I have set a set of file descriptors, say 8, 9, 10, 11, 12 in the order specified and do an epoll_wait() for data to be read on them. epoll_wait returns with data to be read on socket 8,10 and 11. Will the order of the file descriptors…
VSN
  • 386
  • 1
  • 2
  • 11
6
votes
2 answers

C++ Confused by epoll and socket fd on Linux systems and async threads

I am trying to understand how to use the epoll library (Linux) in combination with socket file descriptors. There is limited information about epoll available online as far as I can tell. So far the most useful resource I have found is…
FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225
6
votes
2 answers

Haskell concurrency over kqueue

I wrote concurrent application and have caught the error: buildFdSets: file descriptor out of range I found out that it is the OS limit on the number of file descriptors in one process, in my FreeBSD it is 1024. It is the limit of select(). Also…
Anton
  • 2,535
  • 2
  • 25
  • 28
6
votes
2 answers

One-shot *level*-triggered epoll(): Does EPOLLONESHOT imply EPOLLET?

Is it possible to use epoll in one-shot level-triggered mode? I couldn't find any information on it when I searched; it seems everyone uses edge-triggered mode.
user541686
  • 205,094
  • 128
  • 528
  • 886
6
votes
1 answer

asyncio python with serial device takes 100% CPU

When I run this little main from rfxcom python library : from asyncio import get_event_loop from rfxcom.transport import AsyncioTransport dev_name = '/dev/serial/by-id/usb-RFXCOM_RFXtrx433_A1XZI13O-if00-port0' loop = get_event_loop() def…
Bruno Thomas
  • 1,179
  • 17
  • 31
6
votes
0 answers

Stop EPOLLHUP on a closed pseudo-terminal

I am working on a small library for creating a pair of connected pts. I use an epoll fd, in which I register the master fd for two pseudo-terminals for EPOLLIN events. When my example client program starts, the event loop is idle and so it is when…
ncarrier
  • 433
  • 3
  • 14
6
votes
2 answers

non blocking tcp connect with epoll

My linux application is performing non-blocking TCP connect syscall and then use epoll_wait to detect three way handshake completion. Sometimes epoll_wait returns with both POLLOUT & POLLERR events set for the same socket descriptor. I would like to…
doccarcass
  • 71
  • 1
  • 1
  • 2
6
votes
1 answer

EPOLLRDHUP not reliable

I'm using non-blocking read/writes over a client-server TCP connection with epoll_wait. Problem is, I can't reliably detect 'peer closed connection' event using the EPOLLRDHUP flag. It often happens that the flag is not set. The client uses close()…
haelix
  • 4,245
  • 4
  • 34
  • 56