IOHIDDeviceSetReport causes frequent hangs on macOS #385
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#385
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?
Since IOHIDDeviceSetReport apparently blocks until the report has made it through, it seems that when you have for example a couple HID devices connected via bluetooth and the system can't keep up with the traffic, hid_write stops at IOHIDDeviceSetReport causing the application to hang (and the HID device whose report got stalled to become unresponsive until disconnected/reconnected).
Googling around seems to indicate that the asynchronous sibling (?) IOHIDDeviceSetReportWithCallback was for some reason never implemented by Apple, so I fear there is not much to be done...
on the other hand, I suppose if one could only move IOHIDDeviceSetReport to a different thread, then the main thread could be kept from becoming unresponsive, which while not ideal would be at least a big improvement.
I have been attempting various solutions to this problem, but my experience with threading is close to zero, so any advice would be greatly appreciated. (I am running macOS 12, by the way)
This sounds like an OS bug.
If you need to do such a thing - you can always call
hid_writefrom a different thread.Can you confirm that you're not causing a race condition? HIDAPI is not thread-safe. You generally shouldn't attempt to call
hid_*functions from different threads.Thank you for the fast response!
It does, doesn't it...
I hate to think that this is a scenario where IOKit development has been abandoned and any eventual bugs are simply never going to get addressed, but it does look just like that... oh well.
I see. Thanks for the confirmation! I'll look into that (as I currently have no idea how to do it).
I initially assumed that setting non-blocking with hid_set_nonblocking would mean hid_write was also non-blocking, but I suppose there must be reasons that is not the case.
While I cannot 100% confirm it, I don't think that's the case, since I'm not doing anything outside the main thread (that is, other than setting hid_set_nonblocking).
Unless it's possible that hid_read operating from its own thread and hid_write from the main thread are causing a race condition. Is that possible?
I see. In that case, is the whole calling hid_write from a different thread to avoid stalls not a very good idea to begin with...? (I would very much like to find a better solution, in any case)
On macOS that is totally safe.
The idea is to have a separate working thread for all
hid_*calls.Whew! Good to know.
Does that include hid_write? As far as I can tell, hid_write is currently on the main thread, unless I am missing something...
My suggestion is to have two separate working threads (in addition to main thread): one for hid_read, and one for all other calls.
Makes sense. Thanks for the advice! I'll see what I can get working and report back if I make any useful findings.
Any findings?
Nothing exciting, unfortunately—I did manage to move hid_write to its own separate thread, but that only gave exactly the expected, obvious result (app doesn't hang entirely, only the hid_write thread, which is a marginal improvement; but HID device still becomes unresponsive until reconnection).
I am, in any case, running the latest version of macOS against the common sense of waiting for stability before updating, so I suppose I might as well keep installing new updates as they come for a while and hope the IOHIDDeviceSetReport hang gets fixed at some point. I do not have my hopes up, though, since IOKit is relatively old and Apple seems to have all but moved on entirely to DriverKit. (maybe there's a way to write HID reports without hanging somewhere within DriverKit? I haven't looked at it yet, but if I eventually get the time to and happen to find a way, I'll be sure to post back)
On a kind of unrelated note, at some point within the year I'm thinking of finally biting the bullet and signing up for the (paid) Apple Developer Program, which apparently gives you the chance to post a couple Technical Support Incidents (some sort of official support ticket for Apple APIs?) each year. Since this is the single most unsolvable issue I've run into using Apple APIs so far, it seems like the obvious choice to spend a TSI on.
I'm sorry that I can't give any guarantees, but again, if I do happen to find something useful, I'll be sure to post back here.