Input still available after EPOLLHUP from pipe
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 6k
- Forks
- 1.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 10
Description
| benji reported | |
|---|---|
| Trac ID | trac#7932 |
| Type | defect |
| Created | 2015-06-08 19:32:18Z |
I have an app that uses the epoll reactor to read input from a subprocess. Infrequently the EPOLLHUP event will arrive before the first EPOLLIN event, even though input is available.
Here is a self-contained test script which will generate a test failure about every 100 runs on my machine: http://pastebin.ubuntu.com/11655018/. Save it as repro.py and run "trial -u repro.py". It may take a while to fail. It seems to fail more frequently on slower machines.
Seeing that http://man7.org/linux/man-pages/man2/epoll_ctl.2.html says of EPOLLHUP:
Note that when reading from a channel such as a pipe or a stream
socket, this event merely indicates that the peer closed its end
of the channel. Subsequent reads from the channel will return 0
(end of file) only after all outstanding data in the channel has
been consumed.
I added this hack to our app:
reactor._POLL_IN |= EPOLLHUP
Which causes the reactor to consider the channel readable on EPOLLHUP events. This completely rectified the issue for the test script and our app.
I'm not certain this is actually enough to solve it generally though; my reading of the above man page suggests that it may take multiple post-HUP reads to completely drain the available input.
I was using Twisted 15.2.1 with Python 2.7.8 running on Ubuntu 14.04.2.
Searchable metadata
trac-id__7932 7932
type__defect defect
reporter__benji benji
priority__normal normal
milestone__
branch__
branch_author__
status__assigned assigned
resolution__None None
component__core core
keywords__
time__1433791938007367 1433791938007367
changetime__1469268134345035 1469268134345035
version__None None
owner__sparkiegeek sparkiegeek
cc__@acollard
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Save the linked script as repro.py and run trial -u repro.py to reproduce the intermittent failure. Start by tracing the epoll reactor's handling of EPOLLHUP and EPOLLIN, then verify that available pipe input is consumed after EPOLLHUP and that the reproducer no longer fails.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100