Skip to content

Commit

Permalink
darwin: Use atomic for in_reenumerate flag
Browse files Browse the repository at this point in the history
Signed-off-by: Tormod Volden <[email protected]>
  • Loading branch information
tormodvolden committed Jul 28, 2024
1 parent c3873d5 commit 9ed9eb3
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 13 deletions.
21 changes: 9 additions & 12 deletions libusb/os/darwin_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,9 +611,8 @@ static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
process_new_device (ctx, cached_device, old_session_id);
}

if (cached_device->in_reenumerate) {
if (atomic_exchange(&cached_device->in_reenumerate, false)) {
usbi_dbg (NULL, "cached device in reset state. reset complete...");
cached_device->in_reenumerate = false;
}

IOObjectRelease(service);
Expand Down Expand Up @@ -649,7 +648,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
usbi_mutex_lock(&darwin_cached_devices_mutex);
list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
if (old_device->session == session) {
if (old_device->in_reenumerate) {
if (atomic_load(&old_device->in_reenumerate)) {
/* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
* will deref if needed. */
usbi_dbg (NULL, "detected device detached due to re-enumeration. sessionID: 0x%" PRIx64
Expand Down Expand Up @@ -1290,7 +1289,7 @@ static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io
list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
usbi_dbg(ctx, "matching sessionID/locationID 0x%" PRIx64 "/0x%" PRIx32 " against cached device with sessionID/locationID 0x%" PRIx64 "/0x%" PRIx32,
sessionID, locationID, new_device->session, new_device->location);
if (new_device->location == locationID && new_device->in_reenumerate) {
if (new_device->location == locationID && atomic_load(&new_device->in_reenumerate)) {
usbi_dbg (ctx, "found cached device with matching location that is being re-enumerated");
*old_session_id = new_device->session;
break;
Expand Down Expand Up @@ -1454,7 +1453,7 @@ static enum libusb_error process_new_device (struct libusb_context *ctx, struct

} while (0);

if (!cached_device->in_reenumerate && 0 == ret) {
if (!atomic_load(&cached_device->in_reenumerate) && 0 == ret) {
usbi_connect_device (dev);
} else {
libusb_unref_device (dev);
Expand Down Expand Up @@ -2055,13 +2054,11 @@ static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, b

struct libusb_context *ctx = HANDLE_CTX (dev_handle);

if (dpriv->in_reenumerate) {
if (atomic_exchange(&dpriv->in_reenumerate, true)) {
/* ack, two (or more) threads are trying to reset the device! abort! */
return LIBUSB_ERROR_NOT_FOUND;
}

dpriv->in_reenumerate = true;

/* store copies of descriptors so they can be compared after the reset */
memcpy (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor));
cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
Expand All @@ -2086,14 +2083,14 @@ static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, b
kresult = (*dpriv->device)->USBDeviceReEnumerate (dpriv->device, options);
if (kresult != kIOReturnSuccess) {
usbi_err (ctx, "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
dpriv->in_reenumerate = false;
atomic_store(&dpriv->in_reenumerate, false);
return darwin_to_libusb (kresult);
}

/* capture mode does not re-enumerate but it does require re-open */
if (capture) {
usbi_dbg (ctx, "darwin/reenumerate_device: restoring state...");
dpriv->in_reenumerate = false;
atomic_store(&dpriv->in_reenumerate, false);
return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
}

Expand All @@ -2102,7 +2099,7 @@ static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, b
struct timespec start;
usbi_get_monotonic_time(&start);

while (dpriv->in_reenumerate) {
while (atomic_load(&dpriv->in_reenumerate)) {
struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
nanosleep (&delay, NULL);

Expand All @@ -2115,7 +2112,7 @@ static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, b

if (elapsed_us >= DARWIN_REENUMERATE_TIMEOUT_US) {
usbi_err (ctx, "darwin/reenumerate_device: timeout waiting for reenumerate");
dpriv->in_reenumerate = false;
atomic_store(&dpriv->in_reenumerate, false);
return LIBUSB_ERROR_TIMEOUT;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libusb/os/darwin_usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ struct darwin_cached_device {
UInt8 first_config, active_config, port;
int can_enumerate;
int refcount;
bool in_reenumerate;
atomic_bool in_reenumerate;
int capture_count;
};

Expand Down

0 comments on commit 9ed9eb3

Please sign in to comment.