libusb(3): Implement libusb_interrupt_event_handler() by exposing existing function.

Sponsored by:	NVIDIA Networking

(cherry picked from commit aa87aa5232)
This commit is contained in:
Hans Petter Selasky 2022-10-02 17:30:40 +02:00
parent 8e7cb25f5b
commit e4e79af3f9
4 changed files with 25 additions and 12 deletions

View file

@ -135,6 +135,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

View file

@ -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

View file

@ -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);

View file

@ -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 @@ libusb10_submit_transfer_sub(struct libusb20_device *pdev, uint8_t endpoint)
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 */