What if a condition variable signals to a locked thread?

In the (pseudo-)code below, cond might wake up while it shouldn't, for whatever reason. So I put a while loop there. When it does wake up, it will still consume the lock, so it is guaranteed that in out() only one thread is doing its job.

But what happens if, while there is a spurious wake-up in out(), at the same time in() signals to out(), however at that very moment out() is already locked because of the spurious wake-up. So what happens if the cond signals to a locked thread?

    isEmpty = false

    while isEmpty
    isEmpty = true


Well, to be 100% safe, I know I can use a single mutex for both in() and out(), but the data structure I'm using is 100% safe when input and output happens at the same time; it is a type of a queue. And I think it is a performance compromise to block anything reading out from the queue while filling in some new data or vice versa.

I did consider using semaphores, but the problems is that so many C and C++ libraries don't implement semaphores for whatever reason.

asked Apr 29, 2015 in Core java by rahulgii
0 votes

1 Answer

0 votes

You have to use the same mutex when the in() thread sets isEmpty = false and the out()thread tests while (isEmpty). Otherwise, this can happen:

  1. out() thread tests isEmpty, finds it is true;
  2. in() thread sets isEmpty to false and signals the condition variable (but no-one wakes up, beacuse no-one is waiting yet);
  3. out() thread calls cond.wait() and blocks forever, despite the fact that the queue is not empty anymore.

Note that in this sequence there hasn't been a spurious wakeup - it's just a plain old race condition.

As long as you update isEmpty with the same mutex held as when you test isEmpty, this interleaving can't happen.


answered Apr 29, 2015 by rahulgii