with recent spec changes, 0-length stream writes are used to await "readiness" and, from what I understand, the expectation is that a non-zero-length write following a 0-length write is non-blocking. This works great for e.g. TCP sockets that have a well-defined and clear way of querying the readiness, however, how is this feature expected to be implemented for files and/or stdio?
It appears that the only way to provide this functionality in the host would be buffering the data in the host and have a dedicated worker thread/task performing I/O
With this approach stream.write returning would not guarantee that the data has reached the kernel. In case of stdio, for example, that would mean that println("hello, world") returning does not guarantee that "hello, world" has even attempted to be written to the terminal.
wasi:filesystem defines sync, which seems to be the place where we could hook in to await the "flush" of file worker's buffer, but we would need to introduce a similar construct to wasi:cli.
Personally, I have been under impression that we wanted to avoid buffering in the host - and if so, how would we implement the expected behavior for 0-length writes?
cc @Alex Crichton @Joel Dice
related:
cc @Luke Wagner @Dave Bakker (badeend), who came up with the zero-length read/write semantics, I believe.
Does AsyncWrite::poll_write(..., &[]) not await readiness for files or stdout?
it appears that at least for files it actually might https://github.com/tokio-rs/tokio/blob/925c614c89d0a26777a334612e2ed6ad0e7935c3/tokio/src/fs/file.rs#L721-L791
It appears to buffer by default, but maybe that is complete ready enough from a guest's perspective?
I've just had a quick chat with @Luke Wagner about it and it appears that only 0-length reads are expected to have these semantics, 0-length writes to files/stdio are free to return immediately
I think the empty poll_write is certainly "good enough"
Last updated: Dec 06 2025 at 06:05 UTC