问题
I've been reading through libev's source code and stumbled upon this comment:
a) epoll silently removes fds from the fd set. as nothing tells us that an fd has been removed otherwise, we have to continually "rearm" fds that we suspect might have changed (same problem with kqueue, but much less costly there).
I've been doing some tests with epoll (directly using syscalls) on some modern linux kernel and I couldn't reproduce it. I didn't see any problem with "silently disappearing fds". Could someone elaborate on this and tell me if it's still an issue?
回答1:
This is rather vague text there, but I guess it is just that if the descriptor is close
d elsewhere, it is silently removed from the set. From Linux manpages, epoll(7):
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 (see
open(2)
). Whenever a descriptor is duplicated viadup(2)
,dup2(2)
,fcntl(2)
F_DUPFD
, orfork(2)
, a new file descriptor refer‐ ring to the same open file description is cre‐ ated. An open file description continues to exist until all file descriptors referring to it have been closed. A file descriptor is removed from an epoll 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 an epoll set has been closed, events may be reported for that file descriptor if other file descrip‐ tors referring to the same underlying file description remain open.
So you have a socket with fd 42. It gets close
d, and subsequently removed from the epoll
object. But the kernel doesn't notify the libev
about this through epoll_wait
. Now the epoll_modify
is called again with fd = 42
. epoll_modify
doesn't know whether this file descriptor 42 the same that already was in the epoll
object or some other file description with the file descriptor number 42 reused.
One could also argue that the comments are just ranting and the design of the libev
API is at fault here.
来源:https://stackoverflow.com/questions/46987302/epoll-does-it-silently-remove-fds