问题
Environment
- Linux x64
- Ubuntu 16.4
- C++
Use-case
- Async IO ( epoll )
- A socket is used for both reading and writing
- Read & Write operations and not in sync and are iteratively done on the socket
Sample flow
- Setup socket (EPOLL_CTL_ADD)
- Start read (EPOLL_CTL_MOD + EPOLLIN | EPOLLONESHOT)
- While waiting for data to be read
- [a] Write some data (EPOLL_CTL_MOD + EPOLLOUT | EPOLLONESHOT)
Problem description
- At #2 above a EPOLLIN read operation is registered
- At #3.a, a EPOLLOUT write completion is registered before any data was read from the socket
- Given the above, will the write completion operation @3.a cancel the pending read operation?
- In other words, given the FD was initially called with (EPOLL_CTL_MOD + EPOLLOUT) that has no EPOLLIN set, will calling EPOLL_CTL_MOD + EPOLLOUT erase the previously registered EPOLLIN given data is not yet ready to be read ??
A possible workaround for the above
- is to locally manage the req IO state by routing all read/write operations through the epoll_wait thread, hence, rather than calling EPOLL_CTL_MOD from an arbitrary thread, making sure it'll always be called from the same thread doing the epoll_wait where the FD IO state (EPOLLOUT/EPOLLIN) can be safely maintained.
- the problem w this workaround is that it req synchronizing all IO initiation through the epoll_wait thread, and that, result in an additional context switch that might adversely affect performance...
That`s what I am trying to figure out:
Is there any way to sync the Read/Write IO operations on a common FD w/o the need of syncing through the epoll_wait thread? is there any way of directly calling EPOLL_CTL_MOD w/o resetting the previous state? is there any thread safe way of adding EPOLLOUT on an FD that already has EPOLLIN set ?
回答1:
SOoo..., as @Hasturkun has suggested, using dup
to filter EPOLLIN & EPOLLOUT events (in a thread safe manner) did the trick, however, to me, this looks more of a hack / workaround... I find it awkward that there is no more elegant solution... windows IOCompletion ports seems way more elegant to me...
来源:https://stackoverflow.com/questions/59517961/how-should-i-use-epoll-to-read-and-write-from-the-same-fd