Fix data race when accessing dongle children

This commit is contained in:
Tasos Sahanidis
2021-10-26 02:25:39 +03:00
parent 0ba38d8d83
commit 757b0e853d
4 changed files with 11 additions and 2 deletions
+3 -2
View File
@@ -17,6 +17,7 @@ pthread_cond_t macrovar[DEV_MAX] = { [0 ... DEV_MAX-1] = PTHREAD_COND_INITIALIZE
pthread_cond_t macroint[DEV_MAX]; ///< Should a macro thread's sleep be interrupted, due to repeated key press?
pthread_mutex_t interruptmutex[DEV_MAX] = { [0 ... DEV_MAX-1] = PTHREAD_MUTEX_INITIALIZER };///< Used for interrupt transfers
pthread_cond_t interruptcond[DEV_MAX]; ///< Same as above
pthread_mutex_t childrenmutex[DEV_MAX] = { [0 ... DEV_MAX-1] = PTHREAD_MUTEX_INITIALIZER };
///
/// \brief cond_nanosleep matches semantics of pthread_cond_timedwait, but with a relative wake time
@@ -175,7 +176,7 @@ int _start_dev(usbdevice* kb, int makeactive){
///
if(IS_SINGLE_EP(kb))
kb->features &= ~FEAT_BIND;
///
/// The Polaris doesn't support hardware profiles, so remove the FEAT_HWLOAD bit.
///
@@ -187,7 +188,7 @@ int _start_dev(usbdevice* kb, int makeactive){
///
if(USES_FILE_HWSAVE(kb))
kb->features &= ~FEAT_HWLOAD;
///
/// K66 has no backlight
///
+4
View File
@@ -60,6 +60,10 @@ extern pthread_mutex_t interruptmutex[DEV_MAX];
extern pthread_cond_t interruptcond[DEV_MAX];
#define intcond(kb) (interruptcond + INDEX_OF(kb, keyboard))
// Mutex to access the children for each device
extern pthread_mutex_t childrenmutex[DEV_MAX];
#define cmutex(kb) (childrenmutex + INDEX_OF(kb, keyboard))
int init_cond_monotonic(void);
// Sets up device hardware, after software initialization is finished. Also used during resets
+2
View File
@@ -205,7 +205,9 @@ static inline int bragi_dongle_probe(usbdevice* kb){
subkb->bragi_child_id = i;
// Add the device to our children array
pthread_mutex_lock(cmutex(kb));
kb->children[i-1] = subkb;
pthread_mutex_unlock(cmutex(kb));
// Fill dev information
ushort vid = bragi_get_property(subkb, BRAGI_VID);
+2
View File
@@ -590,6 +590,7 @@ void process_input_urb(void* context, unsigned char* buffer, int urblen, ushort
// All device specific events have the max length of bytes
usbdevice* targetkb = kb;
if(kb->protocol == PROTO_BRAGI && IS_DONGLE(kb)){
pthread_mutex_lock(cmutex(kb));
if(urblen == kb->out_ep_packet_size){
// Extract the device id
int devid = firstbyte & 0x7;
@@ -608,6 +609,7 @@ void process_input_urb(void* context, unsigned char* buffer, int urblen, ushort
ckb_err("kb->children[0] is NULL");
#endif
}
pthread_mutex_unlock(cmutex(kb));
}
// If the response starts with CMD_GET (0x0e) for NXP, or it came from a bragi command EP, that means it needs to go to os_usbrecv()