mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-25 06:23:53 +01:00
xtimer: check in timeout callback if thread blocked on mutex
Prevent a possible race condition when _mutex_timeout fires just after the
mutex was locked but before the xtimer was removed
The flow
int xtimer_mutex_lock_timeout(mutex_t *mutex, uint64_t timeout) {
...
mutex_lock(mutex);
/* mutex locked */
/* _mutex_timeout fires and tries to remove thread from mutex queue */
/* DEBUG: simulate callback call between lock and remove */
xtimer_spin(xtimer_ticks_from_usec(timeout*2));
xtimer_remove(&t);
...
}
This commit is contained in:
parent
cce1438e61
commit
f3b13cf90c
@ -250,20 +250,23 @@ static void _mutex_timeout(void *arg)
|
||||
|
||||
mutex_thread_t *mt = (mutex_thread_t *)arg;
|
||||
|
||||
mt->timeout = 1;
|
||||
list_node_t *node = list_remove(&mt->mutex->queue,
|
||||
(list_node_t *)&mt->thread->rq_entry);
|
||||
if (mt->mutex->queue.next != MUTEX_LOCKED) {
|
||||
mt->timeout = 1;
|
||||
list_node_t *node = list_remove(&mt->mutex->queue,
|
||||
(list_node_t *)&mt->thread->rq_entry);
|
||||
|
||||
/* if thread was removed from the list */
|
||||
if (node != NULL) {
|
||||
if (mt->mutex->queue.next == NULL) {
|
||||
mt->mutex->queue.next = MUTEX_LOCKED;
|
||||
/* if thread was removed from the list */
|
||||
if (node != NULL) {
|
||||
if (mt->mutex->queue.next == NULL) {
|
||||
mt->mutex->queue.next = MUTEX_LOCKED;
|
||||
}
|
||||
sched_set_status(mt->thread, STATUS_PENDING);
|
||||
irq_restore(irqstate);
|
||||
sched_switch(mt->thread->priority);
|
||||
return;
|
||||
}
|
||||
sched_set_status(mt->thread, STATUS_PENDING);
|
||||
irq_restore(irqstate);
|
||||
sched_switch(mt->thread->priority);
|
||||
return;
|
||||
}
|
||||
|
||||
irq_restore(irqstate);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user