You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
RalfJung opened this issue
Apr 4, 2024
· 3 comments
Labels
A-filesArea: related to files, paths, sockets, file descriptors, or handlesA-shimsArea: This affects the external function shimsA-unixArea: affects our shared Unix target supportC-projectCategory: a larger project is being tracked here, usually with checkmarks for individual steps
The main issue with implementing blocking sockets is that they would provide the first source of blocking in Miri that is controlled by the outside world (except for time but we've got that handled pretty well). That will be quite non-trivial to implement as Miri needs to basically become or import an async runtime. We'll have a concept of threads being blocked on a socket. When all threads are blocked and Miri goes to sleep to wait for a timeout to pass, it needs to be able to wait on "either the timeout passes or all the sockets any thread is blocked on". When the socket unblocks we should wake up the thread, even if we never reach the "all threads are blocked" state. Both of these are exactly the core operations of an async runtime.
Somewhat surprisingly, I do not think that epoll makes this a lot more complicated. Even without epoll, we could have 5 threads waiting on a different socket each, so Miri basically needs epoll on the host even if Miri programs do not have epoll available. Having epoll just means that a single Miri thread can wait on more than one socket, but since Miri anyway has to support many threads that doesn't add significant new complications.
Non-blocking sockets would be a lot simpler, but probably also a lot less interesting.
The text was updated successfully, but these errors were encountered:
RalfJung
added
C-project
Category: a larger project is being tracked here, usually with checkmarks for individual steps
A-shims
Area: This affects the external function shims
labels
Apr 4, 2024
RalfJung
added
A-files
Area: related to files, paths, sockets, file descriptors, or handles
A-unix
Area: affects our shared Unix target support
labels
May 5, 2024
As discussed on Zulip, it would probably make sense to use mio on the Miri side here. Fundamentally, the primitives we need are:
each time the active thread yields, do a non-blocking poll on a set of host sockets -- that's generalizing what we already do here where we check whether there's a timer we need to fire
if all Miri threads are blocked, do a blocking poll on a set of host sockets (potentially with a timeout) -- that's generalizing what we do here and here where we just sleep until the next timeout expires
The hope is that mio would give us both of these in a platform-independent way, so that we can run on Windows hosts. (Note that this issue is only about Unix targets, using the typical POSIX socket API. Support for sockets on Windows targets is out-of-scope here. But if possible we should support running Unix targets on Windows hosts, as we already do with file system access.)
There's also a dumb way to do this: just spawn a physical host thread whenever we want to do a blocking op and poll that thread every now and then to see if it finished.
Just so you know that someone would use socket support when it gets put in.
error: unsupported operation: can't call foreign function `socket` on OS `linux`
--> /home/jil/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/pal/unix/net.rs:88:34
|
88 | let fd = cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0))?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function `socket` on OS `linux`
|
= help: if this is a basic API commonly used on this target, please report an issue with Miri
= help: however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases
= note: BACKTRACE:
= note: inside `std::sys::pal::unix::net::Socket::new_raw` at /home/jil/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/pal/unix/net.rs:88:34: 88:79
= note: inside `std::os::unix::net::UnixListener::bind::<&std::path::PathBuf>` at /home/jil/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/os/unix/net/listener.rs:74:25: 74:74
A-filesArea: related to files, paths, sockets, file descriptors, or handlesA-shimsArea: This affects the external function shimsA-unixArea: affects our shared Unix target supportC-projectCategory: a larger project is being tracked here, usually with checkmarks for individual steps
Miri can access files but not sockets currently.
The main issue with implementing blocking sockets is that they would provide the first source of blocking in Miri that is controlled by the outside world (except for time but we've got that handled pretty well). That will be quite non-trivial to implement as Miri needs to basically become or import an async runtime. We'll have a concept of threads being blocked on a socket. When all threads are blocked and Miri goes to sleep to wait for a timeout to pass, it needs to be able to wait on "either the timeout passes or all the sockets any thread is blocked on". When the socket unblocks we should wake up the thread, even if we never reach the "all threads are blocked" state. Both of these are exactly the core operations of an async runtime.
Somewhat surprisingly, I do not think that epoll makes this a lot more complicated. Even without epoll, we could have 5 threads waiting on a different socket each, so Miri basically needs epoll on the host even if Miri programs do not have epoll available. Having epoll just means that a single Miri thread can wait on more than one socket, but since Miri anyway has to support many threads that doesn't add significant new complications.
Non-blocking sockets would be a lot simpler, but probably also a lot less interesting.
The text was updated successfully, but these errors were encountered: