20
20
https://github.com/libusb/hidapi .
21
21
********************************************************/
22
22
23
+ #ifndef HIDAPI_USING_SDL_RUNTIME
23
24
#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
24
25
25
26
/* C */
37
38
#include <sys/ioctl.h>
38
39
#include <sys/utsname.h>
39
40
#include <fcntl.h>
40
- #include <pthread.h>
41
41
#include <wchar.h>
42
42
43
43
/* GNU / LibUSB */
48
48
#define ICONV_CONST
49
49
#endif
50
50
#endif
51
+ #endif /* HIDAPI_USING_SDL_RUNTIME */
51
52
52
53
#include "hidapi_libusb.h"
53
54
55
+ #ifdef __cplusplus
56
+ extern "C" {
57
+ #endif
58
+
59
+ #ifdef DEBUG_PRINTF
60
+ #define LOG (...) fprintf(stderr, __VA_ARGS__)
61
+ #else
62
+ #define LOG (...) do {} while (0)
63
+ #endif
64
+
65
+ #ifndef __FreeBSD__
66
+ #define DETACH_KERNEL_DRIVER
67
+ #endif
68
+
69
+ /* Uncomment to enable the retrieval of Usage and Usage Page in
70
+ hid_enumerate(). Warning, on platforms different from FreeBSD
71
+ this is very invasive as it requires the detach
72
+ and re-attach of the kernel driver. See comments inside hid_enumerate().
73
+ libusb HIDAPI programs are encouraged to use the interface number
74
+ instead to differentiate between interfaces on a composite HID device. */
75
+ /*#define INVASIVE_GET_USAGE*/
76
+
77
+ /* Linked List of input reports received from the device. */
78
+ struct input_report {
79
+ uint8_t * data ;
80
+ size_t len ;
81
+ struct input_report * next ;
82
+ };
83
+
84
+ #ifndef HIDAPI_THREAD_STATE_DEFINED
85
+
86
+ #include <pthread.h>
87
+
54
88
#if defined(__ANDROID__ ) && __ANDROID_API__ < __ANDROID_API_N__
55
89
56
90
/* Barrier implementation because Android/Bionic don't have pthread_barrier.
@@ -112,35 +146,92 @@ static int pthread_barrier_wait(pthread_barrier_t *barrier)
112
146
113
147
#endif
114
148
115
- #ifdef __cplusplus
116
- extern "C" {
117
- #endif
149
+ #define THREAD_STATE_WAIT_TIMED_OUT ETIMEDOUT
118
150
119
- #ifdef DEBUG_PRINTF
120
- #define LOG (...) fprintf(stderr, __VA_ARGS__)
121
- #else
122
- #define LOG (...) do {} while (0)
123
- #endif
151
+ typdef struct
152
+ {
153
+ pthread_t thread ;
154
+ pthread_mutex_t mutex ; /* Protects input_reports */
155
+ pthread_cond_t condition ;
156
+ pthread_barrier_t barrier ; /* Ensures correct startup sequence */
124
157
125
- #ifndef __FreeBSD__
126
- #define DETACH_KERNEL_DRIVER
127
- #endif
158
+ } hid_device_thread_state ;
128
159
129
- /* Uncomment to enable the retrieval of Usage and Usage Page in
130
- hid_enumerate(). Warning, on platforms different from FreeBSD
131
- this is very invasive as it requires the detach
132
- and re-attach of the kernel driver. See comments inside hid_enumerate().
133
- libusb HIDAPI programs are encouraged to use the interface number
134
- instead to differentiate between interfaces on a composite HID device. */
135
- /*#define INVASIVE_GET_USAGE*/
160
+ static void thread_state_init (hid_device_thread_state * state )
161
+ {
162
+ pthread_mutex_init (& state -> mutex , NULL );
163
+ pthread_cond_init (& state -> condition , NULL );
164
+ pthread_barrier_init (& state -> barrier , NULL , 2 );
165
+ }
136
166
137
- /* Linked List of input reports received from the device. */
138
- struct input_report {
139
- uint8_t * data ;
140
- size_t len ;
141
- struct input_report * next ;
142
- };
167
+ static void thread_state_free (hid_device_thread_state * state )
168
+ {
169
+ pthread_barrier_destroy (& state -> barrier );
170
+ pthread_cond_destroy (& state -> condition );
171
+ pthread_mutex_destroy (& state -> mutex );
172
+ }
173
+
174
+ static void thread_state_push_cleanup (void (* routine )(void * ), void * arg )
175
+ {
176
+ pthread_cleanup_push (& cleanup_mutex , dev );
177
+ }
178
+
179
+ static void thread_state_pop_cleanup (int execute )
180
+ {
181
+ pthread_cleanup_pop (execute );
182
+ }
183
+
184
+ static void thread_state_lock (hid_device_thread_state * state )
185
+ {
186
+ pthread_mutex_lock (& state -> mutex );
187
+ }
188
+
189
+ static void thread_state_unlock (hid_device_thread_state * state )
190
+ {
191
+ pthread_mutex_unlock (& state -> mutex );
192
+ }
193
+
194
+ static void thread_state_wait_condition (hid_device_thread_state * state )
195
+ {
196
+ pthread_cond_wait (& state -> condition , & state -> mutex );
197
+ }
198
+
199
+ static int thread_state_wait_condition_timeout (hid_device_thread_state * state , struct timespec * ts )
200
+ {
201
+ return pthread_cond_timedwait (& state -> condition , & state -> mutex , ts );
202
+ }
203
+
204
+ static void thread_state_signal_condition (hid_device_thread_state * state )
205
+ {
206
+ pthread_cond_signal (& state -> condition );
207
+ }
143
208
209
+ static void thread_state_broadcast_condition (hid_device_thread_state * state )
210
+ {
211
+ pthread_cond_broadcast (& state -> condition );
212
+ }
213
+
214
+ static void thread_state_wait_barrier (hid_device_thread_state * state )
215
+ {
216
+ pthread_barrier_wait (& state -> barrier );
217
+ }
218
+
219
+ static void thread_state_create_thread (hid_device_thread_state * state , void * (* func )(void * ), void * func_arg )
220
+ {
221
+ pthread_create (& dev -> thread , NULL , func , param );
222
+ }
223
+
224
+ static void thread_state_join_thread (hid_device_thread_state * state )
225
+ {
226
+ pthread_join (state -> thread , NULL );
227
+ }
228
+
229
+ static void thread_state_get_current_time (struct timespec * ts )
230
+ {
231
+ clock_gettime (CLOCK_REALTIME , ts );
232
+ }
233
+
234
+ #endif /* !HIDAPI_THREAD_STATE_DEFINED */
144
235
145
236
struct hid_device_ {
146
237
/* Handle to the actual device. */
@@ -168,10 +259,7 @@ struct hid_device_ {
168
259
int blocking ; /* boolean */
169
260
170
261
/* Read thread objects */
171
- pthread_t thread ;
172
- pthread_mutex_t mutex ; /* Protects input_reports */
173
- pthread_cond_t condition ;
174
- pthread_barrier_t barrier ; /* Ensures correct startup sequence */
262
+ hid_device_thread_state thread_state ;
175
263
int shutdown_thread ;
176
264
int transfer_loop_finished ;
177
265
struct libusb_transfer * transfer ;
@@ -201,19 +289,15 @@ static hid_device *new_hid_device(void)
201
289
hid_device * dev = (hid_device * ) calloc (1 , sizeof (hid_device ));
202
290
dev -> blocking = 1 ;
203
291
204
- pthread_mutex_init (& dev -> mutex , NULL );
205
- pthread_cond_init (& dev -> condition , NULL );
206
- pthread_barrier_init (& dev -> barrier , NULL , 2 );
292
+ thread_state_init (& dev -> thread_state );
207
293
208
294
return dev ;
209
295
}
210
296
211
297
static void free_hid_device (hid_device * dev )
212
298
{
213
299
/* Clean up the thread objects */
214
- pthread_barrier_destroy (& dev -> barrier );
215
- pthread_cond_destroy (& dev -> condition );
216
- pthread_mutex_destroy (& dev -> mutex );
300
+ thread_state_free (& dev -> thread_state );
217
301
218
302
hid_free_enumeration (dev -> device_info );
219
303
@@ -912,13 +996,13 @@ static void read_callback(struct libusb_transfer *transfer)
912
996
rpt -> len = transfer -> actual_length ;
913
997
rpt -> next = NULL ;
914
998
915
- pthread_mutex_lock (& dev -> mutex );
999
+ thread_state_lock (& dev -> thread_state );
916
1000
917
1001
/* Attach the new report object to the end of the list. */
918
1002
if (dev -> input_reports == NULL ) {
919
1003
/* The list is empty. Put it at the root. */
920
1004
dev -> input_reports = rpt ;
921
- pthread_cond_signal (& dev -> condition );
1005
+ thread_state_signal_condition (& dev -> thread_state );
922
1006
}
923
1007
else {
924
1008
/* Find the end of the list and attach. */
@@ -937,7 +1021,7 @@ static void read_callback(struct libusb_transfer *transfer)
937
1021
return_data (dev , NULL , 0 );
938
1022
}
939
1023
}
940
- pthread_mutex_unlock (& dev -> mutex );
1024
+ thread_state_unlock (& dev -> thread_state );
941
1025
}
942
1026
else if (transfer -> status == LIBUSB_TRANSFER_CANCELLED ) {
943
1027
dev -> shutdown_thread = 1 ;
@@ -996,7 +1080,7 @@ static void *read_thread(void *param)
996
1080
}
997
1081
998
1082
/* Notify the main thread that the read thread is up and running. */
999
- pthread_barrier_wait (& dev -> barrier );
1083
+ thread_state_wait_barrier (& dev -> thread_state );
1000
1084
1001
1085
/* Handle all the events. */
1002
1086
while (!dev -> shutdown_thread ) {
@@ -1028,15 +1112,15 @@ static void *read_thread(void *param)
1028
1112
make sure that a thread which is about to go to sleep waiting on
1029
1113
the condition actually will go to sleep before the condition is
1030
1114
signaled. */
1031
- pthread_mutex_lock (& dev -> mutex );
1032
- pthread_cond_broadcast (& dev -> condition );
1033
- pthread_mutex_unlock (& dev -> mutex );
1115
+ thread_state_lock (& dev -> thread_state );
1116
+ thread_state_broadcast_condition (& dev -> thread_state );
1117
+ thread_state_unlock (& dev -> thread_state );
1034
1118
1035
1119
/* The dev->transfer->buffer and dev->transfer objects are cleaned up
1036
1120
in hid_close(). They are not cleaned up here because this thread
1037
1121
could end either due to a disconnect or due to a user
1038
1122
call to hid_close(). In both cases the objects can be safely
1039
- cleaned up after the call to pthread_join () (in hid_close()), but
1123
+ cleaned up after the call to thread_state_join () (in hid_close()), but
1040
1124
since hid_close() calls libusb_cancel_transfer(), on these objects,
1041
1125
they can not be cleaned up here. */
1042
1126
@@ -1128,15 +1212,15 @@ static int hidapi_initialize_device(hid_device *dev, int config_number, const st
1128
1212
}
1129
1213
}
1130
1214
1131
- pthread_create (& dev -> thread , NULL , read_thread , dev );
1215
+ thread_state_create_thread (& dev -> thread_state , read_thread , dev );
1132
1216
1133
1217
/* Wait here for the read thread to be initialized. */
1134
- pthread_barrier_wait (& dev -> barrier );
1218
+ thread_state_wait_barrier (& dev -> thread_state );
1135
1219
return 1 ;
1136
1220
}
1137
1221
1138
1222
1139
- hid_device * HID_API_EXPORT hid_open_path (const char * path )
1223
+ HID_API_EXPORT hid_device * hid_open_path (const char * path )
1140
1224
{
1141
1225
hid_device * dev = NULL ;
1142
1226
@@ -1347,7 +1431,7 @@ static int return_data(hid_device *dev, unsigned char *data, size_t length)
1347
1431
static void cleanup_mutex (void * param )
1348
1432
{
1349
1433
hid_device * dev = param ;
1350
- pthread_mutex_unlock (& dev -> mutex );
1434
+ thread_state_unlock (& dev -> thread_state );
1351
1435
}
1352
1436
1353
1437
@@ -1363,8 +1447,8 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
1363
1447
/* error: variable ‘bytes_read’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] */
1364
1448
int bytes_read ; /* = -1; */
1365
1449
1366
- pthread_mutex_lock (& dev -> mutex );
1367
- pthread_cleanup_push ( & cleanup_mutex , dev );
1450
+ thread_state_lock (& dev -> thread_state );
1451
+ thread_state_push_cleanup ( cleanup_mutex , dev );
1368
1452
1369
1453
bytes_read = -1 ;
1370
1454
@@ -1385,7 +1469,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
1385
1469
if (milliseconds == -1 ) {
1386
1470
/* Blocking */
1387
1471
while (!dev -> input_reports && !dev -> shutdown_thread ) {
1388
- pthread_cond_wait (& dev -> condition , & dev -> mutex );
1472
+ thread_state_wait_condition (& dev -> thread_state );
1389
1473
}
1390
1474
if (dev -> input_reports ) {
1391
1475
bytes_read = return_data (dev , data , length );
@@ -1395,7 +1479,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
1395
1479
/* Non-blocking, but called with timeout. */
1396
1480
int res ;
1397
1481
struct timespec ts ;
1398
- clock_gettime ( CLOCK_REALTIME , & ts );
1482
+ thread_state_get_current_time ( & ts );
1399
1483
ts .tv_sec += milliseconds / 1000 ;
1400
1484
ts .tv_nsec += (milliseconds % 1000 ) * 1000000 ;
1401
1485
if (ts .tv_nsec >= 1000000000L ) {
@@ -1404,7 +1488,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
1404
1488
}
1405
1489
1406
1490
while (!dev -> input_reports && !dev -> shutdown_thread ) {
1407
- res = pthread_cond_timedwait (& dev -> condition , & dev -> mutex , & ts );
1491
+ res = thread_state_wait_condition_timeout (& dev -> thread_state , & ts );
1408
1492
if (res == 0 ) {
1409
1493
if (dev -> input_reports ) {
1410
1494
bytes_read = return_data (dev , data , length );
@@ -1415,7 +1499,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
1415
1499
or the read thread was shutdown. Run the
1416
1500
loop again (ie: don't break). */
1417
1501
}
1418
- else if (res == ETIMEDOUT ) {
1502
+ else if (res == THREAD_STATE_WAIT_TIMED_OUT ) {
1419
1503
/* Timed out. */
1420
1504
bytes_read = 0 ;
1421
1505
break ;
@@ -1433,8 +1517,8 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
1433
1517
}
1434
1518
1435
1519
ret :
1436
- pthread_mutex_unlock (& dev -> mutex );
1437
- pthread_cleanup_pop (0 );
1520
+ thread_state_unlock (& dev -> thread_state );
1521
+ thread_state_pop_cleanup (0 );
1438
1522
1439
1523
return bytes_read ;
1440
1524
}
@@ -1552,7 +1636,7 @@ void HID_API_EXPORT hid_close(hid_device *dev)
1552
1636
libusb_cancel_transfer (dev -> transfer );
1553
1637
1554
1638
/* Wait for read_thread() to end. */
1555
- pthread_join ( dev -> thread , NULL );
1639
+ thread_state_join_thread ( & dev -> thread_state );
1556
1640
1557
1641
/* Clean up the Transfer objects allocated in read_thread(). */
1558
1642
free (dev -> transfer -> buffer );
@@ -1575,11 +1659,11 @@ void HID_API_EXPORT hid_close(hid_device *dev)
1575
1659
libusb_close (dev -> device_handle );
1576
1660
1577
1661
/* Clear out the queue of received reports. */
1578
- pthread_mutex_lock (& dev -> mutex );
1662
+ thread_state_lock (& dev -> thread_state );
1579
1663
while (dev -> input_reports ) {
1580
1664
return_data (dev , NULL , 0 );
1581
1665
}
1582
- pthread_mutex_unlock (& dev -> mutex );
1666
+ thread_state_unlock (& dev -> thread_state );
1583
1667
1584
1668
free_hid_device (dev );
1585
1669
}
0 commit comments