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,
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);
+ }
}
#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))
// 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 */