mirror of
https://github.com/RPCS3/libusb.git
synced 2026-07-21 00:16:04 -04:00
core: Add helper functions to signal and clear the event pipe
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
This commit is contained in:
committed by
Chris Dickens
parent
5b2f2e1185
commit
192adf437b
+40
-20
@@ -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);
|
||||
|
||||
+2
-8
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define LIBUSB_NANO 10935
|
||||
#define LIBUSB_NANO 10936
|
||||
|
||||
Reference in New Issue
Block a user