Ok so actually everything is fine with this code, the issue was elsewhere : I had a re-entrance problem that caused a deadlock.
Moral: Carefully protect your resources and addresses in a multi-thread context
Why does sem_timedwait() not waking up?
-
13-06-2023 - |
Question
I work on an embedded system with eCos: I have 2 threads within the same process and 1 semaphore.
- Thread A initializes a semaphore to 0 so that the 1st attempt to take it will block.
- Thread A sends a command to Thread B, providing a callback.
- Thread A waits on semaphore with
sem_timedwait
- Thread B process the command and increments the semaphore
- Thread A should be woken up but is still blocked
Here is the code:
Thread A
static sem_t semaphore;
void callback()
{
// Do some stuff
int ret = sem_post(&semaphore);
// print confirmation message
}
void foo()
{
int ret = sem_init(&semaphore, 0, 0);
if(ret != 0)
{
// print errno
}
struct timespec ts;
clock_gettime(CLOCK_REALTIME,&ts); // Get current date
ts.tv_sec += 2; // Add 2s for the deadline
send_command_to_thread_B(&callback);
ret = sem_timedwait(&semaphore, &ts);
if(ret != 0)
{
// print errno
}
// print waking up message
}
What is in Thread B is not relevant.
For debug I tried the following:
- Using
sem_wait
rather thansem_timedwait
works: Thread A is blocked, then unlocked after the callback. But I don't want to use it because if there is a failure in the callback process that prevent the semaphore to be incremented, Thread A will wait forever. - If I don't add the 2s to the
timespec
struct,sem_timedwait
returns immediatly anderrno
is set toETIMEDOUT
(seems legit). The callback is called but it is too late for Thread A. - I put traces in the callback call to ensure that the semaphore is indeed incremented from 0 to 1: all the process is done, the callback exits but Thread A is still blocked.
Do you guys have any clue ? Am I missing something ?
Solution
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow