mirror of
https://github.com/RPCS3/libusb.git
synced 2026-07-21 00:16:04 -04:00
Core: Keep a list of contexts created by libusb_init()
* This list can be used by backends to determine which contexts need notification of device removal (and in the future device arrival). The active_contexts_list is protected from multiple access by the active_contexts_lock. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
committed by
Hans de Goede
parent
2790e8f2b0
commit
913a233ec2
@@ -56,6 +56,9 @@ static int default_context_refcnt = 0;
|
||||
static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER;
|
||||
static struct timeval timestamp_origin = { 0, 0 };
|
||||
|
||||
usbi_mutex_static_t active_contexts_lock = USBI_MUTEX_INITIALIZER;
|
||||
struct list_head active_contexts_list;
|
||||
|
||||
/**
|
||||
* \mainpage libusbx-1.0 API Reference
|
||||
*
|
||||
@@ -1623,6 +1626,7 @@ int API_EXPORTED libusb_init(libusb_context **context)
|
||||
{
|
||||
char *dbg;
|
||||
struct libusb_context *ctx;
|
||||
static int first_init = 1;
|
||||
int r = 0;
|
||||
|
||||
usbi_mutex_static_lock(&default_context_lock);
|
||||
@@ -1688,6 +1692,16 @@ int API_EXPORTED libusb_init(libusb_context **context)
|
||||
}
|
||||
usbi_mutex_static_unlock(&default_context_lock);
|
||||
|
||||
usbi_mutex_static_lock(&active_contexts_lock);
|
||||
if (first_init) {
|
||||
first_init = 0;
|
||||
list_init (&active_contexts_list);
|
||||
}
|
||||
|
||||
list_add (&ctx->list, &active_contexts_list);
|
||||
usbi_mutex_static_unlock(&active_contexts_lock);
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
err_destroy_mutex:
|
||||
@@ -1724,6 +1738,10 @@ void API_EXPORTED libusb_exit(struct libusb_context *ctx)
|
||||
usbi_mutex_static_unlock(&default_context_lock);
|
||||
}
|
||||
|
||||
usbi_mutex_static_lock(&active_contexts_lock);
|
||||
list_del (&ctx->list);
|
||||
usbi_mutex_static_unlock(&active_contexts_lock);
|
||||
|
||||
/* a little sanity check. doesn't bother with open_devs locking because
|
||||
* unless there is an application bug, nobody will be accessing this. */
|
||||
if (!list_empty(&ctx->open_devs))
|
||||
|
||||
@@ -261,6 +261,8 @@ struct libusb_context {
|
||||
* this timerfd is maintained to trigger on the next pending timeout */
|
||||
int timerfd;
|
||||
#endif
|
||||
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
#ifdef USBI_TIMERFD_AVAILABLE
|
||||
@@ -917,4 +919,7 @@ extern const struct usbi_os_backend openbsd_backend;
|
||||
extern const struct usbi_os_backend windows_backend;
|
||||
extern const struct usbi_os_backend wince_backend;
|
||||
|
||||
extern struct list_head active_contexts_list;
|
||||
extern usbi_mutex_static_t active_contexts_lock;
|
||||
|
||||
#endif
|
||||
|
||||
+20
-13
@@ -285,10 +285,8 @@ static kern_return_t darwin_get_device (uint32_t dev_location, usb_device_t ***d
|
||||
return kIOReturnSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
|
||||
struct libusb_context *ctx = (struct libusb_context *)ptr;
|
||||
struct libusb_context *ctx;
|
||||
struct libusb_device_handle *handle;
|
||||
struct darwin_device_priv *dpriv;
|
||||
struct darwin_device_handle_priv *priv;
|
||||
@@ -311,27 +309,36 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
|
||||
continue;
|
||||
|
||||
locationValid = CFGetTypeID(locationCF) == CFNumberGetTypeID() &&
|
||||
CFNumberGetValue(locationCF, kCFNumberSInt32Type, &location);
|
||||
CFNumberGetValue(locationCF, kCFNumberSInt32Type, &location);
|
||||
|
||||
CFRelease (locationCF);
|
||||
|
||||
if (!locationValid)
|
||||
continue;
|
||||
|
||||
usbi_mutex_lock(&ctx->open_devs_lock);
|
||||
list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) {
|
||||
dpriv = (struct darwin_device_priv *)handle->dev->os_priv;
|
||||
usbi_mutex_lock(&active_contexts_lock);
|
||||
|
||||
/* the device may have been opened several times. write to each handle's event descriptor */
|
||||
if (dpriv->location == location && handle->os_priv) {
|
||||
priv = (struct darwin_device_handle_priv *)handle->os_priv;
|
||||
list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
|
||||
usbi_mutex_lock(&ctx->open_devs_lock);
|
||||
|
||||
message = MESSAGE_DEVICE_GONE;
|
||||
write (priv->fds[1], &message, sizeof (message));
|
||||
usbi_dbg ("libusb/darwin.c darwin_devices_detached: notifying context %p of device disconnect", ctx);
|
||||
|
||||
list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) {
|
||||
dpriv = (struct darwin_device_priv *)handle->dev->os_priv;
|
||||
|
||||
/* the device may have been opened several times. write to each handle's event descriptor */
|
||||
if (dpriv->location == location && handle->os_priv) {
|
||||
priv = (struct darwin_device_handle_priv *)handle->os_priv;
|
||||
|
||||
message = MESSAGE_DEVICE_GONE;
|
||||
write (priv->fds[1], &message, sizeof (message));
|
||||
}
|
||||
}
|
||||
|
||||
usbi_mutex_unlock(&ctx->open_devs_lock);
|
||||
}
|
||||
|
||||
usbi_mutex_unlock(&ctx->open_devs_lock);
|
||||
usbi_mutex_unlock(&active_contexts_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define LIBUSB_NANO 10648
|
||||
#define LIBUSB_NANO 10649
|
||||
|
||||
Reference in New Issue
Block a user