Question about epoll and splice
1st question
- You can use edge triggered rather then even triggered polling thus you do not have to delete socket each time.
- You can use EPOLLONESHOT to prevent removing socket
File descriptor has to become readable first and there will be some interval before socket will become writable.
What kind of file descriptor? If this file on file system you can't use select/poll or other tools for this purpose, file will be always readable or writeable regardless the state if disk and cache. If you need to do staff asynchronous you may use aio_*
API but generally just read from file write to file and assume it is non-blocking.
If it is TCP socket then it would be writeable most of the time. It is better to use
non-blocking calls and put sockets to epoll when you get EWOULDBLOCK.
Distinguishing file descriptor types in epoll
Yes you have to compare the file descriptors. The example in the manual page does this.
chaining multiple epoll instances
From man epoll
Q3 Is the epoll file descriptor itself poll/epoll/selectable?
A3 Yes. If an epoll file descriptor has events waiting, then it will indicate as being readable.
How does epoll return the correct file descriptor
- So how does
events[i].data.fd
contain the socket file descriptor?
It's put in there by epoll_wait()
. It fills in the events
array with information about all the events that occurred.
- Why do we set
ev.data.fd=listenfd;
if we have an array ofepoll_event
, which has a file descriptor data member?
ev
is used to register events to wait for with epoll_ctl()
, the events
array contains the events that occurred.
When to rearm epoll with edge mode & oneshot?
Should I rearm before calling a non-blocking operation or after?
Technically, after, but it's not as simple as that.
Regardless of EPOLLONESHOT
, once you receive an edge-triggered event signalling read-readiness of a given file descriptor, you must consider that FD to continue to be ready until a read()
on it fails with errno
set to EAGAIN
(and therefore the file must be in non-blocking mode). Over the course of those reads, it may be the case that you read all remaining bytes with one read()
, but then more arrive before the next. In that case, if the FD is still armed then a new event for it will be queued (or merged with another event for that FD, as appropriate). This is the case that could result in you receiving an event when in fact the FD is not any longer ready.
You should consider just accepting those "phantom" events. Since your file will be in non-blocking mode, they will not cause unwanted stalls, just a little extra work. And your code will be simpler. But if you do use EPOLLONESHOT
to avoid receiving phantom events, then you must not re-arm the FD before you determine it to be unready (via a read
failing with EAGAIN
), else you defeat the purpose.
Thus, the full answer is after the FD is determined to be unready. That will take at least two read()
s, and possibly more. If the file becomes ready after the last read and before the rearming then the rearming should cause an appropriate event to be queued.
Is it necessary to deregister a socket from epoll before closing it?
From the man page:
Q6 Will closing a file descriptor cause it to be removed from all epoll sets
automatically?A6 Yes, but be aware of the following point. A file descriptor is a
reference to an open file description (seeopen
(2)). Whenever a
descriptor is duplicated viadup
(2),dup2
(2),fcntl
(2)F_DUPFD
, or
fork
(2), a new file descriptor referring to the same open file description
is created. An open file description continues to exist until all file
descriptors referring to it have been closed. A file descriptor is
removed from anepoll
set only after all the file descriptors referring to
the underlying open file description have been closed (or before if the
descriptor is explicitly removed usingepoll_ctl
(2)EPOLL_CTL_DEL
). This
means that even after a file descriptor that is part of anepoll
set has
been closed, events may be reported for that file descriptor if other file
descriptors referring to the same underlying file description remain open.
epoll VS select
select
is the standard Unix facility for doing asynchronous IO. Its programming interface is quirky, and its implementation in most Unixes is mediocre at best. It also imposes a limit on the maximum number of descriptors a process can watch, which is inconvenient in an application. Regarding efficiency, the performance of select
usually degrades linearly with the number of descriptors.
epoll
is a huge improvement over select
in terms of programming interface and efficiency, but is only provided in Linux starting from version 2.6. Other Unixes have their specialised calls, too.
Why epoll_wait() doesn't react on dup2(writable_fd, non_writable_fd)?
The problem is that epoll
cares about "open file descriptions", not about file descriptors. The answer is hidden in a few layers of man pages. First, epoll_wait
:
Will closing a file descriptor cause it to be removed from all epoll
sets automatically?Yes, but be aware of the following point. A file
descriptor is a reference to an open file description (see
open(2))[...]
Back to your dup2
call:
dup2(writable_fd, non_writable_fd)
dup2
call atomically first closes non_writable_fd
and then makes it point to the same file description as writable_fd
. Consider 2 cases:
You didn't do anything special so your
dup2
ends up closing the open file description associated withnon_writable_fd
. In this caseepoll
simply removes it from the set and that's thatYou had beforehand
dup
'dnon_writable_fd
into something else. In this casedup2
simply severs the association betweennon_writable_fd
and its OFD, which lives on, watched byepoll
In both situations your dup
call doesn't achieve what you want: you need to explicitly call epoll_ctl
again.
how to assign a context to a socket or an epoll event
The epoll_event structure that you pass to epoll_ctl(), and which is filled in by epoll_wait(), has a data_ptr field.
Related Topics
How Does Sort Work Out How Much Ram There Is
How to Determine a Tar Archive's Format
How to Add Multilanguage Support to a Yocto Build
Killing a Daemon Using a Pid File
How to Extract Text Which Matches Particular Fields in Text File Using Linux Commands
Monitoring (Sniffing) /Dev/Ttyusb0 Created by Ftdi Usb Serial Converter
PHPmyadmin, Neginx Error.Log - Check Group Www-Data Has Read Access and Open_Basedir
How to Finding All Runnable Processes
Linux Bash Commands to Remove Duplicates from a CSV File
Inspect Network Traffic from Simple Linux Cli App
A Mess with Different Perl Installs
Sysfs Interface. I Can't Export Gpio Pins in a Xilinx's Board (Zybo and Other)
Wmctrl: Moving a Fullscreen Window
Ssh-Add from Bash Script and Automate Passphrase Entry
How Does Linux Handles The I/O Permission Bitmap in The Tss Structure