summaryrefslogtreecommitdiff
path: root/libusb/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'libusb/core.c')
-rw-r--r--libusb/core.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/libusb/core.c b/libusb/core.c
index 626fabc..9894209 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -1200,13 +1200,16 @@ int usbi_clear_event(struct libusb_context *ctx)
*/
void usbi_fd_notification(struct libusb_context *ctx)
{
- /* record that there is a new poll fd */
+ int pending_events;
+
+ /* Record that there is a new poll fd.
+ * Only signal an event if there are no prior pending events. */
usbi_mutex_lock(&ctx->event_data_lock);
+ pending_events = usbi_pending_events(ctx);
ctx->fd_notify = 1;
+ if (!pending_events)
+ usbi_signal_event(ctx);
usbi_mutex_unlock(&ctx->event_data_lock);
-
- /* signal the event pipe to interrupt event handlers */
- usbi_signal_event(ctx);
}
/** \ingroup dev
@@ -1407,6 +1410,7 @@ static void do_close(struct libusb_context *ctx,
void API_EXPORTED libusb_close(libusb_device_handle *dev_handle)
{
struct libusb_context *ctx;
+ int pending_events;
if (!dev_handle)
return;
@@ -1420,26 +1424,28 @@ void API_EXPORTED libusb_close(libusb_device_handle *dev_handle)
* thread from doing event handling) because we will be removing a file
* descriptor from the polling loop. */
- /* record that we are closing a device */
+ /* Record that we are closing a device.
+ * Only signal an event if there are no prior pending events. */
usbi_mutex_lock(&ctx->event_data_lock);
+ pending_events = usbi_pending_events(ctx);
ctx->device_close++;
+ if (!pending_events)
+ usbi_signal_event(ctx);
usbi_mutex_unlock(&ctx->event_data_lock);
- /* signal the event pipe to interrupt event handlers */
- usbi_signal_event(ctx);
-
/* take event handling lock */
libusb_lock_events(ctx);
- /* clear the event pipe */
- usbi_clear_event(ctx);
-
/* Close the device */
do_close(ctx, dev_handle);
- /* we're done with closing this device */
+ /* We're done with closing this device.
+ * Clear the event pipe if there are no further pending events. */
usbi_mutex_lock(&ctx->event_data_lock);
ctx->device_close--;
+ pending_events = usbi_pending_events(ctx);
+ if (!pending_events)
+ usbi_clear_event(ctx);
usbi_mutex_unlock(&ctx->event_data_lock);
/* Release event handling lock and wake up event waiters */