forked from bytecodealliance/wasmtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Immediately return StreamError::Closed when the TCP stream is closed. (…
…bytecodealliance#8968) This saves the caller from having to perform one last `poll`+`read` sequence. Before this change, it would first return an empty list of bytes, which is the wasi-io equivalent of EWOULDBLOCK.
- Loading branch information
Showing
4 changed files
with
57 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use std::time::Duration; | ||
|
||
use test_programs::wasi::io::streams::StreamError; | ||
use test_programs::wasi::sockets::network::{IpAddress, IpAddressFamily, IpSocketAddress, Network}; | ||
use test_programs::wasi::sockets::tcp::{ShutdownType, TcpSocket}; | ||
|
||
/// InputStream::read should return `StreamError::Closed` after the connection has been shut down by the server. | ||
fn test_tcp_read_from_closed_input_stream(net: &Network, family: IpAddressFamily) { | ||
// Set up server & client sockets: | ||
let bind_address = IpSocketAddress::new(IpAddress::new_loopback(family), 0); | ||
let listener = TcpSocket::new(family).unwrap(); | ||
listener.blocking_bind(&net, bind_address).unwrap(); | ||
listener.blocking_listen().unwrap(); | ||
let bound_address = listener.local_address().unwrap(); | ||
let client = TcpSocket::new(family).unwrap(); | ||
let (connected_input, connected_output) = client.blocking_connect(net, bound_address).unwrap(); | ||
let (accepted, accepted_input, accepted_output) = listener.blocking_accept().unwrap(); | ||
|
||
// Shut down the connection from the server side and give the kernel a bit | ||
// of time to propagate the shutdown signal from the server socket to the | ||
// client socket. | ||
accepted.shutdown(ShutdownType::Both).unwrap(); | ||
drop(accepted_input); | ||
drop(accepted_output); | ||
drop(accepted); | ||
std::thread::sleep(Duration::from_millis(50)); | ||
|
||
// And now the actual test: | ||
|
||
// The input stream should immediately signal StreamError::Closed. | ||
// Notably, it should _not_ return an empty list (the wasi-io equivalent of EWOULDBLOCK) | ||
// See: https://github.com/bytecodealliance/wasmtime/pull/8968 | ||
assert!(matches!(connected_input.read(10), Err(StreamError::Closed))); // If this randomly fails, try tweaking the timeout above. | ||
|
||
// Stream should still be closed, even when requesting 0 bytes: | ||
assert!(matches!(connected_input.read(0), Err(StreamError::Closed))); | ||
|
||
drop(connected_input); | ||
drop(connected_output); | ||
drop(client); | ||
} | ||
|
||
fn main() { | ||
let net = Network::default(); | ||
|
||
test_tcp_read_from_closed_input_stream(&net, IpAddressFamily::Ipv4); | ||
test_tcp_read_from_closed_input_stream(&net, IpAddressFamily::Ipv6); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters