Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(c-api) Don't drain the entire captured stream at first read #2070

Merged
merged 4 commits into from
Jan 28, 2021

Conversation

Hywan
Copy link
Contributor

@Hywan Hywan commented Jan 28, 2021

Description

We use VecDeque::drain to read the captured stream, zipped with the
given buffer. We could expect that only the yielded items from the
drain will be removed, but actually no. Reading the
documentation
:

Note 1: The element range is removed even if the iterator is not
consumed until the end.

So by using a range like .. (as we do) will drain the entire captured stream,
whatever we read from it. Said differently, if the given buffer length
is smaller than the captured stream, the first read will drain the
entire captured stream.

This patch fixes the problem by specifying a better range:
..min(inner_buffer.len(), oc.buffer.len()).

With this new range, it's actually useless to increment
num_bytes_written, we already know ahead of time the amount of bytes
we are going to read. Consequently, the patch simplifies this code a
little bit more.

This patch also updates the test-wasi integration test. Previously,
stdout wasn't captured, so the loop using wasi_env_read_stdout was
doing nothing. Now we have the following output:

Initializing...
Loading binary...
Compiling module...
Setting up WASI...
Instantiating module...
Extracting export...
found 2 exports
Calling export...
Evaluating "function greet(name) { return JSON.stringify('Hello, ' + name); }; print(greet('World'));"
WASI Stdout: `"Hello, World"
`
Shutting down...
Done.

Review

  • Add a short description of the the change to the CHANGELOG.md file

…l range.

We use `VecDeque::drain` to read the captured stream, zipped with the
given buffer. We could expect that only the yielded items from the
`drain` will be removed, but actually no. Reading [the
documentation](https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.drain):

> Note 1: The element `range` is removed even if the iterator is not
> consumed until the end.

So by using a range like `..` will drain the entire captured stream,
whatever we read from it. Said differently, if the given buffer length
is smaller than the captured stream, the first read will drain the
entire captured stream.

This patch fixes the problem by specifying a better range:
`..min(inner_buffer.len(), oc.buffer.len())`.

With this new range, it's actually useless to increment
`num_bytes_written`, we already know ahead of time the amount of bytes
we are going to read. Consequently, the patch simplifies this code a
little bit more.
@Hywan Hywan added bug Something isn't working 📦 lib-c-api About wasmer-c-api labels Jan 28, 2021
@Hywan Hywan self-assigned this Jan 28, 2021
@Hywan
Copy link
Contributor Author

Hywan commented Jan 28, 2021

bors r+

@bors
Copy link
Contributor

bors bot commented Jan 28, 2021

@bors bors bot merged commit aea76b8 into wasmerio:master Jan 28, 2021
Hywan added a commit to Hywan/wasmer that referenced this pull request Jan 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working 📦 lib-c-api About wasmer-c-api
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants