summaryrefslogtreecommitdiff
path: root/libusb/core.c
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2010-06-10 17:00:25 -0500
committerDaniel Drake <dan@reactivated.net>2010-06-10 17:00:25 -0500
commita7c056c14867e1cc3ef83682f2706cdbdca7c4ce (patch)
treec6e7e60bafbac67b581b500ba4289787cca65480 /libusb/core.c
parentfc0af8e3f76925ad09e0fbc6d233d500753ee375 (diff)
downloadlibusbx-a7c056c14867e1cc3ef83682f2706cdbdca7c4ce.tar.gz
Factorize event handler interruption code
This will be additionally used by the windows backend which modifies the fd set frequently.
Diffstat (limited to 'libusb/core.c')
-rw-r--r--libusb/core.c79
1 files changed, 45 insertions, 34 deletions
diff --git a/libusb/core.c b/libusb/core.c
index 08c23fa..227219b 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -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;
}