}
/** \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
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");
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
* 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
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);
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 */
-#define LIBUSB_NANO 11016
+#define LIBUSB_NANO 11017