News for hackers. Stuff that matters.
Re:Epoll is broken – part 2/2 by ajross on Monday March 20, 2017 @11:18PM (#13919602)
> Closing a FD you are using is a bug.

Sort of, but think of the problem epoll is addressing: having an epoll-registered descriptor is semantically equivalent to having an active read() on the thing. That's sort of the whole point, of course. Calling close() on a descriptor blocked in read() works fine and produces the expected (synchronous EOF) behavior. Doing it on the epoll one produces surprising behavior depending on whether or not it got dup'd somewhere (which can have been somewhere outside your process!).

It's a bug for sure. Not sure it rises to the level of "fundamentally broken", but it's a bug.

Re:Epoll is broken – part 2/2 by mark4o on Tuesday March 21, 2017 @12:43AM (#13919921)
POSIX does not require EOF to be returned from a blocking read() if the same file descriptor is passed to close() in another thread. Even if it appears to work on some particular OS, consider the case where the reading thread may have called read() but is preempted just before entering the kernel. If another thread then closes the file descriptor, expecting the first thread to see EBADF or EOF, but then the file descriptor is reused (e.g. by accept()) before the first thread resumes, the reading thread may block reading from an unrelated socket. Even if you can guarantee that accept(), open(), or other calls that explicitly allocate a file descriptor will not be called, ordinary library functions are generally allowed to use file descriptors internally (e.g. to read a configuration file), so closing the file descriptor while another thread is reading from it is almost certainly a bug.
Re:Epoll is broken – part 2/2 by mbrumlow on Monday March 20, 2017 @11:38PM (#13919699)
epoll and read are different calls though, expecting them to behave the same when they have very different uses is weird to me.

If it is a bug, then why does the man page call out this case, and other cases with dup and dup2 as use cases? Was the man page edited after the fact to cover up the bug? If so why not change how it works?

I really disagree calling something somebody finds surprising a bug, even more so when the man page covers the "surprising" behaviour.

Edit:

Something was bugging me so I checked it out myself. You are actually wrong. and read does work the same way epoll works. If if you dup your fd, launch a pthread that will wait a while and then close the fd, and then start your blocking read call on the fd. If the thread closes your original fd while the read is active you will not get a EOF, and you will continue to receive data from the server. Only using the FD to a system call after the fd has been closed will generate an error.

This is very much what we are seeing with epoll. We pass a fd to a system call. It is now doing its thing. We then close the fd, and are now surprised that the system call has no clue what you are talking about? The thing to remember there is a table from FD to file (or description). That table is how we talk to the kernel about files. If that table is missing a entry it won't know what file we are talking about.