kernel: fix xxx_fiber_wakeup() if the timeout has expired

A call to xxx_fiber_wakeup() if the timeout had expired would put the
fiber on the fiber ready queue _again_, corrupting it, or could remove
the fiber from a nanokernel object wait queue, prematurely un-pending
it.

We now verify the fiber is indeed still on the timeout queue and also
not on a wait queue, meaning the fiber is indeed sleeping.

Change-Id: Iba454d79ab50db01632b0591fb7b589221b5110b
Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
This commit is contained in:
Benjamin Walsh 2016-02-24 15:27:54 -05:00
commit 7a613adc14

View file

@ -46,22 +46,27 @@ FUNC_ALIAS(_fiber_wakeup, fiber_fiber_wakeup, void);
void _fiber_wakeup(nano_thread_id_t fiber)
{
int key;
int key = irq_lock();
key = irq_lock();
_nano_timeout_abort(fiber);
/* verify first if fiber is not waiting on an object */
if (!fiber->nano_timeout.wait_q && (_nano_timeout_abort(fiber) == 0)) {
_nano_fiber_ready(fiber);
}
irq_unlock(key);
}
void task_fiber_wakeup(nano_thread_id_t fiber)
{
int key;
int key = irq_lock();
key = irq_lock();
_nano_timeout_abort(fiber);
/* verify first if fiber is not waiting on an object */
if ((fiber->nano_timeout.wait_q) || (_nano_timeout_abort(fiber) < 0)) {
irq_unlock(key);
} else {
_nano_fiber_ready(fiber);
_Swap(key);
}
}
#ifndef CONFIG_MICROKERNEL