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

Abort hid_write? #58

Open
vanweric opened this issue May 8, 2012 · 9 comments
Open

Abort hid_write? #58

vanweric opened this issue May 8, 2012 · 9 comments

Comments

@vanweric
Copy link

vanweric commented May 8, 2012

On occasion, hid_write fails to return. This happens randomly, and does not seem to be dependent on the message I am sending - I send a nearly identical packet 20k+ times in a row back to back, and it will on occasion lock up at any point in that burst. I believe the root cause to be the device misbehaving.

Can I timeout or abort one of these "stuck" writes?

This is seen on Win 7 x64 running in a 32-bit process. I have not yet tried on Mac or on other Windows versions.

@signal11
Copy link
Owner

signal11 commented May 9, 2012

Try the windows_write_timeout branch and see if this does what you want it to do.

@vanweric
Copy link
Author

I keep one read pending at all times to pick up whatever my device my send back asynchronously. It looks like the two overlapped calls are arguing with each other, I now get "Overlapped I/O operation is in progress" errors when I call hid_write.

@signal11
Copy link
Owner

Hmm... interesting. Do you think there's a way around this then? It sounds like maybe Windows doesn't want an overlapped read and write happening at the same time.

There's not a reason to keep a hid_read() blocking in a separate thread all the time for asynchronous data. Windows will buffer up any data received. I think the buffer size is 30 currently inside Windows. Jan Axelson has those numbers on her website at lvr.com.

@vanweric
Copy link
Author

I don't know, but I certainly hope there is... :-)

I'm going to try splitting the handle in two, but honestly that is just a shot in the dark on my part. I'm just an EE/RF guy pretending to be able to do software.

How do you suggest I receive asynchronous data? Would you poll with zero timeout?
I need to be able to have both read and write timeout, which I think means that both need to be overlapped. If I can only have one overlapped transaction pending at once, I'll need to lock around these calls - reads happen in one thread, writes happen in several other threads.

I don't know if it is relevant, but I am p/invoking hidapi from C#.

@signal11
Copy link
Owner

Just call hid_read() whenever you're ready to process data. If any data has come in from the device, Windows will have queued it, and it will all be there ready for you.

I think you are making this harder than it needs to be. If you can get it all onto a single thread, that would be the best, especially on Windows. You won't lose data (unless > 30 (or whatever the limit is) come in).

@vanweric
Copy link
Author

You are probably right - this is getting a bit messy. I have to accept commands (hid_write) from multiple client threads, and responses are not guaranteed to come back from the device in order. Some commands take several minutes to execute, during which other commands are allowed to execute in parallel.

The current solution is to send from within the thread that the command originates from, and receive in a separate worker/dispatcher. Are you recommending dispatching the sends through the worker, or is there a silver-bullet I'm overlooking?

@signal11
Copy link
Owner

In your situation, on Windows, I'd put a mutex around the HIDAPI object, then send hid_write() commands from wherever they're needed (under lock), and then have a single place which calls hid_read*() periodically and dispatches the responses.

@vanweric
Copy link
Author

Just to close out the issue, I implemented your last suggestion and it works well. hid_writes are mutexed, and hid_read_timeout periodically reads and dispatches.

Thank You

@signal11
Copy link
Owner

Did you ever try the code in the windows_write_timeout branch?

@signal11 signal11 reopened this Jul 18, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants