diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -624,7 +624,7 @@ { libusb_context *ctx = dev->ctx; struct libusb20_device *pdev = dev->os_priv; - int err; + int fd, err; if (devh == NULL) return (LIBUSB_ERROR_INVALID_PARAM); @@ -642,6 +642,19 @@ return (LIBUSB_ERROR_NO_MEM); } + /* + * Place an advisory lock on the device. + * If this fails, some other process did so first. + * Closing the device clears the lock. + */ + fd = libusb20_dev_get_fd(pdev); + err = flock(fd, LOCK_EX|LOCK_NB); + if (err) { + libusb20_dev_close(pdev); + libusb_unref_device(dev); + return (LIBUSB_ERROR_ACCESS); + } + /* * Clear the device gone flag, in case the device was opened * after a re-attach, to allow new transaction: @@ -650,7 +663,7 @@ dev->device_is_gone = 0; CTX_UNLOCK(ctx); - libusb10_add_pollfd(ctx, &dev->dev_poll, pdev, libusb20_dev_get_fd(pdev), POLLIN | + libusb10_add_pollfd(ctx, &dev->dev_poll, pdev, fd, POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM); /* make sure our event loop detects the new device */ @@ -670,6 +683,7 @@ struct LIBUSB20_DEVICE_DESC_DECODED *pdesc; int i; int j; + int ok; ctx = GET_CONTEXT(ctx); if (ctx == NULL) @@ -693,8 +707,12 @@ */ if (pdesc->idVendor == vendor_id && pdesc->idProduct == product_id) { - libusb_open(devs[j], &pdev); - break; + ok = libusb_open(devs[j], &pdev); + /* + *if this fails, try the next one. + */ + if (ok == 0) + break; } }