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:
Nathan Hjelm
2012-09-30 11:49:01 -06:00
committed by Hans de Goede
parent 2790e8f2b0
commit 913a233ec2
4 changed files with 44 additions and 14 deletions
+18
View File
@@ -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))
+5
View File
@@ -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
View File
@@ -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
View File
@@ -1 +1 @@
#define LIBUSB_NANO 10648
#define LIBUSB_NANO 10649