Factorize event handler interruption code
authorPete Batard <pbatard@gmail.com>
Thu, 10 Jun 2010 22:00:25 +0000 (17:00 -0500)
committerDaniel Drake <dan@reactivated.net>
Thu, 10 Jun 2010 22:00:25 +0000 (17:00 -0500)
This will be additionally used by the windows backend which modifies
the fd set frequently.

libusb/core.c
libusb/libusbi.h

index 08c23fa..227219b 100644 (file)
@@ -845,6 +845,50 @@ API_EXPORTED void libusb_unref_device(libusb_device *dev)
        }
 }
 
+/*
+ * Interrupt the iteration of the event handling thread, so that it picks
+ * up the new fd.
+ */
+void usbi_fd_notification(struct libusb_context *ctx)
+{
+       unsigned char dummy = 1;
+       ssize_t r;
+
+       if (ctx == NULL)
+               return;
+
+       /* record that we are messing with poll fds */
+       usbi_mutex_lock(&ctx->pollfd_modify_lock);
+       ctx->pollfd_modify++;
+       usbi_mutex_unlock(&ctx->pollfd_modify_lock);
+
+       /* write some data on control pipe to interrupt event handlers */
+       r = usbi_write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
+       if (r <= 0) {
+               usbi_warn(ctx, "internal signalling write failed");
+               usbi_mutex_lock(&ctx->pollfd_modify_lock);
+               ctx->pollfd_modify--;
+               usbi_mutex_unlock(&ctx->pollfd_modify_lock);
+               return;
+       }
+
+       /* take event handling lock */
+       libusb_lock_events(ctx);
+
+       /* read the dummy data */
+       r = usbi_read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
+       if (r <= 0)
+               usbi_warn(ctx, "internal signalling read failed");
+
+       /* we're done with modifying poll fds */
+       usbi_mutex_lock(&ctx->pollfd_modify_lock);
+       ctx->pollfd_modify--;
+       usbi_mutex_unlock(&ctx->pollfd_modify_lock);
+
+       /* Release event handling lock and wake up event waiters */
+       libusb_unlock_events(ctx);
+}
+
 /** \ingroup dev
  * Open a device and obtain a device handle. A handle allows you to perform
  * I/O on the device in question.
@@ -869,9 +913,7 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle)
        struct libusb_context *ctx = DEVICE_CTX(dev);
        struct libusb_device_handle *_handle;
        size_t priv_size = usbi_backend->device_handle_priv_size;
-       unsigned char dummy = 1;
        int r;
-       ssize_t tmp;
        usbi_dbg("open %d.%d", dev->bus_number, dev->device_address);
 
        _handle = malloc(sizeof(*_handle) + priv_size);
@@ -901,44 +943,13 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle)
        usbi_mutex_unlock(&ctx->open_devs_lock);
        *handle = _handle;
 
-
        /* At this point, we want to interrupt any existing event handlers so
         * that they realise the addition of the new device's poll fd. One
         * example when this is desirable is if the user is running a separate
         * dedicated libusb events handling thread, which is running with a long
         * or infinite timeout. We want to interrupt that iteration of the loop,
         * so that it picks up the new fd, and then continues. */
-
-       /* record that we are messing with poll fds */
-       usbi_mutex_lock(&ctx->pollfd_modify_lock);
-       ctx->pollfd_modify++;
-       usbi_mutex_unlock(&ctx->pollfd_modify_lock);
-
-       /* write some data on control pipe to interrupt event handlers */
-       tmp = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
-       if (tmp <= 0) {
-               usbi_warn(ctx, "internal signalling write failed");
-               usbi_mutex_lock(&ctx->pollfd_modify_lock);
-               ctx->pollfd_modify--;
-               usbi_mutex_unlock(&ctx->pollfd_modify_lock);
-               return 0;
-       }
-
-       /* take event handling lock */
-       libusb_lock_events(ctx);
-
-       /* read the dummy data */
-       tmp = read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
-       if (tmp <= 0)
-               usbi_warn(ctx, "internal signalling read failed");
-
-       /* we're done with modifying poll fds */
-       usbi_mutex_lock(&ctx->pollfd_modify_lock);
-       ctx->pollfd_modify--;
-       usbi_mutex_unlock(&ctx->pollfd_modify_lock);
-
-       /* Release event handling lock and wake up event waiters */
-       libusb_unlock_events(ctx);
+       usbi_fd_notification(ctx);
 
        return 0;
 }
index 14996cf..1e9b69f 100644 (file)
@@ -364,6 +364,7 @@ struct usbi_pollfd {
 
 int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events);
 void usbi_remove_pollfd(struct libusb_context *ctx, int fd);
+void usbi_fd_notification(struct libusb_context *ctx);
 
 /* device discovery */