summaryrefslogtreecommitdiff
path: root/libusb/os
diff options
context:
space:
mode:
authorVitali Lovich <vlovich@aliph.com>2011-03-16 19:43:30 -0700
committerPeter Stuge <peter@stuge.se>2011-07-24 22:29:09 +0200
commit74282582cc879f091ad1d847411337bc3fa78a2b (patch)
treeb90980dff598e1b026c7cd22fc27037ed0419fa8 /libusb/os
parent8f1bc0659136faf312dabe8fe67380a798299d33 (diff)
downloadlibusb-74282582cc879f091ad1d847411337bc3fa78a2b.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]
Diffstat (limited to 'libusb/os')
-rw-r--r--libusb/os/threads_posix.c55
-rw-r--r--libusb/os/threads_posix.h2
-rw-r--r--libusb/os/threads_windows.h2
3 files changed, 59 insertions, 0 deletions
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);