core: Add helper functions to signal and clear the event pipe
authorChris Dickens <christopher.a.dickens@gmail.com>
Tue, 18 Nov 2014 07:53:11 +0000 (23:53 -0800)
committerChris Dickens <chris.dickens@hp.com>
Fri, 19 Dec 2014 19:17:50 +0000 (11:17 -0800)
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
libusb/core.c
libusb/io.c
libusb/libusbi.h
libusb/version_nano.h

index 042f7a5..32db2a6 100644 (file)
@@ -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);
index 97af568..f00af14 100644 (file)
@@ -2051,8 +2051,6 @@ redo_poll:
                /* another thread wanted to interrupt event handling, and it succeeded!
                 * handle any other events that cropped up at the same time, and
                 * simply return */
-               ssize_t ret;
-               unsigned char dummy;
                unsigned int ru;
 
                usbi_dbg("caught a fish on the event pipe");
@@ -2063,13 +2061,9 @@ redo_poll:
                ru = ctx->device_close;
                usbi_mutex_unlock(&ctx->event_data_lock);
                if (!ru) {
-                       ret = usbi_read(ctx->event_pipe[0], &dummy, sizeof(dummy));
-                       if (ret != sizeof(dummy)) {
-                               usbi_err(ctx, "event pipe read error %d err=%d",
-                                        ret, errno);
-                               r = LIBUSB_ERROR_OTHER;
+                       r = usbi_clear_event(ctx);
+                       if (r)
                                goto handled;
-                       }
                }
 
                if (0 == --r)
index cdcc61a..ebcc0d3 100644 (file)
@@ -462,6 +462,9 @@ int usbi_get_config_index_by_value(struct libusb_device *dev,
 void usbi_connect_device (struct libusb_device *dev);
 void usbi_disconnect_device (struct libusb_device *dev);
 
+int usbi_signal_event(struct libusb_context *ctx);
+int usbi_clear_event(struct libusb_context *ctx);
+
 /* Internal abstraction for poll (needs struct usbi_transfer on Windows) */
 #if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) || defined(OS_HAIKU)
 #include <unistd.h>
index b41fc42..73d2ed1 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 10935
+#define LIBUSB_NANO 10936