-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Minimal viable implementation of poll_oneoff for Windows #552
Conversation
@kubkon @peterhuene Please wait a while with reviewing this change until I add some notes and state some ideas/concerns, so that we can meaningfully discuss it. I probably wasn't clear enough about that. |
Sorry, just saw your comment now! I'll hold off on additional review feedback. |
@kubkon @peterhuene please share your feedback guys! Thanks! |
@marmistrz sorry this completely slipped off my radar with the holiday last week. I'll review and provide feedback shortly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marmistrz this looks great, thanks for implementing this rather tricky API! I have some questions regarding the approach that I think we should address.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All in all, this looks good to me especially since this is our first pass at implementing poll_oneoff
on Windows.
While here, not sure how relevant it is now, but it seems that stdin
is always buffered by Rust. See here for more details on the subject. This PR does mention that we should be able to use stdin_raw
to access the raw, unbuffered stdin handle, but this method is kept private in libstd
. @alexcrichton would you perhaps be able to chip in here?
Also, FWIW, it might be worth pointing out that the busy loop might disappear soon-ish when we start considering rewriting the syscalls in an async fashion. Although, I'm not sure we will ever want to support only the async version especially if determinism is a requirement for the client code.
38593bd
to
423ec09
Compare
This is ready for another round of reviews. The |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! I just have one nit-picky name question and a more important clarification question. Once answered, I think this is good to go.
I made sure that we don't wait on events if there are any available immediately ( |
I rebased and got rid of the loop. Now we're just calling It seems the tests are failing because of the snapshot stuff. Should I try to somehow port these changes into the snapshot, or what's the preferred way of coping with that? |
This comment has been minimized.
This comment has been minimized.
I have just pushed a new minimal viable implementation of
I'm blocked by #760 for now. I need to either have the top-level error type implement With the current test configuration it's impossible to test the real stdin implementation on CI, because in
|
Concerning the empty poll case, we've now merged WebAssembly/WASI#193 in the WASI spec, so while that isn't in a snapshot yet, it means we don't need to worry much about this case here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good!
While I'm not thrilled to have to use a thread to implement this on Windows, you've called out the limitations quite clearly and I think we can live with them.
Just one more requested change regarding the EINVAL
return and then 👍.
Co-Authored-By: Peter Huene <peterhuene@protonmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Huge thanks for sticking through this difficult PR!
Is there anything that prevents this PR from being merged? It's ready as far as I'm concerned. |
I agree it is ready. Merging now. Thanks again! |
Again, I dislike the implementation, but it's the best what we can do without touching the implementation of other syscalls and a starting point for the discussion.
I'll be adding more comments and explanations in the coming days. I'll add a follow-up reply when I'm done with it.
The main blocker that forces us to busy-wait on stdin getting ready for input is the fact that the current implementation of
fd_read
(and similarlyfd_write
, but this is not significant) usesBufRead
to read from stdin, which does internal buffering. The details have been described in a comment and will be omitted from this summary.Still,
libstd
doing buffering on our behalf may be superfluous if not wasteful. Note that ourfd_read
is the rough counterpart ofread
from POSIX, which doesn't do any buffering and will most likely not be used directly. Most probably, the relevant standard library will do its buffering itself, be itstdio
,iostream
or Rustlibstd
, whichever is used by the wasm binary. Therefore, there should be no technical problem dropping buffering fromwasi-common
and it may even be desirable.Even more, this may be a leftover bug, judging by a closed issue: #255. The use of
BufRead
is implied by this line:wasmtime/crates/wasi-common/src/hostcalls_impl/fs.rs
Line 162 in 85cfdd0
Still, this brings another issue: if we rely on this behavior, we must not ever use
BufRead
onstdin
throughoutwasi-common
, neither can it be used in any of the dependent crates. I don't think it's easy to be checked.Possible solutions:
fd_read
(andfd_write
) not to make use ofBufRead
I tried using
WaitForSingleObject
to detect new stdin events, but this function doesn't work for me as expected. (see wait.cpp.gz for the exact code I tested).Something else happened
. On the contrary, I get absolutely no message until I actually write a line to the terminalWaitForSingleObject
return immediately withWAIT_OBJECT_0
, but clearly there's no data for getline to read. Moreover, the handle still seems valid:GetHandleInformation
succeeds even after the stdin has been closed, so I don't know if we have a valid way of detecting such situation.Please note that my tests were done over an SSH terminal from MSYS2 on Windows 10. I compiled the test program using
g++
from mingw.There are also other questions related to
WaitForSingleObject
. How will it react to "empty" key presses, i.e. those which don't produce any character, for instance arrow up/arrow down. I'd need to test it. We could possible ignore this issue, asselect
&poll
on Linux may in some cases report spurious readiness notifications.