-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Blocking IO makes it impossible to join threads reliably #26446
Comments
There are three possible solutions here: timeout, close the TCP listener, or select/epoll on a control channel. Eventually, we probably want all three but the simplest one to implement is closing the TCP listener (you can actually do this now with a bit of unsafe code (just manually close the file descriptor)). Another solution is to send an interrupt signal to the listener thread but I don't know how rust wants to handle interrupts. Regardless, this issue goes on in the RFC repo. |
@Stebalien Not sure if this is the place to detail such things, but could you explain how polling a "control" channel might fix this? Wouldn't we be in the same place regarding the fact that the IO is blocking and we can't rely on it to check a channel? In my opinion (read: "I might be wrong, but"), the only safe, semantic design I can picture is all blocking |
As of 1.1, you can get the raw file descriptor for a TcpListener. This means that, on Linux at least, you can use the epoll/select system calls to block on both a control file descriptor (some other file descriptor such as an eventfd) and the TcpListener's fd. You could then write to the control file descriptor causing the select/epoll call to return. Obviously, this requires a fair bit of low-level code so it would be nice if the standard library provided some abstractions here.
That's what interrupts are for. If you send a SIGINT to the blocking thread, the read should stop blocking and should return an |
As @Stebalien mentions, there isn't currently a way to do this in the standard library and it's also unclear how it would be done in a "standard fashion" if at all. Unfortunately the underlying system does not give the ability to return from a blocking As a result I'm going to close this issue for now, but I would certainly recommend checking out mio and/or opening an RFC issue on this topic, although it may fall under the "async I/O story" more than wanting its own issue. |
fn main(){ how can extract fd from the listener??? |
@anil1596 You can use the |
@Stebalien that worked with implementation of AsRawFd trait. |
@anil1596 What precisely are you trying to do? |
@Stebalien I am implementing I/O notification facility based on epoll in rust. |
@anil1596 got it. Yes, you want AsRawFd. |
Threads spawned to interface blocking IO with a non-blocking channel can't be cleaned up in a programmatic way.
Example:
To my knowledge, the only way to communicate to
listener_thread
that it should break is by dropping the receiving end of the channel:The problem is, if
listener_thread
is blocking waiting for a client, it may never reachaccept_tx.send(..)
, let alone reach it in a computationally timely manner.You can make dummy connections for
TcpListener
s, and shutdownTcpStream
s via a clone, but these are really hacky ways to clean up such threads, and as it stands, I don't even know of a hack to trigger a thread blocking on a read fromstdin
to join.Meta
rustc --version --verbose
:rustc 1.0.0 (a59de37 2015-05-13) (built 2015-05-14)
binary: rustc
commit-hash: a59de37
commit-date: 2015-05-13
build-date: 2015-05-14
host: x86_64-unknown-linux-gnu
release: 1.0.0
The text was updated successfully, but these errors were encountered: