{
size_t priv_size = usbi_backend->device_priv_size;
struct libusb_device *dev = malloc(sizeof(*dev) + priv_size);
+ int r;
+
if (!dev)
return NULL;
+ r = pthread_mutex_init(&dev->lock, NULL);
+ if (r)
+ return NULL;
+
dev->refcnt = 1;
dev->session_data = session_id;
memset(&dev->os_priv, 0, priv_size);
*/
API_EXPORTED struct libusb_device *libusb_device_ref(struct libusb_device *dev)
{
+ pthread_mutex_lock(&dev->lock);
dev->refcnt++;
+ pthread_mutex_unlock(&dev->lock);
return dev;
}
*/
API_EXPORTED void libusb_device_unref(struct libusb_device *dev)
{
+ int refcnt;
+
if (!dev)
return;
- if (--dev->refcnt == 0) {
+ pthread_mutex_lock(&dev->lock);
+ refcnt = --dev->refcnt;
+ pthread_mutex_unlock(&dev->lock);
+
+ if (refcnt == 0) {
usbi_dbg("destroy device %04x:%04x", dev->desc.idVendor,
dev->desc.idProduct);
#define usbi_err(fmt...) _usbi_log(LOG_LEVEL_ERROR, fmt)
struct libusb_device {
- struct list_head list;
+ /* lock protects refcnt, everything else is finalized at initialization
+ * time */
+ pthread_mutex_t lock;
int refcnt;
+
+ struct list_head list;
unsigned long session_data;
struct libusb_device_descriptor desc;
struct libusb_config_descriptor *config;