Different behavior of nonblocking hid_read on different OSs? #33
Labels
No labels
3rdparty
Android
API
Author does not respond
bsd
bug
build system/CI
ci-virtual-device
CMake
Contributions Welcome
Core
dependencies
device-specific
documentation
don't_merge
duplicate
enhancement
Example
Haiku
hidraw
hotplug
info required
invalid
libusb
macOS
Misc
Not an issue
question
Release
Test
Test GUI
Windows
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-libusb/hidapi#33
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The Linux libusb and macOS backends maintain an internal buffer of 30 (where did this number come from?) input reports. If I understand correctly, when hid_read is called repeatedly, one input report is returned at a time in the order they were received. If that is correct, then I think the correct way to use nonblocking calls to hid_read on a polling timer would be to loop until hid_read returns <= 0. However, the Windows implementation does not seem to maintain such an internal buffer, so I'm not sure how many times to call hid_read on each polling iteration. I have searched for examples of how to use hid_read in the nonblocking mode but have not found any useful information about this.
For background context, in Mixxx, our current use of HIDAPI has separate threads for reading and writing with the reading thread using hid_read_timeout with a 500ms timeout. However, a Windows user found that when writing data frequently, Mixxx would stop reading incoming data. We presume this is because of the read and write thread trying to access the device concurrently, so we are trying to move both reading and writing into the same thread and use polling, nonblocking reading. I'm not entirely certain that was the issue, so switching to using polling might be moot.
https://github.com/mixxxdj/mixxx/pull/2179
https://mixxx.zulipchat.com/#narrow/stream/113295-controller-mapping/topic/Is.20shutdown.20called.20when.20reloading.20script.3F
I believe that's the only way HIDAPI gives you to use it in a separate thread
and yes, Windows implementation is a bit different, than others, and doesn't seems to be thread safe
check this discussion: https://github.com/signal11/hidapi/issues/45
I'm not sure the scenarios described in that old discussion are the same as what we have. We have reading in one thread and writing in another. If that's not safe, what should we do? Guard each read and write with a mutex? Or move them to one thread and run that thread on a polling timer with nonblocking reads? If we use nonblocking reads, how many calls to hid_read do we need to do on each poll?
there shouldn't be such thing as "how many" - normally you poll intinitelly, until
hid_read_timeoutreturn value <0 (an error), or you stop your polling externallyI never needed/tried using both
hid_readandhid_writein separate threads, so I wouldn't have a solution for youwhat I'd suggest, is you to try to debug
hid.con Windows and see is there an issue that can be fixed (a synchronization, or smth) and develop/submit patchPR(s) are welcome
But between each iteration of the poll there will likely be many incoming packets. hid_read only returns one packet at a time. If we don't process all the intermediate packets between each poll, we could miss a button press for example. Also if we only called hid_read once each poll, IIUC that would break devices that use multiple different input packets.
do you have delays between pooling?
About thread safety on Linux and macOS
https://github.com/signal11/hidapi/issues/45
https://github.com/signal11/hidapi/issues/95