-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
sys.stdio: add support for ioctl and make sys.stdin.buffer.read non-blocking #4859
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
Conversation
On what this is based? It's hard to believe that CPython has non-blocking sys.stdin.buffer. Not only it doesn't, in my quick testing (n 3.6.7), it doesn't even issue short reads, i.e. running sys.stdin.buffer.read(4) and typing just |
See my comment #4849 (comment) sys.stdin reading on bare-metal is already different to CPython. Non-blocking behaviour is arguably more useful than blocking, and since sys.stdin.buffer is most likely going to be used for raw reads I changed this here to non-blocking, but not sys.stdin. |
If a method exists to check, whether sys.stdin.read() would be successful, the non-blocking read may not be needed. That method is given now with select. That's good. |
As someone who likes to do adjustments, simplifications, and extensions to CPython I/O model, as well as the original designer of MicroPython's streams subsystem, I don't see how "non-blocking behaviour is arguably more useful than blocking". Blocking behavior is definitely more useful than non-blocking, because non-blocking mode for any non-toy usage requires I/O scheduling (aka answering question "what to do if there's EAGAIN condition"). That's why CPython has it blocking, following the same default for POSIX. It however should be possible to enable non-blocking mode for any stream which can support it. There's stream.setblocking() method for this. MicroPython streams also cater for "no short reads/writes" behavior, but if for some type of stream (e.g. UART streams) short reads would make sense, there're provisions for such (there're just no current usages in the codebase). Beyond that, there're a number of issues and unfinished things in MicroPython stream subsystem:
Again, perhaps some levels above might be superfluous for small baremetal ports, but doing things like "sys.stdin is blocking, while "sys.stdin.buffer is non-blocking", ignoring theie meaning and interaction of the things as described above - that's complete adhoc mess, just for the purpose of doing something #4849. And noticeable further deterioration of design quality, already started by #4020, where, instead of starting with generic improvements to stream interface (with a whole bunch having been proposed), just adhoc I2C-specific changes were made. As for #4849, it's rather separate issue. It's a bit too optimistic to assume in the first place that one case use the same stream for REPL, and change its settings arbitrarily at the same time. I see that issue very similar to Unix port one, where adding something to dupterm breaks REPL. It would be very similar in Unix to setting terminal to e.g. raw mode behind bash's back - there should be no surprise that it stops to work as expected. Fixing that issue would require to implement the I/O stream hierarchy above, and more than that, and of course per good tradition would start with Unix port. |
64a2563
to
41d1830
Compare
I agree that making But making |
A port must provide the following function for this to work: uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags);
Fix pulsein pause and resume functions to handle HCSR04
This PR allows to poll sys.stdin for readability, and also makes sys.stdin.buffer.read non-blocking (but keeps sys.stdin.read blocking as it was before). A port must provide
mp_hal_stdin_rx_avail()
for this to work (this function is only implemented on esp8266 for now).Testing of polling can be done with:
Testing of non-blocking read can be done with (enter chars while it's sleeping):
See issue #4849 for background.