summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_sdl.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_sdl.h')
-rw-r--r--contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_sdl.h202
1 files changed, 202 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_sdl.h b/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_sdl.h
new file mode 100644
index 0000000..1f5c7db
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/hidapi/libusb/hidapi_thread_sdl.h
@@ -0,0 +1,202 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22/* Barrier implementation because Android/Bionic don't have pthread_barrier.
23 This implementation came from Brent Priddy and was posted on
24 StackOverflow. It is used with his permission. */
25
26typedef struct _SDL_ThreadBarrier
27{
28 SDL_Mutex *mutex;
29 SDL_Condition *cond;
30 Uint32 count;
31 Uint32 trip_count;
32} SDL_ThreadBarrier;
33
34static int SDL_CreateThreadBarrier(SDL_ThreadBarrier *barrier, Uint32 count)
35{
36 SDL_assert(barrier != NULL);
37 SDL_assert(count != 0);
38
39 barrier->mutex = SDL_CreateMutex();
40 if (barrier->mutex == NULL) {
41 return -1; /* Error set by CreateMutex */
42 }
43 barrier->cond = SDL_CreateCondition();
44 if (barrier->cond == NULL) {
45 return -1; /* Error set by CreateCond */
46 }
47
48 barrier->trip_count = count;
49 barrier->count = 0;
50
51 return 0;
52}
53
54static void SDL_DestroyThreadBarrier(SDL_ThreadBarrier *barrier)
55{
56 SDL_DestroyCondition(barrier->cond);
57 SDL_DestroyMutex(barrier->mutex);
58}
59
60static int SDL_WaitThreadBarrier(SDL_ThreadBarrier *barrier)
61{
62 SDL_LockMutex(barrier->mutex);
63 barrier->count += 1;
64 if (barrier->count >= barrier->trip_count) {
65 barrier->count = 0;
66 SDL_BroadcastCondition(barrier->cond);
67 SDL_UnlockMutex(barrier->mutex);
68 return 1;
69 }
70 SDL_WaitCondition(barrier->cond, barrier->mutex);
71 SDL_UnlockMutex(barrier->mutex);
72 return 0;
73}
74
75#include "../../thread/SDL_systhread.h"
76
77#define HIDAPI_THREAD_TIMED_OUT 1
78
79typedef Uint64 hidapi_timespec;
80
81typedef struct
82{
83 SDL_Thread *thread;
84 SDL_Mutex *mutex; /* Protects input_reports */
85 SDL_Condition *condition;
86 SDL_ThreadBarrier barrier; /* Ensures correct startup sequence */
87
88} hidapi_thread_state;
89
90static void hidapi_thread_state_init(hidapi_thread_state *state)
91{
92 state->mutex = SDL_CreateMutex();
93 state->condition = SDL_CreateCondition();
94 SDL_CreateThreadBarrier(&state->barrier, 2);
95}
96
97static void hidapi_thread_state_destroy(hidapi_thread_state *state)
98{
99 SDL_DestroyThreadBarrier(&state->barrier);
100 SDL_DestroyCondition(state->condition);
101 SDL_DestroyMutex(state->mutex);
102}
103
104static void hidapi_thread_cleanup_push(void (*routine)(void *), void *arg)
105{
106 /* There isn't an equivalent in SDL, and it's only useful for threads calling hid_read_timeout() */
107}
108
109static void hidapi_thread_cleanup_pop(int execute)
110{
111}
112
113static void hidapi_thread_mutex_lock(hidapi_thread_state *state)
114{
115 SDL_LockMutex(state->mutex);
116}
117
118static void hidapi_thread_mutex_unlock(hidapi_thread_state *state)
119{
120 SDL_UnlockMutex(state->mutex);
121}
122
123static void hidapi_thread_cond_wait(hidapi_thread_state *state)
124{
125 SDL_WaitCondition(state->condition, state->mutex);
126}
127
128static int hidapi_thread_cond_timedwait(hidapi_thread_state *state, hidapi_timespec *ts)
129{
130 Sint64 timeout_ns;
131 Sint32 timeout_ms;
132
133 timeout_ns = (Sint64)(*ts - SDL_GetTicksNS());
134 if (timeout_ns <= 0) {
135 timeout_ms = 0;
136 } else {
137 timeout_ms = (Sint32)SDL_NS_TO_MS(timeout_ns);
138 }
139 if (SDL_WaitConditionTimeout(state->condition, state->mutex, timeout_ms)) {
140 return 0;
141 } else {
142 return HIDAPI_THREAD_TIMED_OUT;
143 }
144}
145
146static void hidapi_thread_cond_signal(hidapi_thread_state *state)
147{
148 SDL_SignalCondition(state->condition);
149}
150
151static void hidapi_thread_cond_broadcast(hidapi_thread_state *state)
152{
153 SDL_BroadcastCondition(state->condition);
154}
155
156static void hidapi_thread_barrier_wait(hidapi_thread_state *state)
157{
158 SDL_WaitThreadBarrier(&state->barrier);
159}
160
161typedef struct
162{
163 void *(*func)(void*);
164 void *func_arg;
165
166} RunInputThreadParam;
167
168static int RunInputThread(void *param)
169{
170 RunInputThreadParam *data = (RunInputThreadParam *)param;
171 void *(*func)(void*) = data->func;
172 void *func_arg = data->func_arg;
173 SDL_free(data);
174 func(func_arg);
175 return 0;
176}
177
178static void hidapi_thread_create(hidapi_thread_state *state, void *(*func)(void*), void *func_arg)
179{
180 RunInputThreadParam *param = (RunInputThreadParam *)malloc(sizeof(*param));
181 /* Note that the hidapi code didn't check for thread creation failure.
182 * We'll crash if malloc() fails
183 */
184 param->func = func;
185 param->func_arg = func_arg;
186 state->thread = SDL_CreateThread(RunInputThread, "libusb", param);
187}
188
189static void hidapi_thread_join(hidapi_thread_state *state)
190{
191 SDL_WaitThread(state->thread, NULL);
192}
193
194static void hidapi_thread_gettime(hidapi_timespec *ts)
195{
196 *ts = SDL_GetTicksNS();
197}
198
199static void hidapi_thread_addtime(hidapi_timespec *ts, int milliseconds)
200{
201 *ts += SDL_MS_TO_NS(milliseconds);
202}