I am trying to implement very simple Windows events in Linux. Only for my scenario - 3 threads, 1 main and 2 secondary. Each of secondary threads raise 1 event by SetEvent a
Basing this on the description of WaitForSingleObject
The WaitForSingleObject function checks the current state of the specified object. If the object's state is nonsignaled, the calling thread enters the wait state until the object is signaled or the time-out interval elapses.
The difference between that behavior and the code is that the code will always wait on the condition variable, as it does not check a predicate. This introduces synchronization issues between the pthread_condt_timewait
and pthread_cond_signal
calls.
The general idiom for signalling a condition variable is:
lock mutex set predicate unlock mutex signal condition variable
And when waiting for a condition variable:
lock mutex while ( !predicate ) { wait on condition variable } unlock mutex
Based on what is trying to be accomplished, a separate bool
could be used as a predicate for each Event
. By introducing a predicate, WaitForSingleObject
should only wait on the condition variable if the Event
has not been signaled. The code would look similar to the following:
bool SetEvent (mutex, condition)
{
pthread_mutex_lock(mutex); // lock mutex
bool& signalled = find_signal(condition); // find predicate
signalled = true; // set predicate
pthread_mutex_unlock(mutex); // unlock mutex
pthread_cond_signal(condition); // signal condition variable
}
int WaitForSingleObject(mutex, condition, timeout)
{
pthread_mutex_lock(mutex); // lock mutex
bool& signalled = find_signal(condition); // find predicate
while (!signalled)
{
pthread_cond_timedwait(condition, mutex, timeout);
}
signalled = false; // reset predicate
pthread_mutex_unlock(mutex); // unlock mutex
}