Skip to content

Commit e43174a

Browse files
CopilotYouw
andcommitted
Fix double-enumeration: restore devs init before threads, use it for ENUMERATE
Agent-Logs-Url: https://github.com/libusb/hidapi/sessions/687b4058-4c04-4d5f-8de6-2f38035fd760 Co-authored-by: Youw <5939659+Youw@users.noreply.github.com>
1 parent 3f4721e commit e43174a

File tree

1 file changed

+5
-7
lines changed

1 file changed

+5
-7
lines changed

libusb/hid.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ static struct hid_hotplug_context {
173173
struct hid_hotplug_callback *hotplug_cbs;
174174

175175
/* Linked list of the device infos (mandatory when the device is disconnected).
176-
* Only accessed from callback_thread. */
176+
* Initialized before callback_thread is created; exclusively owned by
177+
* callback_thread after that (both reads/writes and final cleanup). */
177178
struct hid_device_info *devs;
178179
} hid_hotplug_context = {
179180
.next_handle = FIRST_HOTPLUG_CALLBACK_HANDLE,
@@ -1218,9 +1219,6 @@ static void* callback_thread(void* user_data)
12181219

12191220
hidapi_thread_mutex_lock(&hid_hotplug_context.callback_thread);
12201221

1221-
/* Initialize the known-device list; only accessed from this thread */
1222-
hid_hotplug_context.devs = hid_enumerate(0, 0);
1223-
12241222
/* We stop the thread if by the moment there are no events left in the queue there are no callbacks left */
12251223
while (1) {
12261224
/* Wait for events to arrive or shutdown signal */
@@ -1342,12 +1340,14 @@ int HID_API_EXPORT HID_API_CALL hid_hotplug_register_callback(unsigned short ven
13421340
last->next = hotplug_cb;
13431341
}
13441342
else {
1343+
/* Fill already connected devices so we can use this info in disconnection notification */
13451344
if (libusb_init(&hid_hotplug_context.context)) {
13461345
free(hotplug_cb);
13471346
pthread_mutex_unlock(&hid_hotplug_context.mutex);
13481347
return -1;
13491348
}
13501349

1350+
hid_hotplug_context.devs = hid_enumerate(0, 0);
13511351
hid_hotplug_context.hotplug_cbs = hotplug_cb;
13521352

13531353
/* Arm a global callback to receive ALL notifications for HID class devices */
@@ -1372,8 +1372,7 @@ int HID_API_EXPORT HID_API_CALL hid_hotplug_register_callback(unsigned short ven
13721372
hid_hotplug_context.mutex_in_use = 1;
13731373

13741374
if ((flags & HID_API_HOTPLUG_ENUMERATE) && (events & HID_API_HOTPLUG_EVENT_DEVICE_ARRIVED)) {
1375-
struct hid_device_info* all_devs = hid_enumerate(0, 0);
1376-
struct hid_device_info* device = all_devs;
1375+
struct hid_device_info* device = hid_hotplug_context.devs;
13771376
/* Notify about already connected devices, if asked so */
13781377
while (device != NULL) {
13791378
if (hid_internal_match_device_id(device->vendor_id, device->product_id, hotplug_cb->vendor_id, hotplug_cb->product_id)) {
@@ -1382,7 +1381,6 @@ int HID_API_EXPORT HID_API_CALL hid_hotplug_register_callback(unsigned short ven
13821381

13831382
device = device->next;
13841383
}
1385-
hid_free_enumeration(all_devs);
13861384
}
13871385

13881386
hid_hotplug_context.mutex_in_use = old_state;

0 commit comments

Comments
 (0)