summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_pthread.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_pthread.h')
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_pthread.h174
1 files changed, 174 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_pthread.h b/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_pthread.h
new file mode 100644
index 0000000..0abe733
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_pthread.h
@@ -0,0 +1,174 @@
1/*******************************************************
2 HIDAPI - Multi-Platform library for
3 communication with HID devices.
4
5 Alan Ott
6 Signal 11 Software
7
8 libusb/hidapi Team
9
10 Sam Lantinga
11
12 Copyright 2023, All Rights Reserved.
13
14 At the discretion of the user of this library,
15 this software may be licensed under the terms of the
16 GNU General Public License v3, a BSD-Style license, or the
17 original HIDAPI license as outlined in the LICENSE.txt,
18 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
19 files located at the root of the source distribution.
20 These files may also be found in the public source
21 code repository located at:
22 https://github.com/libusb/hidapi .
23********************************************************/
24
25#include <pthread.h>
26
27#if defined(__ANDROID__) && __ANDROID_API__ < __ANDROID_API_N__
28
29/* Barrier implementation because Android/Bionic don't have pthread_barrier.
30 This implementation came from Brent Priddy and was posted on
31 StackOverflow. It is used with his permission. */
32typedef int pthread_barrierattr_t;
33typedef struct pthread_barrier {
34 pthread_mutex_t mutex;
35 pthread_cond_t cond;
36 int count;
37 int trip_count;
38} pthread_barrier_t;
39
40static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
41{
42 if(count == 0) {
43 errno = EINVAL;
44 return -1;
45 }
46
47 if(pthread_mutex_init(&barrier->mutex, 0) < 0) {
48 return -1;
49 }
50 if(pthread_cond_init(&barrier->cond, 0) < 0) {
51 pthread_mutex_destroy(&barrier->mutex);
52 return -1;
53 }
54 barrier->trip_count = count;
55 barrier->count = 0;
56
57 return 0;
58}
59
60static int pthread_barrier_destroy(pthread_barrier_t *barrier)
61{
62 pthread_cond_destroy(&barrier->cond);
63 pthread_mutex_destroy(&barrier->mutex);
64 return 0;
65}
66
67static int pthread_barrier_wait(pthread_barrier_t *barrier)
68{
69 pthread_mutex_lock(&barrier->mutex);
70 ++(barrier->count);
71 if(barrier->count >= barrier->trip_count) {
72 barrier->count = 0;
73 pthread_cond_broadcast(&barrier->cond);
74 pthread_mutex_unlock(&barrier->mutex);
75 return 1;
76 }
77 else {
78 pthread_cond_wait(&barrier->cond, &(barrier->mutex));
79 pthread_mutex_unlock(&barrier->mutex);
80 return 0;
81 }
82}
83
84#endif
85
86#define HIDAPI_THREAD_TIMED_OUT ETIMEDOUT
87
88typedef struct timespec hidapi_timespec;
89
90typedef struct
91{
92 pthread_t thread;
93 pthread_mutex_t mutex; /* Protects input_reports */
94 pthread_cond_t condition;
95 pthread_barrier_t barrier; /* Ensures correct startup sequence */
96
97} hidapi_thread_state;
98
99static void hidapi_thread_state_init(hidapi_thread_state *state)
100{
101 pthread_mutex_init(&state->mutex, NULL);
102 pthread_cond_init(&state->condition, NULL);
103 pthread_barrier_init(&state->barrier, NULL, 2);
104}
105
106static void hidapi_thread_state_destroy(hidapi_thread_state *state)
107{
108 pthread_barrier_destroy(&state->barrier);
109 pthread_cond_destroy(&state->condition);
110 pthread_mutex_destroy(&state->mutex);
111}
112
113#define hidapi_thread_cleanup_push pthread_cleanup_push
114#define hidapi_thread_cleanup_pop pthread_cleanup_pop
115
116static void hidapi_thread_mutex_lock(hidapi_thread_state *state)
117{
118 pthread_mutex_lock(&state->mutex);
119}
120
121static void hidapi_thread_mutex_unlock(hidapi_thread_state *state)
122{
123 pthread_mutex_unlock(&state->mutex);
124}
125
126static void hidapi_thread_cond_wait(hidapi_thread_state *state)
127{
128 pthread_cond_wait(&state->condition, &state->mutex);
129}
130
131static int hidapi_thread_cond_timedwait(hidapi_thread_state *state, hidapi_timespec *ts)
132{
133 return pthread_cond_timedwait(&state->condition, &state->mutex, ts);
134}
135
136static void hidapi_thread_cond_signal(hidapi_thread_state *state)
137{
138 pthread_cond_signal(&state->condition);
139}
140
141static void hidapi_thread_cond_broadcast(hidapi_thread_state *state)
142{
143 pthread_cond_broadcast(&state->condition);
144}
145
146static void hidapi_thread_barrier_wait(hidapi_thread_state *state)
147{
148 pthread_barrier_wait(&state->barrier);
149}
150
151static void hidapi_thread_create(hidapi_thread_state *state, void *(*func)(void*), void *func_arg)
152{
153 pthread_create(&state->thread, NULL, func, func_arg);
154}
155
156static void hidapi_thread_join(hidapi_thread_state *state)
157{
158 pthread_join(state->thread, NULL);
159}
160
161static void hidapi_thread_gettime(hidapi_timespec *ts)
162{
163 clock_gettime(CLOCK_REALTIME, ts);
164}
165
166static void hidapi_thread_addtime(hidapi_timespec *ts, int milliseconds)
167{
168 ts->tv_sec += milliseconds / 1000;
169 ts->tv_nsec += (milliseconds % 1000) * 1000000;
170 if (ts->tv_nsec >= 1000000000L) {
171 ts->tv_sec++;
172 ts->tv_nsec -= 1000000000L;
173 }
174}