-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Asynchronous callbacks for reading and writing on Windows, attempt 2. #1328
Conversation
Instead of ReadFile and WriteFile, which block and transfer data synchronously, use ReadFileEx and WriteFileEx, which both allow async callbacks. In addition, change how timeouts are used for ReadFile*, using an unlimited timeout for the first byte, and no timeout for the rest of the data in the input buffer. This removes the need to poll entirely, while still retrieving all data available in the input buffer. In both cases, the I/O operations happen in their own threads, since Windows requires IOCompletion callbacks to wait for their calling thread to be in an "alertable wait state". Fixes serialport#1221
Verified this builds in 32-bit mode using: Ran tests using Looks like the 3 pending tests are features that are disabled on Windows? |
👋 is this ready for me to test on my Windows box? |
running
|
@noopkat is that error consistent? |
@dustmop I pushed your commit to appveryor https://ci.appveyor.com/project/j5js/node-serialport/build/1.0.1581 |
@reconbot it is consistent. I tried board resetting, repeated testing, and ran tests in both git-bash and powershell with the same results each time. |
On my machine:
1582ms is pretty close-ish to 2000ms? Is there a way to try with an increased timeout? |
yeah, |
this machine is a good example of a 🐢 to test with, if that provides context around this at all |
I'm ok with adjusting the timeouts, we don't have any speed specific tests. However that test does seem really slow, all it's doing is opening the port and waiting for the first byte. Arduino's usually boot in around 300ms.
However it IS slow everywhere so no worries. Eg on OSX.
Appveyor passes! |
@noopkat if the extended timeout works for you let us know! you can use ( |
|
Small correction: this test (doesn't throw if the port is open) reads multiple bytes, equal to readyData.length. It's the test below (returns at maximum the requested number of bytes) that only reads a single byte. However, I agree it still seems to be on the slow side. I want to make sure this isn't a regression. Was an increased timeout needed before this change? Also, is there a benchmark, or at least something that validates that cpu usage goes down? It seems good on my machine but would be nice to verify. |
weirdly trying from a master build will yield
verified the port:
I do have to 😴 right now my apologies - early day in the city tomorrow. Will bring a board with me and can continue to debug if needed. |
You didn't need the extended timeout so I Don't think it's a regression. @noopkat could try master and report timings. We don't have a perf test for large reads and writes, I've been using the repl |
@noopkat you can't unlock the port on windows, that's weird it would run that test. |
so this dummy here did not pull the latest master before building (it is late) 🤦♀️ I get the exact same |
Ok! Thank you very much for helping, go get some rest! 👍 |
Thank you @noopkat! We're going to get finished builds from travis in anywhere between 0 and 6 hours. Their OSX backlock is quite long tonight. I'm ok to merge with everything that's passing passing. We can bump the timeout in your pr (if you use an additional commit it will not cause the existing build jobs to fail) or master and cut a new beta release. |
That is to say if you're ok with this landing, I'm ok with this landing. |
Sure! Maybe wait until tomorrow, just in case? |
Looks like this should be good to go |
🎉 |
Hi all. I had a chance to try it out on our real-life application (Electron, Windows, x86 build). |
OK, this is what happens:
|
Error code 87 is Windows' very unhelpful "ERROR_INVALID_PARAMETER", which doesn't say much. Could be the file handle is being invalidated, or the buffer is, somehow. Hard to figure out without a minimal repro case. This is 32-bit or 64-bit? I haven't done any testing in electron, and won't be able to until I'm back home from travel (September 20th). |
I would bet this doesn't have anything to do with electron in particular. @vshymanskyy if you could try to reproduce this in node and open a new issue I can start debugging before @dustmop gets back. The new issue template has a section where you can talk about the hardware you're talking to. On windows the manufacture of the chipset of the USB serial device is very good to know. (FTDI etc) |
Works fine with the latest version. Thank you! |
Instead of ReadFile and WriteFile, which block and transfer data synchronously, use ReadFileEx and WriteFileEx, which both allow async callbacks. In addition, change how timeouts are used for ReadFile*, using an unlimited timeout for the first byte, and no timeout for the rest of the data in the input buffer. This removes the need to poll entirely, while still retrieving all data available in the input buffer. In both cases, the I/O operations happen in their own threads, since Windows requires IOCompletion callbacks to wait for their calling thread to be in an "alertable wait state".
Fixes #1221