Skip to content

Multi‐threading Notes

Ihor Dutchak edited this page Jun 28, 2025 · 3 revisions

General statement

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.

Initialisation / enumeration

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.

Multiple devices

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.

hid_read

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.

Before v0.15.0 many projects where successfully using one thread for hid_read and another thread for all other device functions. See previous description for potential problems with this on older versions of HIDAPI.

Since v0.15.0 such scenario/usage is perfectly safe for as long as only hid_read/hid_read_timeout and hid_read_error are the only functions to be used from a dedicated thread. hid_error is no longer affected by hid_read and should not be used concurently to other device functions. hid_read_error on the other hand is specifically designed to be used in the same thread as hid_read.

Clone this wiki locally