summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2010-03-02 15:39:01 +0000
committerPete Batard <pbatard@gmail.com>2010-03-02 15:39:01 +0000
commit4637f267b036c37f58cb9e9cb35692b813be02f5 (patch)
tree40b6bc84c22e4e8373e6cb01b4122a3dda8b65ef
parent4072ec828c53f6d923bdea1f8d002a10f08bf7e9 (diff)
downloadlibusb-4637f267b036c37f58cb9e9cb35692b813be02f5.tar.gz
poll fd notification improvements (core)
factorized code from libusb_open into new function usbi_fd_notification
-rw-r--r--libusb/core.c75
1 files changed, 45 insertions, 30 deletions
diff --git a/libusb/core.c b/libusb/core.c
index da0ca9d..22c8265 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -837,6 +837,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.
@@ -900,36 +944,7 @@ API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle)
* 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 */
- 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 0;
- }
-
- /* 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);
+ usbi_fd_notification(ctx);
return 0;
}