From: Daniel Drake Date: Fri, 18 Apr 2008 22:42:40 +0000 (+0100) Subject: mutex protection for device and handle lists X-Git-Tag: upstream/1.0.21~1100 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0efd2efa65d5513e5754d717d522b2c5c45332e2;p=platform%2Fupstream%2Flibusb.git mutex protection for device and handle lists --- diff --git a/libusb/core.c b/libusb/core.c index f90ea06..3bce9a1 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -37,7 +37,10 @@ const struct usbi_os_backend * const usbi_backend = &linux_usbfs_backend; #endif static struct list_head usb_devs; +static pthread_mutex_t usb_devs_lock = PTHREAD_MUTEX_INITIALIZER; + struct list_head usbi_open_devs; +pthread_mutex_t usbi_open_devs_lock = PTHREAD_MUTEX_INITIALIZER; /** * \mainpage libusb-1.0 API Reference @@ -237,20 +240,28 @@ struct libusb_device *usbi_alloc_device(unsigned long session_id) dev->refcnt = 1; dev->session_data = session_id; - list_add(&dev->list, &usb_devs); memset(&dev->os_priv, 0, priv_size); + + pthread_mutex_lock(&usb_devs_lock); + list_add(&dev->list, &usb_devs); + pthread_mutex_unlock(&usb_devs_lock); return dev; } struct libusb_device *usbi_get_device_by_session_id(unsigned long session_id) { struct libusb_device *dev; + struct libusb_device *ret = NULL; + pthread_mutex_lock(&usb_devs_lock); list_for_each_entry(dev, &usb_devs, list) - if (dev->session_data == session_id) - return dev; + if (dev->session_data == session_id) { + ret = dev; + break; + } + pthread_mutex_unlock(&usb_devs_lock); - return NULL; + return ret; } /** @ingroup dev @@ -354,7 +365,10 @@ API_EXPORTED void libusb_device_unref(struct libusb_device *dev) if (usbi_backend->destroy_device) usbi_backend->destroy_device(dev); + pthread_mutex_lock(&usb_devs_lock); list_del(&dev->list); + pthread_mutex_unlock(&usb_devs_lock); + if (dev->config) free(dev->config); free(dev); @@ -392,7 +406,9 @@ API_EXPORTED struct libusb_device_handle *libusb_open(struct libusb_device *dev) return NULL; } + pthread_mutex_lock(&usbi_open_devs_lock); list_add(&handle->list, &usbi_open_devs); + pthread_mutex_unlock(&usbi_open_devs_lock); return handle; } @@ -460,7 +476,10 @@ API_EXPORTED void libusb_close(struct libusb_device_handle *dev_handle) return; usbi_dbg(""); + pthread_mutex_lock(&usbi_open_devs_lock); list_del(&dev_handle->list); + pthread_mutex_unlock(&usbi_open_devs_lock); + do_close(dev_handle); free(dev_handle); } @@ -545,12 +564,16 @@ API_EXPORTED void libusb_exit(void) { struct libusb_device_handle *devh; usbi_dbg(""); + + pthread_mutex_lock(&usbi_open_devs_lock); if (!list_empty(&usbi_open_devs)) { usbi_dbg("naughty app left some devices open!\n"); list_for_each_entry(devh, &usbi_open_devs, list) do_close(devh); /* FIXME where do the open handles get freed? */ } + pthread_mutex_unlock(&usbi_open_devs_lock); + if (usbi_backend->exit) usbi_backend->exit(); } diff --git a/libusb/io.c b/libusb/io.c index 5e0e92f..18ab594 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -624,12 +624,14 @@ out: static int submit_transfer(struct usbi_transfer *itransfer) { - int r = usbi_backend->submit_transfer(itransfer); + int r; + + add_to_flying_list(itransfer); + r = usbi_backend->submit_transfer(itransfer); if (r < 0) - return r; + list_del(&itransfer->list); - add_to_flying_list(itransfer); - return 0; + return r; } /** \ingroup asyncio diff --git a/libusb/libusbi.h b/libusb/libusbi.h index c589ef6..19b28b6 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -206,6 +207,7 @@ struct usb_descriptor_header { /* shared data and functions */ extern struct list_head usbi_open_devs; +extern pthread_mutex_t usbi_open_devs_lock; void usbi_io_init(void); diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index 550fa08..2504fea 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -1036,8 +1037,9 @@ static int reap_for_handle(struct libusb_device_handle *handle) static int op_handle_events(fd_set *readfds, fd_set *writefds) { struct libusb_device_handle *handle; - int r; + int r = 0; + pthread_mutex_lock(&usbi_open_devs_lock); list_for_each_entry(handle, &usbi_open_devs, list) { struct linux_device_handle_priv *hpriv = __device_handle_priv(handle); if (!FD_ISSET(hpriv->fd, writefds)) @@ -1046,10 +1048,13 @@ static int op_handle_events(fd_set *readfds, fd_set *writefds) if (r == -1 && errno == EAGAIN) continue; if (r < 0) - return r; + goto out; } - return 0; + r = 0; +out: + pthread_mutex_unlock(&usbi_open_devs_lock); + return r; } const struct usbi_os_backend linux_usbfs_backend = {