summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Dickens <christopher.a.dickens@gmail.com>2014-11-17 23:53:11 -0800
committerChris Dickens <chris.dickens@hp.com>2014-12-19 11:17:50 -0800
commit192adf437baec398bec36de50737a570e6c2f29c (patch)
tree93c6c3bd74bcbd70f7f7e7c275f2e26dc5fe0fe4
parent5b2f2e11852edf81be401736e5ece7c9debe047e (diff)
downloadlibusb-192adf437baec398bec36de50737a570e6c2f29c.tar.gz
core: Add helper functions to signal and clear the event pipe
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
-rw-r--r--libusb/core.c60
-rw-r--r--libusb/io.c10
-rw-r--r--libusb/libusbi.h3
-rw-r--r--libusb/version_nano.h2
4 files changed, 46 insertions, 29 deletions
diff --git a/libusb/core.c b/libusb/core.c
index 042f7a5..32db2a6 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -1172,18 +1172,50 @@ void API_EXPORTED libusb_unref_device(libusb_device *dev)
}
/*
- * Interrupt the iteration of the event handling thread, so that it picks
- * up the new fd.
+ * Signal the event pipe so that the event handling thread will be
+ * interrupted to process an internal event.
*/
-void usbi_fd_notification(struct libusb_context *ctx)
+int usbi_signal_event(struct libusb_context *ctx)
{
unsigned char dummy = 1;
ssize_t r;
/* write some data on event pipe to interrupt event handlers */
r = usbi_write(ctx->event_pipe[1], &dummy, sizeof(dummy));
- if (r != sizeof(dummy))
+ if (r != sizeof(dummy)) {
usbi_warn(ctx, "internal signalling write failed");
+ return LIBUSB_ERROR_IO;
+ }
+
+ return 0;
+}
+
+/*
+ * Clear the event pipe so that the event handling will no longer be
+ * interrupted.
+ */
+int usbi_clear_event(struct libusb_context *ctx)
+{
+ unsigned char dummy;
+ ssize_t r;
+
+ /* read some data on event pipe to clear it */
+ r = usbi_read(ctx->event_pipe[0], &dummy, sizeof(dummy));
+ if (r != sizeof(dummy)) {
+ usbi_warn(ctx, "internal signalling read failed");
+ return LIBUSB_ERROR_IO;
+ }
+
+ return 0;
+}
+
+/*
+ * Interrupt the iteration of the event handling thread, so that it picks
+ * up the new fd.
+ */
+void usbi_fd_notification(struct libusb_context *ctx)
+{
+ usbi_signal_event(ctx);
}
/** \ingroup dev
@@ -1384,8 +1416,6 @@ static void do_close(struct libusb_context *ctx,
void API_EXPORTED libusb_close(libusb_device_handle *dev_handle)
{
struct libusb_context *ctx;
- unsigned char dummy = 1;
- ssize_t r;
if (!dev_handle)
return;
@@ -1404,24 +1434,14 @@ void API_EXPORTED libusb_close(libusb_device_handle *dev_handle)
ctx->device_close++;
usbi_mutex_unlock(&ctx->event_data_lock);
- /* write some data on event pipe to interrupt event handlers */
- r = usbi_write(ctx->event_pipe[1], &dummy, sizeof(dummy));
- if (r <= 0) {
- usbi_warn(ctx, "internal signalling write failed, closing anyway");
- do_close(ctx, dev_handle);
- usbi_mutex_lock(&ctx->event_data_lock);
- ctx->device_close--;
- usbi_mutex_unlock(&ctx->event_data_lock);
- return;
- }
+ /* signal the event pipe to interrupt event handlers */
+ usbi_signal_event(ctx);
/* take event handling lock */
libusb_lock_events(ctx);
- /* read the dummy data */
- r = usbi_read(ctx->event_pipe[0], &dummy, sizeof(dummy));
- if (r <= 0)
- usbi_warn(ctx, "internal signalling read failed, closing anyway");
+ /* clear the event pipe */
+ usbi_clear_event(ctx);
/* Close the device */
do_close(ctx, dev_handle);
diff --git a/libusb/io.c b/libusb/io.c
index 97af568..f00af14 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -2051,8 +2051,6 @@ redo_poll:
/* 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 event pipe");
@@ -2063,13 +2061,9 @@ redo_poll:
ru = ctx->device_close;
usbi_mutex_unlock(&ctx->event_data_lock);
if (!ru) {
- ret = usbi_read(ctx->event_pipe[0], &dummy, sizeof(dummy));
- if (ret != sizeof(dummy)) {
- usbi_err(ctx, "event pipe read error %d err=%d",
- ret, errno);
- r = LIBUSB_ERROR_OTHER;
+ r = usbi_clear_event(ctx);
+ if (r)
goto handled;
- }
}
if (0 == --r)
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index cdcc61a..ebcc0d3 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -462,6 +462,9 @@ int usbi_get_config_index_by_value(struct libusb_device *dev,
void usbi_connect_device (struct libusb_device *dev);
void usbi_disconnect_device (struct libusb_device *dev);
+int usbi_signal_event(struct libusb_context *ctx);
+int usbi_clear_event(struct libusb_context *ctx);
+
/* Internal abstraction for poll (needs struct usbi_transfer on Windows) */
#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) || defined(OS_HAIKU)
#include <unistd.h>
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index b41fc42..73d2ed1 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10935
+#define LIBUSB_NANO 10936