summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Dickens <christopher.a.dickens@gmail.com>2018-01-04 13:42:52 -0800
committerChris Dickens <christopher.a.dickens@gmail.com>2018-01-04 13:42:52 -0800
commitf06c4f5b37178afbd8752799fe44080568c2b7fb (patch)
tree22e550f9760e9033b6463eb93cd43b3f3e556d5f
parent3f69af86769c98931061357e0f96aea4c349b5cb (diff)
downloadlibusb-f06c4f5b37178afbd8752799fe44080568c2b7fb.tar.gz
Windows: Further improve thread abstraction
Adopt typedefs and inline functions to get the benefits of type checking. Convert all trivial functions to inline and remove return values where they aren't checked. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
-rw-r--r--libusb/os/threads_windows.c122
-rw-r--r--libusb/os/threads_windows.h89
-rw-r--r--libusb/version_nano.h2
3 files changed, 82 insertions, 131 deletions
diff --git a/libusb/os/threads_windows.c b/libusb/os/threads_windows.c
index 7bcb870..409c490 100644
--- a/libusb/os/threads_windows.c
+++ b/libusb/os/threads_windows.c
@@ -29,87 +29,16 @@ struct usbi_cond_perthread {
HANDLE event;
};
-int usbi_mutex_static_lock(usbi_mutex_static_t *mutex)
+void usbi_mutex_static_lock(usbi_mutex_static_t *mutex)
{
- while (InterlockedExchange(mutex, 1) == 1)
+ while (InterlockedExchange(mutex, 1L) == 1L)
SleepEx(0, TRUE);
- return 0;
}
-int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex)
-{
- InterlockedExchange(mutex, 0);
- return 0;
-}
-
-int usbi_mutex_init(usbi_mutex_t *mutex)
-{
- InitializeCriticalSection(mutex);
- return 0;
-}
-
-int usbi_mutex_lock(usbi_mutex_t *mutex)
-{
- EnterCriticalSection(mutex);
- return 0;
-}
-
-int usbi_mutex_unlock(usbi_mutex_t *mutex)
-{
- LeaveCriticalSection(mutex);
- return 0;
-}
-
-int usbi_mutex_trylock(usbi_mutex_t *mutex)
-{
- if (TryEnterCriticalSection(mutex))
- return 0;
- else
- return EBUSY;
-}
-
-int usbi_mutex_destroy(usbi_mutex_t *mutex)
-{
- DeleteCriticalSection(mutex);
- return 0;
-}
-
-int usbi_cond_init(usbi_cond_t *cond)
+void usbi_cond_init(usbi_cond_t *cond)
{
list_init(&cond->waiters);
list_init(&cond->not_waiting);
- return 0;
-}
-
-int usbi_cond_destroy(usbi_cond_t *cond)
-{
- // This assumes no one is using this anymore. The check MAY NOT BE safe.
- struct usbi_cond_perthread *pos, *next;
-
- if (!list_empty(&cond->waiters))
- return EBUSY; // (!see above!)
- list_for_each_entry_safe(pos, next, &cond->not_waiting, list, struct usbi_cond_perthread) {
- CloseHandle(pos->event);
- list_del(&pos->list);
- free(pos);
- }
- return 0;
-}
-
-int usbi_cond_broadcast(usbi_cond_t *cond)
-{
- // Assumes mutex is locked; this is not in keeping with POSIX spec, but
- // libusb does this anyway, so we simplify by not adding more sync
- // primitives to the CV definition!
- struct usbi_cond_perthread *pos;
- int r = 0;
-
- list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread) {
- if (!SetEvent(pos->event))
- r = EINVAL;
- }
- // The wait function will remove its respective item from the list.
- return r;
}
static int usbi_cond_intwait(usbi_cond_t *cond,
@@ -170,37 +99,28 @@ int usbi_cond_timedwait(usbi_cond_t *cond,
return usbi_cond_intwait(cond, mutex, millis);
}
-int usbi_tls_key_create(usbi_tls_key_t *key)
-{
- *key = TlsAlloc();
- if (*key == TLS_OUT_OF_INDEXES)
- return ENOMEM;
- else
- return 0;
-}
-
-void *usbi_tls_key_get(usbi_tls_key_t key)
+void usbi_cond_broadcast(usbi_cond_t *cond)
{
- return TlsGetValue(key);
-}
+ // Assumes mutex is locked; this is not in keeping with POSIX spec, but
+ // libusb does this anyway, so we simplify by not adding more sync
+ // primitives to the CV definition!
+ struct usbi_cond_perthread *pos;
-int usbi_tls_key_set(usbi_tls_key_t key, void *value)
-{
- if (TlsSetValue(key, value))
- return 0;
- else
- return EINVAL;
+ list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread)
+ SetEvent(pos->event);
+ // The wait function will remove its respective item from the list.
}
-int usbi_tls_key_delete(usbi_tls_key_t key)
+void usbi_cond_destroy(usbi_cond_t *cond)
{
- if (TlsFree(key))
- return 0;
- else
- return EINVAL;
-}
+ // This assumes no one is using this anymore. The check MAY NOT BE safe.
+ struct usbi_cond_perthread *pos, *next;
-int usbi_get_tid(void)
-{
- return (int)GetCurrentThreadId();
+ if (!list_empty(&cond->waiters))
+ return; // (!see above!)
+ list_for_each_entry_safe(pos, next, &cond->not_waiting, list, struct usbi_cond_perthread) {
+ CloseHandle(pos->event);
+ list_del(&pos->list);
+ free(pos);
+ }
}
diff --git a/libusb/os/threads_windows.h b/libusb/os/threads_windows.h
index 288b3b4..630dcab 100644
--- a/libusb/os/threads_windows.h
+++ b/libusb/os/threads_windows.h
@@ -21,17 +21,36 @@
#ifndef LIBUSB_THREADS_WINDOWS_H
#define LIBUSB_THREADS_WINDOWS_H
-#define usbi_mutex_static_t volatile LONG
-#define USBI_MUTEX_INITIALIZER 0
+#define USBI_MUTEX_INITIALIZER 0L
+typedef volatile LONG usbi_mutex_static_t;
+void usbi_mutex_static_lock(usbi_mutex_static_t *mutex);
+static inline void usbi_mutex_static_unlock(usbi_mutex_static_t *mutex)
+{
+ InterlockedExchange(mutex, 0L);
+}
-#define usbi_mutex_t CRITICAL_SECTION
-
-typedef struct usbi_cond {
- // Every time a thread touches the CV, it winds up in one of these lists.
- // It stays there until the CV is destroyed, even if the thread terminates.
- struct list_head waiters;
- struct list_head not_waiting;
-} usbi_cond_t;
+typedef CRITICAL_SECTION usbi_mutex_t;
+static inline int usbi_mutex_init(usbi_mutex_t *mutex)
+{
+ InitializeCriticalSection(mutex);
+ return 0;
+}
+static inline void usbi_mutex_lock(usbi_mutex_t *mutex)
+{
+ EnterCriticalSection(mutex);
+}
+static inline void usbi_mutex_unlock(usbi_mutex_t *mutex)
+{
+ LeaveCriticalSection(mutex);
+}
+static inline int usbi_mutex_trylock(usbi_mutex_t *mutex)
+{
+ return !TryEnterCriticalSection(mutex);
+}
+static inline void usbi_mutex_destroy(usbi_mutex_t *mutex)
+{
+ DeleteCriticalSection(mutex);
+}
// We *were* getting timespec from pthread.h:
#if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED))
@@ -45,32 +64,44 @@ struct timespec {
// We *were* getting ETIMEDOUT from pthread.h:
#ifndef ETIMEDOUT
-# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
+#define ETIMEDOUT 10060 /* This is the value in winsock.h. */
#endif
-#define usbi_tls_key_t DWORD
-
-int usbi_mutex_static_lock(usbi_mutex_static_t *mutex);
-int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex);
-
-int usbi_mutex_init(usbi_mutex_t *mutex);
-int usbi_mutex_lock(usbi_mutex_t *mutex);
-int usbi_mutex_unlock(usbi_mutex_t *mutex);
-int usbi_mutex_trylock(usbi_mutex_t *mutex);
-int usbi_mutex_destroy(usbi_mutex_t *mutex);
+typedef struct usbi_cond {
+ // Every time a thread touches the CV, it winds up in one of these lists.
+ // It stays there until the CV is destroyed, even if the thread terminates.
+ struct list_head waiters;
+ struct list_head not_waiting;
+} usbi_cond_t;
-int usbi_cond_init(usbi_cond_t *cond);
+void usbi_cond_init(usbi_cond_t *cond);
int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex);
int usbi_cond_timedwait(usbi_cond_t *cond,
usbi_mutex_t *mutex, const struct timeval *tv);
-int usbi_cond_broadcast(usbi_cond_t *cond);
-int usbi_cond_destroy(usbi_cond_t *cond);
+void usbi_cond_broadcast(usbi_cond_t *cond);
+void usbi_cond_destroy(usbi_cond_t *cond);
-int usbi_tls_key_create(usbi_tls_key_t *key);
-void *usbi_tls_key_get(usbi_tls_key_t key);
-int usbi_tls_key_set(usbi_tls_key_t key, void *value);
-int usbi_tls_key_delete(usbi_tls_key_t key);
+typedef DWORD usbi_tls_key_t;
+static inline void usbi_tls_key_create(usbi_tls_key_t *key)
+{
+ *key = TlsAlloc();
+}
+static inline void *usbi_tls_key_get(usbi_tls_key_t key)
+{
+ return TlsGetValue(key);
+}
+static inline void usbi_tls_key_set(usbi_tls_key_t key, void *ptr)
+{
+ (void)TlsSetValue(key, ptr);
+}
+static inline void usbi_tls_key_delete(usbi_tls_key_t key)
+{
+ (void)TlsFree(key);
+}
-int usbi_get_tid(void);
+static inline int usbi_get_tid(void)
+{
+ return (int)GetCurrentThreadId();
+}
#endif /* LIBUSB_THREADS_WINDOWS_H */
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 3dadd03..3272eae 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11250
+#define LIBUSB_NANO 11251