diff --git a/libusb/hid.c b/libusb/hid.c index 272fc24de..d3bd1ad90 100644 --- a/libusb/hid.c +++ b/libusb/hid.c @@ -1096,6 +1096,7 @@ static void hid_internal_invoke_callbacks(struct hid_device_info* info, hid_hotp } current = &callback->next; } + hid_hotplug_context.mutex_state = 1; pthread_mutex_unlock(&hid_hotplug_context.cb_mutex); } diff --git a/linux/hid.c b/linux/hid.c index 64de46f55..2ef72132a 100644 --- a/linux/hid.c +++ b/linux/hid.c @@ -1111,6 +1111,7 @@ void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs) static void hid_internal_invoke_callbacks(struct hid_device_info *info, hid_hotplug_event event) { hid_hotplug_context.mutex_state = 2; + struct hid_hotplug_callback **current = &hid_hotplug_context.hotplug_cbs; while (*current) { struct hid_hotplug_callback *callback = *current; @@ -1126,6 +1127,7 @@ static void hid_internal_invoke_callbacks(struct hid_device_info *info, hid_hotp } current = &callback->next; } + hid_hotplug_context.mutex_state = 1; } diff --git a/mac/hid.c b/mac/hid.c index 3fba3506d..e3af80ca4 100644 --- a/mac/hid.c +++ b/mac/hid.c @@ -932,23 +932,25 @@ void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs) static void hid_internal_invoke_callbacks(struct hid_device_info *info, hid_hotplug_event event) { + hid_hotplug_context.mutex_state = 2; + struct hid_hotplug_callback **current = &hid_hotplug_context.hotplug_cbs; while (*current) { struct hid_hotplug_callback *callback = *current; if ((callback->events & event) && hid_internal_match_device_id(info->vendor_id, info->product_id, callback->vendor_id, callback->product_id)) { int result = callback->callback(callback->handle, info, event, callback->user_data); - /* If the result is non-zero, we remove the callback and proceed */ + /* If the result is non-zero, we mark the callback for removal and proceed */ /* Do not use the deregister call as it locks the mutex, and we are currently in a lock */ if (result) { - struct hid_hotplug_callback *callback = *current; - *current = (*current)->next; - free(callback); + (*current)->events = 0; continue; } } current = &callback->next; } + + hid_hotplug_context.mutex_state = 1; } static void hid_internal_hotplug_connect_callback(void *context, IOReturn result, void *sender, IOHIDDeviceRef device) @@ -968,7 +970,6 @@ static void hid_internal_hotplug_connect_callback(void *context, IOReturn result { /* Lock the mutex to avoid race conditions */ pthread_mutex_lock(&hid_hotplug_context.mutex); - hid_hotplug_context.mutex_state = 2; /* Invoke all callbacks */ while(info_cur) @@ -994,7 +995,6 @@ static void hid_internal_hotplug_connect_callback(void *context, IOReturn result if (hid_hotplug_context.thread_state > 0) { - hid_hotplug_context.mutex_state = 1; pthread_mutex_unlock(&hid_hotplug_context.mutex); } }