diff options
author | Pete Batard <pbatard@gmail.com> | 2010-03-02 15:39:01 +0000 |
---|---|---|
committer | Pete Batard <pbatard@gmail.com> | 2010-03-02 15:39:01 +0000 |
commit | 4637f267b036c37f58cb9e9cb35692b813be02f5 (patch) | |
tree | 40b6bc84c22e4e8373e6cb01b4122a3dda8b65ef /libusb | |
parent | 4072ec828c53f6d923bdea1f8d002a10f08bf7e9 (diff) | |
download | libusb-4637f267b036c37f58cb9e9cb35692b813be02f5.tar.gz |
poll fd notification improvements (core)
factorized code from libusb_open into new function usbi_fd_notification
Diffstat (limited to 'libusb')
-rw-r--r-- | libusb/core.c | 75 |
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; } |