}
}
+/*
+ * 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.
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);
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;
}