-
Notifications
You must be signed in to change notification settings - Fork 408
Multi‐threading Notes
HIDAPI
v0.x.x is not thread-safe.
There are a few specific cases that softens the above statement and this document describes those from the most strict to least strict.
Some of the HIDAPI functions may be used from different threads and the below describes in which cases.
hid_init
/hid_exit
/hid_enumerate
/hid_open
/hid_open_path
/hid_close
/hid_error(NULL)
shall not be called concurently from different threads. Yes, in general case, it is not even safe to open different devices in different threads concurently.
One of the reasons is that in case of any of those function fails - a global error string will be updated (which can be accessed with hid_error(NULL)
).
NOTE: if hid_init
is never called explicitly, it is called implicitly by each of hid_enumerate
/hid_open
/hid_open_path
.
macOS: on macOS there is even stricter requirement: hid_init
and hid_exit
has to be called from the same thread. See #666 for discussion.
And the thread where hid_init
has been called should not be exited until all HIDAPI devices are closed and hid_exit
is called.
All functions that accept hid_device
as a first argument are to be referenced as a "device functions".
All device functions are thread-unsafe, but may be used from different threads on different devices. I.e. same HIDAPI device cannot be accessed concurently with any of the device function, but different devices can be accessed from different threads (i.e. a dedicated thread per-device).
hid_close
is the exception here - it should be serialized with initialisation/enumeration functions described in the previous section.
Even though it is perfectly safe to have a separate thread to handle a specific hid_device
it is often desirable to have a another dedicated thread to handle hid_read
/hid_read_timeout
specifically.
NOTE: it is almost impossible to use hid_read
in real-world scenarios and handle some of the errors/corner cases correctly, until #146 is implemented (see #133), but for simplicity in this document hid_read
would most likey imply the usage of hid_read_timeout
instead.
Many projects successfully using one thread for hid_read
and another thread for all other device functions. That is the only way of using HIDAPI device in such manner, and it works fine most of the time.
The problem starts for backends that implement hid_error
. In case of an error, the internal error string buffer (which later used by hid_error
) can be concurently accessed from different threads causing undefined behavior. An attemt was made to reference this issue, but not yet accepted as a solution.
So as of this moment (v0.14.0), it is strictly safe to have a separate thread for hid_read
only when using libusb backend of HIDAPI as it is the only backend that doesn't have hid_error
implemented.