This is an example from the Glib docs for g_cond_wait()
:
gpointer current_data = NULL;
GMutex data_mutex;
GCond data_cond;
void push_data (gpointer data)
{
g_mutex_lock (&data_mutex); // (3)
current_data = data;
g_cond_signal (&data_cond);
g_mutex_unlock (&data_mutex); // (4)
}
gpointer pop_data (void)
{
gpointer data;
g_mutex_lock (&data_mutex); // (1)
while (!current_data)
g_cond_wait (&data_cond, &data_mutex); // (2)
data = current_data;
current_data = NULL;
g_mutex_unlock (&data_mutex); // (5)
return data;
}
Let's now go through this:
pop_data()
, data_mutex
is locked (1)g_cond_wait()
is called, data_mutex
is unlocked (2), first thread is waitingpush_data()
, data_mutex
is locked (3)data_mutex
(4)g_cond_wait()
and unlocks data_mutex
again (5)The docs say that unlocking a non-locked mutex is undefined. Does this mean the example contains a bug? Or will g_cond_wait()
lock the mutex before exiting?
The docs say that unlocking a non-locked mutex is undefined. Does this mean the example contains a bug? Or will g_cond_wait() lock the mutex before exiting?
There's no bug here. There's no unlocking of a mutex which wasn't locked in the code. g_cond_wait()
will lock the mutex when it returns.
Thread1 calls g_cond_wait()
with mutex locked and g_cond_wait()
atomically unlocks the mutex and waits on the condition. After this, thread2 locks the mutex and performs the operation, then signals to thread1 which is waiting in g_cond_wait()
. But thread1 can't continue as the mutex is still not available (thread2 is yet to unlock it). So after the call g_mutex_unlock()
in thread2 unlocks it, g_cond_wait()
in thread1 locks the mutex and the call returns.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With