Atlas - hidapi_thread_sdl.h
Home / ext / SDL / src / hidapi / libusb Lines: 1 | Size: 5519 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 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} 203[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.