Implement sock_accept

With the addition of `sock_accept()` in `wasi-0.11.0`, wasmtime can now
implement basic networking for pre-opened sockets.

For Windows `AsHandle` was replaced with `AsRawHandleOrSocket` to cope
with the duality of Handles and Sockets.

For Unix a `wasi_cap_std_sync::net::Socket` enum was created to handle
the {Tcp,Unix}{Listener,Stream} more efficiently in
`WasiCtxBuilder::preopened_socket()`.

The addition of that many `WasiFile` implementors was mainly necessary,
because of the difference in the `num_ready_bytes()` function.

A known issue is Windows now busy polling on sockets, because except
for `stdin`, nothing is querying the status of windows handles/sockets.

Another know issue on Windows, is that there is no crate providing
support for `fcntl(fd, F_GETFL, 0)` on a socket.

Signed-off-by: Harald Hoyer <harald@profian.com>
This commit is contained in:
Harald Hoyer
2022-01-21 14:42:43 +01:00
committed by Dan Gohman
parent 8ba3294881
commit 853a025613
18 changed files with 650 additions and 30 deletions

View File

@@ -1,6 +1,5 @@
use crate::block_on_dummy_executor;
use io_lifetimes::AsHandle;
use std::os::windows::io::{AsRawHandle, RawHandle};
use io_extras::os::windows::{AsRawHandleOrSocket, RawHandleOrSocket};
use wasi_cap_std_sync::sched::windows::poll_oneoff_;
use wasi_common::{file::WasiFile, sched::Poll, Error};
@@ -16,35 +15,43 @@ pub fn wasi_file_is_stdin(f: &dyn WasiFile) -> bool {
f.as_any().is::<crate::stdio::Stdin>()
}
fn wasi_file_raw_handle(f: &dyn WasiFile) -> Option<RawHandle> {
fn wasi_file_raw_handle(f: &dyn WasiFile) -> Option<RawHandleOrSocket> {
let a = f.as_any();
if a.is::<crate::file::File>() {
Some(
a.downcast_ref::<crate::file::File>()
.unwrap()
.as_handle()
.as_raw_handle(),
.as_raw_handle_or_socket(),
)
} else if a.is::<crate::net::TcpListener>() {
Some(
a.downcast_ref::<crate::net::TcpListener>()
.unwrap()
.as_raw_handle_or_socket(),
)
} else if a.is::<crate::net::TcpStream>() {
Some(
a.downcast_ref::<crate::net::TcpStream>()
.unwrap()
.as_raw_handle_or_socket(),
)
} else if a.is::<crate::stdio::Stdin>() {
Some(
a.downcast_ref::<crate::stdio::Stdin>()
.unwrap()
.as_handle()
.as_raw_handle(),
.as_raw_handle_or_socket(),
)
} else if a.is::<crate::stdio::Stdout>() {
Some(
a.downcast_ref::<crate::stdio::Stdout>()
.unwrap()
.as_handle()
.as_raw_handle(),
.as_raw_handle_or_socket(),
)
} else if a.is::<crate::stdio::Stderr>() {
Some(
a.downcast_ref::<crate::stdio::Stderr>()
.unwrap()
.as_handle()
.as_raw_handle(),
.as_raw_handle_or_socket(),
)
} else {
None