summaryrefslogtreecommitdiff
path: root/libusb/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'libusb/core.c')
-rw-r--r--libusb/core.c60
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);