diff options
author | Vitali Lovich <vlovich@aliph.com> | 2011-03-16 19:43:30 -0700 |
---|---|---|
committer | Peter Stuge <peter@stuge.se> | 2011-06-15 02:45:20 +0200 |
commit | 1ac6183419412f6efe56cf24a7270eaef95bf430 (patch) | |
tree | 7e11dd66db72c9ed56c3c286f71ea2318ce35e13 | |
parent | fd9c3cf13ca124a8b44d331b2578318baa92d976 (diff) | |
download | libusb-1ac6183419412f6efe56cf24a7270eaef95bf430.tar.gz |
Add recursive mutexes to threading abstraction
This is necessary for the device close path which needs to attain the
events lock, but which might itself be called while handling an event.
The events lock is necessary to properly clean up transfers which might
still be pointing to the device. References #82.
[stuge: Move usbi_mutex_init_recursive() into threads_posix.c]
[stuge: Must also #define _XOPEN_SOURCE 500 to be able to build]
[pbatard: Un-inline usbi_mutex_init_recursive() to make Cygwin happy]
-rw-r--r-- | libusb/Makefile.am | 4 | ||||
-rw-r--r-- | libusb/os/threads_posix.c | 55 | ||||
-rw-r--r-- | libusb/os/threads_posix.h | 2 | ||||
-rw-r--r-- | libusb/os/threads_windows.h | 2 |
4 files changed, 61 insertions, 2 deletions
diff --git a/libusb/Makefile.am b/libusb/Makefile.am index 0428830..22661dc 100644 --- a/libusb/Makefile.am +++ b/libusb/Makefile.am @@ -5,7 +5,7 @@ DARWIN_USB_SRC = os/darwin_usb.c WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(WINDOWS_USB_SRC) \ - os/threads_windows.c + os/threads_posix.c os/threads_windows.c if OS_LINUX OS_SRC = $(LINUX_USBFS_SRC) @@ -24,7 +24,7 @@ OS_SRC = $(WINDOWS_USB_SRC) endif if THREADS_POSIX -THREADS_SRC = os/threads_posix.h +THREADS_SRC = os/threads_posix.h os/threads_posix.c else THREADS_SRC = os/threads_windows.h os/threads_windows.c endif diff --git a/libusb/os/threads_posix.c b/libusb/os/threads_posix.c new file mode 100644 index 0000000..435b873 --- /dev/null +++ b/libusb/os/threads_posix.c @@ -0,0 +1,55 @@ +/* + * libusb synchronization using POSIX Threads + * + * Copyright (C) 2011 Vitali Lovich <vlovich@aliph.com> + * Copyright (C) 2011 Peter Stuge <peter@stuge.se> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef _XOPEN_SOURCE +# if _XOPEN_SOURCE < 500 +# undef _XOPEN_SOURCE +# define _XOPEN_SOURCE 500 +# endif +#else +#define _XOPEN_SOURCE 500 +#endif /* _XOPEN_SOURCE */ + +#include <pthread.h> + +int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr) +{ + int err; + pthread_mutexattr_t stack_attr; + if (!attr) { + attr = &stack_attr; + err = pthread_mutexattr_init(&stack_attr); + if (err != 0) + return err; + } + + err = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE); + if (err != 0) + goto finish; + + err = pthread_mutex_init(mutex, attr); + +finish: + if (attr == &stack_attr) + pthread_mutexattr_destroy(&stack_attr); + + return err; +} diff --git a/libusb/os/threads_posix.h b/libusb/os/threads_posix.h index 86e0f88..b9a902e 100644 --- a/libusb/os/threads_posix.h +++ b/libusb/os/threads_posix.h @@ -43,4 +43,6 @@ #define usbi_cond_destroy pthread_cond_destroy #define usbi_cond_signal pthread_cond_signal +extern int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr); + #endif /* __LIBUSB_THREADS_POSIX_H__ */ diff --git a/libusb/os/threads_windows.h b/libusb/os/threads_windows.h index 2cd1867..34ae64c 100644 --- a/libusb/os/threads_windows.h +++ b/libusb/os/threads_windows.h @@ -58,6 +58,8 @@ struct timespec { #define usbi_mutexattr_t void #define usbi_condattr_t void +// all Windows mutexes are recursive +#define usbi_mutex_init_recursive(mutex, attr) usbi_mutex_init((mutex), (attr)) int usbi_mutex_static_lock(usbi_mutex_static_t *mutex); int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex); |