git: aa87aa52326b - main - libusb(3): Implement libusb_interrupt_event_handler() by exposing existing function.

From: Hans Petter Selasky <hselasky_at_FreeBSD.org>
Date: Sun, 02 Oct 2022 15:41:17 UTC
The branch main has been updated by hselasky:

URL: https://cgit.FreeBSD.org/src/commit/?id=aa87aa52326be7b726664dba65e91ec3d8160f48

commit aa87aa52326be7b726664dba65e91ec3d8160f48
Author:     Hans Petter Selasky <hselasky@FreeBSD.org>
AuthorDate: 2022-10-02 15:30:40 +0000
Commit:     Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2022-10-02 15:32:59 +0000

    libusb(3): Implement libusb_interrupt_event_handler() by exposing existing function.
    
    MFC after:      1 week
    Sponsored by:   NVIDIA Networking
---
 lib/libusb/Makefile   |  1 +
 lib/libusb/libusb.3   | 13 ++++++++++---
 lib/libusb/libusb.h   |  1 +
 lib/libusb/libusb10.c | 22 +++++++++++++---------
 4 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile
index 59389d74e179..c8f3dda0f1f8 100644
--- a/lib/libusb/Makefile
+++ b/lib/libusb/Makefile
@@ -137,6 +137,7 @@ MLINKS += libusb.3 libusb_lock_events.3
 MLINKS += libusb.3 libusb_unlock_events.3
 MLINKS += libusb.3 libusb_event_handling_ok.3
 MLINKS += libusb.3 libusb_event_handler_active.3
+MLINKS += libusb.3 libusb_interrupt_event_handler.3
 MLINKS += libusb.3 libusb_lock_event_waiters.3
 MLINKS += libusb.3 libusb_unlock_event_waiters.3
 MLINKS += libusb.3 libusb_wait_for_event.3
diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3
index 0d0e2b1a4ef1..d4c638d986e4 100644
--- a/lib/libusb/libusb.3
+++ b/lib/libusb/libusb.3
@@ -1,8 +1,6 @@
 .\"
 .\" Copyright (c) 2009 Sylvestre Gallon
 .\"
-.\" All rights reserved.
-.\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
 .\" are met:
@@ -26,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 9, 2020
+.Dd October, 2, 2022
 .Dt LIBUSB 3
 .Os
 .Sh NAME
@@ -604,6 +602,15 @@ Returns 1 if there is a thread handling events and 0 if there
 are no threads currently handling events.
 .Pp
 .Ft void
+.Fn libusb_interrupt_event_handler "libusb_context *ctx"
+Causes the
+.Fn libusb_handle_events
+familiy of functions to return to the caller one time.
+The
+.Fn libusb_handle_events
+functions may be called again after calling this function.
+.Pp
+.Ft void
 .Fn libusb_lock_event_waiters "libusb_context *ctx"
 Acquire the event_waiters lock.
 This lock is designed to be obtained in the
diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h
index 3d353402ea06..9eaee671b8b3 100644
--- a/lib/libusb/libusb.h
+++ b/lib/libusb/libusb.h
@@ -550,6 +550,7 @@ void	libusb_lock_events(libusb_context * ctx);
 void	libusb_unlock_events(libusb_context * ctx);
 int	libusb_event_handling_ok(libusb_context * ctx);
 int	libusb_event_handler_active(libusb_context * ctx);
+void	libusb_interrupt_event_handler(libusb_context *ctx);
 void	libusb_lock_event_waiters(libusb_context * ctx);
 void	libusb_unlock_event_waiters(libusb_context * ctx);
 int	libusb_wait_for_event(libusb_context * ctx, struct timeval *tv);
diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c
index ecfffde555aa..1fc89fc409f0 100644
--- a/lib/libusb/libusb10.c
+++ b/lib/libusb/libusb10.c
@@ -116,12 +116,16 @@ libusb_set_nonblocking(int f)
 	fcntl(f, F_SETFL, flags);
 }
 
-static void
-libusb10_wakeup_event_loop(libusb_context *ctx)
+void
+libusb_interrupt_event_handler(libusb_context *ctx)
 {
-	uint8_t dummy = 0;
+	uint8_t dummy;
 	int err;
 
+	if (ctx == NULL)
+		return;
+
+	dummy = 0;
 	err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy));
 	if (err < (int)sizeof(dummy)) {
 		/* ignore error, if any */
@@ -545,7 +549,7 @@ libusb_open(libusb_device *dev, libusb_device_handle **devh)
 	    POLLOUT | POLLRDNORM | POLLWRNORM);
 
 	/* make sure our event loop detects the new device */
-	libusb10_wakeup_event_loop(ctx);
+	libusb_interrupt_event_handler(ctx);
 
 	*devh = pdev;
 
@@ -614,7 +618,7 @@ libusb_close(struct libusb20_device *pdev)
 	libusb_unref_device(dev);
 
 	/* make sure our event loop detects the closed device */
-	libusb10_wakeup_event_loop(ctx);
+	libusb_interrupt_event_handler(ctx);
 }
 
 libusb_device *
@@ -1443,7 +1447,7 @@ found:
 failure:
 	libusb10_complete_transfer(pxfer0, sxfer, LIBUSB_TRANSFER_ERROR);
 	/* make sure our event loop spins the done handler */
-	libusb10_wakeup_event_loop(dev->ctx);
+	libusb_interrupt_event_handler(dev->ctx);
 }
 
 /* The following function must be called unlocked */
@@ -1555,7 +1559,7 @@ libusb_cancel_transfer(struct libusb_transfer *uxfer)
 		libusb10_complete_transfer(NULL,
 		    sxfer, LIBUSB_TRANSFER_CANCELLED);
 		/* make sure our event loop spins the done handler */
-		libusb10_wakeup_event_loop(dev->ctx);
+		libusb_interrupt_event_handler(dev->ctx);
 	} else if (pxfer0 == NULL || pxfer1 == NULL) {
 		/* not started */
 		retval = LIBUSB_ERROR_NOT_FOUND;
@@ -1566,7 +1570,7 @@ libusb_cancel_transfer(struct libusb_transfer *uxfer)
 			/* clear transfer pointer */
 			libusb20_tr_set_priv_sc1(pxfer0, NULL);
 			/* make sure our event loop spins the done handler */
-			libusb10_wakeup_event_loop(dev->ctx);
+			libusb_interrupt_event_handler(dev->ctx);
 		} else {
 			libusb20_tr_stop(pxfer0);
 			/* make sure the queue doesn't stall */
@@ -1580,7 +1584,7 @@ libusb_cancel_transfer(struct libusb_transfer *uxfer)
 			/* clear transfer pointer */
 			libusb20_tr_set_priv_sc1(pxfer1, NULL);
 			/* make sure our event loop spins the done handler */
-			libusb10_wakeup_event_loop(dev->ctx);
+			libusb_interrupt_event_handler(dev->ctx);
 		} else {
 			libusb20_tr_stop(pxfer1);
 			/* make sure the queue doesn't stall */