diff options
author | Daniel Drake <dsd@gentoo.org> | 2008-04-18 23:58:54 +0100 |
---|---|---|
committer | Daniel Drake <dsd@gentoo.org> | 2008-04-18 23:58:54 +0100 |
commit | 1fcdb0678b759569db7cd530457dbc0a5f86fb1d (patch) | |
tree | 40772dd266cf198b3ca87d03b0d28491664455e1 | |
parent | 0efd2efa65d5513e5754d717d522b2c5c45332e2 (diff) | |
download | libusb-1fcdb0678b759569db7cd530457dbc0a5f86fb1d.tar.gz |
libusb_device mutex protection
-rw-r--r-- | libusb/core.c | 16 | ||||
-rw-r--r-- | libusb/libusbi.h | 6 |
2 files changed, 20 insertions, 2 deletions
diff --git a/libusb/core.c b/libusb/core.c index 3bce9a1..450c5fb 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -235,9 +235,15 @@ struct libusb_device *usbi_alloc_device(unsigned long session_id) { 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); @@ -344,7 +350,9 @@ API_EXPORTED void libusb_free_device_list(struct libusb_device **list, */ 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; } @@ -355,10 +363,16 @@ API_EXPORTED struct libusb_device *libusb_device_ref(struct libusb_device *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); diff --git a/libusb/libusbi.h b/libusb/libusbi.h index 19b28b6..7436491 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -143,8 +143,12 @@ void usbi_log(enum usbi_log_level, const char *function, const char *format, ... #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; |