37
37
#include <sys/ioctl.h>
38
38
#include <sys/utsname.h>
39
39
#include <fcntl.h>
40
- #include <pthread.h>
41
40
#include <wchar.h>
42
41
43
42
/* GNU / LibUSB */
51
50
52
51
#include "hidapi_libusb.h"
53
52
54
- #if defined(__ANDROID__ ) && __ANDROID_API__ < __ANDROID_API_N__
55
-
56
- /* Barrier implementation because Android/Bionic don't have pthread_barrier.
57
- This implementation came from Brent Priddy and was posted on
58
- StackOverflow. It is used with his permission. */
59
- typedef int pthread_barrierattr_t ;
60
- typedef struct pthread_barrier {
61
- pthread_mutex_t mutex ;
62
- pthread_cond_t cond ;
63
- int count ;
64
- int trip_count ;
65
- } pthread_barrier_t ;
66
-
67
- static int pthread_barrier_init (pthread_barrier_t * barrier , const pthread_barrierattr_t * attr , unsigned int count )
68
- {
69
- if (count == 0 ) {
70
- errno = EINVAL ;
71
- return -1 ;
72
- }
73
-
74
- if (pthread_mutex_init (& barrier -> mutex , 0 ) < 0 ) {
75
- return -1 ;
76
- }
77
- if (pthread_cond_init (& barrier -> cond , 0 ) < 0 ) {
78
- pthread_mutex_destroy (& barrier -> mutex );
79
- return -1 ;
80
- }
81
- barrier -> trip_count = count ;
82
- barrier -> count = 0 ;
83
-
84
- return 0 ;
85
- }
86
-
87
- static int pthread_barrier_destroy (pthread_barrier_t * barrier )
88
- {
89
- pthread_cond_destroy (& barrier -> cond );
90
- pthread_mutex_destroy (& barrier -> mutex );
91
- return 0 ;
92
- }
93
-
94
- static int pthread_barrier_wait (pthread_barrier_t * barrier )
95
- {
96
- pthread_mutex_lock (& barrier -> mutex );
97
- ++ (barrier -> count );
98
- if (barrier -> count >= barrier -> trip_count )
99
- {
100
- barrier -> count = 0 ;
101
- pthread_cond_broadcast (& barrier -> cond );
102
- pthread_mutex_unlock (& barrier -> mutex );
103
- return 1 ;
104
- }
105
- else
106
- {
107
- pthread_cond_wait (& barrier -> cond , & (barrier -> mutex ));
108
- pthread_mutex_unlock (& barrier -> mutex );
109
- return 0 ;
110
- }
111
- }
112
-
53
+ #ifndef HIDAPI_THREAD_MODEL_INCLUDE
54
+ #define HIDAPI_THREAD_MODEL_INCLUDE "hidapi_thread_pthread.h"
113
55
#endif
56
+ #include HIDAPI_THREAD_MODEL_INCLUDE
114
57
115
58
#ifdef __cplusplus
116
59
extern "C" {
@@ -168,10 +111,7 @@ struct hid_device_ {
168
111
int blocking ; /* boolean */
169
112
170
113
/* 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 */
114
+ hidapi_thread_state thread_state ;
175
115
int shutdown_thread ;
176
116
int transfer_loop_finished ;
177
117
struct libusb_transfer * transfer ;
@@ -201,19 +141,15 @@ static hid_device *new_hid_device(void)
201
141
hid_device * dev = (hid_device * ) calloc (1 , sizeof (hid_device ));
202
142
dev -> blocking = 1 ;
203
143
204
- pthread_mutex_init (& dev -> mutex , NULL );
205
- pthread_cond_init (& dev -> condition , NULL );
206
- pthread_barrier_init (& dev -> barrier , NULL , 2 );
144
+ hidapi_thread_state_init (& dev -> thread_state );
207
145
208
146
return dev ;
209
147
}
210
148
211
149
static void free_hid_device (hid_device * dev )
212
150
{
213
151
/* Clean up the thread objects */
214
- pthread_barrier_destroy (& dev -> barrier );
215
- pthread_cond_destroy (& dev -> condition );
216
- pthread_mutex_destroy (& dev -> mutex );
152
+ hidapi_thread_state_destroy (& dev -> thread_state );
217
153
218
154
hid_free_enumeration (dev -> device_info );
219
155
@@ -912,13 +848,13 @@ static void read_callback(struct libusb_transfer *transfer)
912
848
rpt -> len = transfer -> actual_length ;
913
849
rpt -> next = NULL ;
914
850
915
- pthread_mutex_lock (& dev -> mutex );
851
+ hidapi_thread_mutex_lock (& dev -> thread_state );
916
852
917
853
/* Attach the new report object to the end of the list. */
918
854
if (dev -> input_reports == NULL ) {
919
855
/* The list is empty. Put it at the root. */
920
856
dev -> input_reports = rpt ;
921
- pthread_cond_signal (& dev -> condition );
857
+ hidapi_thread_cond_signal (& dev -> thread_state );
922
858
}
923
859
else {
924
860
/* Find the end of the list and attach. */
@@ -937,7 +873,7 @@ static void read_callback(struct libusb_transfer *transfer)
937
873
return_data (dev , NULL , 0 );
938
874
}
939
875
}
940
- pthread_mutex_unlock (& dev -> mutex );
876
+ hidapi_thread_mutex_unlock (& dev -> thread_state );
941
877
}
942
878
else if (transfer -> status == LIBUSB_TRANSFER_CANCELLED ) {
943
879
dev -> shutdown_thread = 1 ;
@@ -996,7 +932,7 @@ static void *read_thread(void *param)
996
932
}
997
933
998
934
/* Notify the main thread that the read thread is up and running. */
999
- pthread_barrier_wait (& dev -> barrier );
935
+ hidapi_thread_barrier_wait (& dev -> thread_state );
1000
936
1001
937
/* Handle all the events. */
1002
938
while (!dev -> shutdown_thread ) {
@@ -1028,15 +964,15 @@ static void *read_thread(void *param)
1028
964
make sure that a thread which is about to go to sleep waiting on
1029
965
the condition actually will go to sleep before the condition is
1030
966
signaled. */
1031
- pthread_mutex_lock (& dev -> mutex );
1032
- pthread_cond_broadcast (& dev -> condition );
1033
- pthread_mutex_unlock (& dev -> mutex );
967
+ hidapi_thread_mutex_lock (& dev -> thread_state );
968
+ hidapi_thread_cond_broadcast (& dev -> thread_state );
969
+ hidapi_thread_mutex_unlock (& dev -> thread_state );
1034
970
1035
971
/* The dev->transfer->buffer and dev->transfer objects are cleaned up
1036
972
in hid_close(). They are not cleaned up here because this thread
1037
973
could end either due to a disconnect or due to a user
1038
974
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
975
+ cleaned up after the call to hidapi_thread_join () (in hid_close()), but
1040
976
since hid_close() calls libusb_cancel_transfer(), on these objects,
1041
977
they can not be cleaned up here. */
1042
978
@@ -1128,10 +1064,10 @@ static int hidapi_initialize_device(hid_device *dev, int config_number, const st
1128
1064
}
1129
1065
}
1130
1066
1131
- pthread_create (& dev -> thread , NULL , read_thread , dev );
1067
+ hidapi_thread_create (& dev -> thread_state , read_thread , dev );
1132
1068
1133
1069
/* Wait here for the read thread to be initialized. */
1134
- pthread_barrier_wait (& dev -> barrier );
1070
+ hidapi_thread_barrier_wait (& dev -> thread_state );
1135
1071
return 1 ;
1136
1072
}
1137
1073
@@ -1347,7 +1283,7 @@ static int return_data(hid_device *dev, unsigned char *data, size_t length)
1347
1283
static void cleanup_mutex (void * param )
1348
1284
{
1349
1285
hid_device * dev = param ;
1350
- pthread_mutex_unlock (& dev -> mutex );
1286
+ hidapi_thread_mutex_unlock (& dev -> thread_state );
1351
1287
}
1352
1288
1353
1289
@@ -1363,8 +1299,8 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
1363
1299
/* error: variable ‘bytes_read’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] */
1364
1300
int bytes_read ; /* = -1; */
1365
1301
1366
- pthread_mutex_lock (& dev -> mutex );
1367
- pthread_cleanup_push ( & cleanup_mutex , dev );
1302
+ hidapi_thread_mutex_lock (& dev -> thread_state );
1303
+ hidapi_thread_cleanup_push ( cleanup_mutex , dev );
1368
1304
1369
1305
bytes_read = -1 ;
1370
1306
@@ -1385,7 +1321,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
1385
1321
if (milliseconds == -1 ) {
1386
1322
/* Blocking */
1387
1323
while (!dev -> input_reports && !dev -> shutdown_thread ) {
1388
- pthread_cond_wait (& dev -> condition , & dev -> mutex );
1324
+ hidapi_thread_cond_wait (& dev -> thread_state );
1389
1325
}
1390
1326
if (dev -> input_reports ) {
1391
1327
bytes_read = return_data (dev , data , length );
@@ -1394,17 +1330,12 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
1394
1330
else if (milliseconds > 0 ) {
1395
1331
/* Non-blocking, but called with timeout. */
1396
1332
int res ;
1397
- struct timespec ts ;
1398
- clock_gettime (CLOCK_REALTIME , & ts );
1399
- ts .tv_sec += milliseconds / 1000 ;
1400
- ts .tv_nsec += (milliseconds % 1000 ) * 1000000 ;
1401
- if (ts .tv_nsec >= 1000000000L ) {
1402
- ts .tv_sec ++ ;
1403
- ts .tv_nsec -= 1000000000L ;
1404
- }
1333
+ hidapi_timespec ts ;
1334
+ hidapi_thread_gettime (& ts );
1335
+ hidapi_thread_addtime (& ts , milliseconds );
1405
1336
1406
1337
while (!dev -> input_reports && !dev -> shutdown_thread ) {
1407
- res = pthread_cond_timedwait (& dev -> condition , & dev -> mutex , & ts );
1338
+ res = hidapi_thread_cond_timedwait (& dev -> thread_state , & ts );
1408
1339
if (res == 0 ) {
1409
1340
if (dev -> input_reports ) {
1410
1341
bytes_read = return_data (dev , data , length );
@@ -1415,7 +1346,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
1415
1346
or the read thread was shutdown. Run the
1416
1347
loop again (ie: don't break). */
1417
1348
}
1418
- else if (res == ETIMEDOUT ) {
1349
+ else if (res == HIDAPI_THREAD_TIMED_OUT ) {
1419
1350
/* Timed out. */
1420
1351
bytes_read = 0 ;
1421
1352
break ;
@@ -1433,8 +1364,8 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
1433
1364
}
1434
1365
1435
1366
ret :
1436
- pthread_mutex_unlock (& dev -> mutex );
1437
- pthread_cleanup_pop (0 );
1367
+ hidapi_thread_mutex_unlock (& dev -> thread_state );
1368
+ hidapi_thread_cleanup_pop (0 );
1438
1369
1439
1370
return bytes_read ;
1440
1371
}
@@ -1552,7 +1483,7 @@ void HID_API_EXPORT hid_close(hid_device *dev)
1552
1483
libusb_cancel_transfer (dev -> transfer );
1553
1484
1554
1485
/* Wait for read_thread() to end. */
1555
- pthread_join ( dev -> thread , NULL );
1486
+ hidapi_thread_join ( & dev -> thread_state );
1556
1487
1557
1488
/* Clean up the Transfer objects allocated in read_thread(). */
1558
1489
free (dev -> transfer -> buffer );
@@ -1575,11 +1506,11 @@ void HID_API_EXPORT hid_close(hid_device *dev)
1575
1506
libusb_close (dev -> device_handle );
1576
1507
1577
1508
/* Clear out the queue of received reports. */
1578
- pthread_mutex_lock (& dev -> mutex );
1509
+ hidapi_thread_mutex_lock (& dev -> thread_state );
1579
1510
while (dev -> input_reports ) {
1580
1511
return_data (dev , NULL , 0 );
1581
1512
}
1582
- pthread_mutex_unlock (& dev -> mutex );
1513
+ hidapi_thread_mutex_unlock (& dev -> thread_state );
1583
1514
1584
1515
free_hid_device (dev );
1585
1516
}
0 commit comments