diff options
Diffstat (limited to 'libusb/core.c')
-rw-r--r-- | libusb/core.c | 60 |
1 files changed, 40 insertions, 20 deletions
diff --git a/libusb/core.c b/libusb/core.c index 042f7a5..32db2a6 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -1172,18 +1172,50 @@ void API_EXPORTED libusb_unref_device(libusb_device *dev) } /* - * Interrupt the iteration of the event handling thread, so that it picks - * up the new fd. + * Signal the event pipe so that the event handling thread will be + * interrupted to process an internal event. */ -void usbi_fd_notification(struct libusb_context *ctx) +int usbi_signal_event(struct libusb_context *ctx) { unsigned char dummy = 1; ssize_t r; /* write some data on event pipe to interrupt event handlers */ r = usbi_write(ctx->event_pipe[1], &dummy, sizeof(dummy)); - if (r != sizeof(dummy)) + if (r != sizeof(dummy)) { usbi_warn(ctx, "internal signalling write failed"); + return LIBUSB_ERROR_IO; + } + + return 0; +} + +/* + * Clear the event pipe so that the event handling will no longer be + * interrupted. + */ +int usbi_clear_event(struct libusb_context *ctx) +{ + unsigned char dummy; + ssize_t r; + + /* read some data on event pipe to clear it */ + r = usbi_read(ctx->event_pipe[0], &dummy, sizeof(dummy)); + if (r != sizeof(dummy)) { + usbi_warn(ctx, "internal signalling read failed"); + return LIBUSB_ERROR_IO; + } + + return 0; +} + +/* + * Interrupt the iteration of the event handling thread, so that it picks + * up the new fd. + */ +void usbi_fd_notification(struct libusb_context *ctx) +{ + usbi_signal_event(ctx); } /** \ingroup dev @@ -1384,8 +1416,6 @@ static void do_close(struct libusb_context *ctx, void API_EXPORTED libusb_close(libusb_device_handle *dev_handle) { struct libusb_context *ctx; - unsigned char dummy = 1; - ssize_t r; if (!dev_handle) return; @@ -1404,24 +1434,14 @@ void API_EXPORTED libusb_close(libusb_device_handle *dev_handle) ctx->device_close++; usbi_mutex_unlock(&ctx->event_data_lock); - /* write some data on event pipe to interrupt event handlers */ - r = usbi_write(ctx->event_pipe[1], &dummy, sizeof(dummy)); - if (r <= 0) { - usbi_warn(ctx, "internal signalling write failed, closing anyway"); - do_close(ctx, dev_handle); - usbi_mutex_lock(&ctx->event_data_lock); - ctx->device_close--; - usbi_mutex_unlock(&ctx->event_data_lock); - return; - } + /* signal the event pipe to interrupt event handlers */ + usbi_signal_event(ctx); /* take event handling lock */ libusb_lock_events(ctx); - /* read the dummy data */ - r = usbi_read(ctx->event_pipe[0], &dummy, sizeof(dummy)); - if (r <= 0) - usbi_warn(ctx, "internal signalling read failed, closing anyway"); + /* clear the event pipe */ + usbi_clear_event(ctx); /* Close the device */ do_close(ctx, dev_handle); |