diff options
author | Chris Dickens <christopher.a.dickens@gmail.com> | 2015-12-10 00:20:18 -0800 |
---|---|---|
committer | Chris Dickens <christopher.a.dickens@gmail.com> | 2015-12-17 00:28:35 -0800 |
commit | a6db382ad11f7662b550338e0570d5a2dfd8ce5a (patch) | |
tree | 6b14ce8d5359234536e2c280c91c97d5ec440a7a | |
parent | 87a97e4f2065cc7190b0098b4d0df5a68e10a547 (diff) | |
download | libusb-a6db382ad11f7662b550338e0570d5a2dfd8ce5a.tar.gz |
API: Add libusb_interrupt_event_handler() function
This new function will allow the user to purposely interrupt an
event handling thread, causing it to return from the event handling
function. This is mainly useful for cleanly exiting from a dedicated
event handling thread during application shutdown.
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
-rw-r--r-- | libusb/io.c | 28 | ||||
-rw-r--r-- | libusb/libusb-1.0.def | 2 | ||||
-rw-r--r-- | libusb/libusb.h | 3 | ||||
-rw-r--r-- | libusb/libusbi.h | 3 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 |
5 files changed, 36 insertions, 2 deletions
diff --git a/libusb/io.c b/libusb/io.c index 2b2bf29..f1980f0 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -1857,6 +1857,29 @@ int API_EXPORTED libusb_event_handler_active(libusb_context *ctx) } /** \ingroup poll + * Interrupt any active thread that is handling events. This is mainly useful + * for interrupting a dedicated event handling thread when an application + * wishes to call libusb_exit(). + * + * Since version 1.0.21, \ref LIBUSB_API_VERSION >= 0x01000105 + * + * \param ctx the context to operate on, or NULL for the default context + * \ref mtasync + */ +void API_EXPORTED libusb_interrupt_event_handler(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + + usbi_dbg(""); + usbi_mutex_lock(&ctx->event_data_lock); + if (!usbi_pending_events(ctx)) { + ctx->event_flags |= USBI_EVENT_USER_INTERRUPT; + usbi_signal_event(ctx); + } + usbi_mutex_unlock(&ctx->event_data_lock); +} + +/** \ingroup poll * Acquire the event waiters lock. This lock is designed to be obtained under * the situation where you want to be aware when events are completed, but * some other thread is event handling so calling libusb_handle_events() is not @@ -2149,6 +2172,11 @@ redo_poll: if (ctx->event_flags & USBI_EVENT_POLLFDS_MODIFIED) usbi_dbg("someone updated the poll fds"); + if (ctx->event_flags & USBI_EVENT_USER_INTERRUPT) { + usbi_dbg("someone purposely interrupted"); + ctx->event_flags &= ~USBI_EVENT_USER_INTERRUPT; + } + /* check if someone is closing a device */ if (ctx->device_close) usbi_dbg("someone is closing a device"); diff --git a/libusb/libusb-1.0.def b/libusb/libusb-1.0.def index 538ad49..7b14e0f 100644 --- a/libusb/libusb-1.0.def +++ b/libusb/libusb-1.0.def @@ -116,6 +116,8 @@ EXPORTS libusb_hotplug_register_callback@36 = libusb_hotplug_register_callback libusb_init libusb_init@4 = libusb_init + libusb_interrupt_event_handler + libusb_interrupt_event_handler@4 = libusb_interrupt_event_handler libusb_interrupt_transfer libusb_interrupt_transfer@24 = libusb_interrupt_transfer libusb_kernel_driver_active diff --git a/libusb/libusb.h b/libusb/libusb.h index 513945f..ba82c36 100644 --- a/libusb/libusb.h +++ b/libusb/libusb.h @@ -141,7 +141,7 @@ typedef unsigned __int32 uint32_t; * Internally, LIBUSB_API_VERSION is defined as follows: * (libusb major << 24) | (libusb minor << 16) | (16 bit incremental) */ -#define LIBUSB_API_VERSION 0x01000104 +#define LIBUSB_API_VERSION 0x01000105 /* The following is kept for compatibility, but will be deprecated in the future */ #define LIBUSBX_API_VERSION LIBUSB_API_VERSION @@ -1801,6 +1801,7 @@ void LIBUSB_CALL libusb_lock_events(libusb_context *ctx); void LIBUSB_CALL libusb_unlock_events(libusb_context *ctx); int LIBUSB_CALL libusb_event_handling_ok(libusb_context *ctx); int LIBUSB_CALL libusb_event_handler_active(libusb_context *ctx); +void LIBUSB_CALL libusb_interrupt_event_handler(libusb_context *ctx); void LIBUSB_CALL libusb_lock_event_waiters(libusb_context *ctx); void LIBUSB_CALL libusb_unlock_event_waiters(libusb_context *ctx); int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv); diff --git a/libusb/libusbi.h b/libusb/libusbi.h index 73d3492..ea39303 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -323,6 +323,9 @@ struct libusb_context { enum usbi_event_flags { /* The list of pollfds has been modified */ USBI_EVENT_POLLFDS_MODIFIED = 1 << 0, + + /* The user has interrupted the event handler */ + USBI_EVENT_USER_INTERRUPT = 1 << 1, }; /* Macros for managing event handling state */ diff --git a/libusb/version_nano.h b/libusb/version_nano.h index 53bfa23..bc5ae28 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11016 +#define LIBUSB_NANO 11017 |