Skip to content
This repository was archived by the owner on Nov 9, 2019. It is now read-only.

Make fd_write unbuffered; fixes CraneStation/wasmtime#255#55

Merged
sunfishcode merged 1 commit intoCraneStation:masterfrom
kubkon:unbuffered
Aug 7, 2019
Merged

Make fd_write unbuffered; fixes CraneStation/wasmtime#255#55
sunfishcode merged 1 commit intoCraneStation:masterfrom
kubkon:unbuffered

Conversation

@kubkon
Copy link
Copy Markdown
Member

@kubkon kubkon commented Aug 6, 2019

This PR fixes bytecodealliance/wasmtime#255 by making fd_write unbuffered. AFAIK, std::io::Read and std::io::Write all do buffered reads and writes respectively. I'm not sure whether the fact that our implementation of fd_read uses buffered reads is a problem?

@marmistrz I've not re-used your fn errno_from_ioerror as I didn't want to create additional conflicts for your PR #46.

@kubkon
Copy link
Copy Markdown
Member Author

kubkon commented Aug 6, 2019

cc @alexcrichton @sunfishcode

let nwritten = stderr.write_vectored(&iovs);
stderr
.flush()
.map_err(|err| err.raw_os_error().map_or(host::__WASI_EIO, errno_from_host))?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike io::stdout, io::stderr is not buffered, so we don't need to flush it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent point!

Descriptor::File(f) => {
let nwritten = f.write_vectored(&iovs);
f.flush()
.map_err(|err| err.raw_os_error().map_or(host::__WASI_EIO, errno_from_host))?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Rust documentation isn't clear about this, but if I read the implementation correctly, on Windows and Unix, File's write functions don't do buffering, so we shouldn't need to flush them.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, it may be a good idea to add the currently-no-op flush in case the Rust implementation decides to do some buffering. Or to clarify the docs.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sunfishcode I think you're spot on! @marmistrz I'm partial to leaving flushing out of this one, and clarifying Rust's docs instead. Then, if anything changes we should in principle be able to track it down through the changes in the docs. :-)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, if Rust ever does decide to make File's write etc. buffered, it'd be better to switch to a lower-level API without buffering, rather than use buffering and flushing.

It's unfortunate that we have to deal with stdout buffering, but it is useful to coordinate with io::stdout so that we interop with Rust code in the host.

let nwritten = stdout.write_vectored(&iovs);
stdout
.flush()
.map_err(|err| err.raw_os_error().map_or(host::__WASI_EIO, errno_from_host))?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really subtle, but the ordering here means that errors from the flush call are reported before errors from the write_vectored call. I admittedly can't think of a case where it would matter offhand, but it feels untidy to check errors out of order.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, of course! Well spotted, thanks!

@marmistrz
Copy link
Copy Markdown
Member

@kubkon you can rebase onto #46 if you feel like, or I can also refactor your change later on.

@kubkon
Copy link
Copy Markdown
Member Author

kubkon commented Aug 7, 2019

@kubkon you can rebase onto #46 if you feel like, or I can also refactor your change later on.

I was thinking of not rebasing onto #46 as this PR is a hotfix rather than a major change, and then we could apply your refactoring #46 when we sync with master?

@marmistrz
Copy link
Copy Markdown
Member

@kubkon ok

@sunfishcode
Copy link
Copy Markdown
Member

Looks good!

@sunfishcode sunfishcode merged commit 8ea7a98 into CraneStation:master Aug 7, 2019
@kubkon kubkon deleted the unbuffered branch August 7, 2019 12:06
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fd_write should be unbuffered

3 participants