summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitali Lovich <vlovich@aliph.com>2011-03-16 19:43:30 -0700
committerPeter Stuge <peter@stuge.se>2011-06-15 02:45:20 +0200
commit1ac6183419412f6efe56cf24a7270eaef95bf430 (patch)
tree7e11dd66db72c9ed56c3c286f71ea2318ce35e13
parentfd9c3cf13ca124a8b44d331b2578318baa92d976 (diff)
downloadlibusb-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.am4
-rw-r--r--libusb/os/threads_posix.c55
-rw-r--r--libusb/os/threads_posix.h2
-rw-r--r--libusb/os/threads_windows.h2
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);