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) {
+ if (r != sizeof(dummy))
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
/* 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 control pipe");
+ /* read the dummy data from the control pipe unless someone is closing
+ * a device */
+ usbi_mutex_lock(&ctx->pollfd_modify_lock);
+ ru = ctx->pollfd_modify;
+ usbi_mutex_unlock(&ctx->pollfd_modify_lock);
+ if (!ru) {
+ ret = usbi_read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy));
+ if (ret != sizeof(dummy)) {
+ usbi_err(ctx, "control pipe read error %d err=%d",
+ ret, errno);
+ r = LIBUSB_ERROR_OTHER;
+ goto handled;
+ }
+ }
+
if (0 == --r)
goto handled;
}