handle UnboundedBlockingMpscQueue spurious wake-ups
A spurious wake-up can be produced by the new UnblockOnMainActorTest which
triggers the assert(!mpscQueue.empty())
in UnboundedBlockingMpscQueue::get
.
Those spurious wake-ups are possible because the push and wake-up pair in
UnboundedBlockingMpscQueue::put
are not atomic.
The following sequence diagram demonstrates a spurious wake-up:
T1 T2 Q
. . { }
put(e) . { }
push 54-57 . {e}
. get() {e}
. consume e { }
. . { }
. get() { }
. block { }
unblock . { }
. . { }
. wakeup { }
. . { }
X
assert(!queue.Empty())
To deal with spurious wake-ups we recheck the wake-up condition (a non empty queue) and block again if we find it empty. We assume spurious wake-ups are rare because it was difficult to reproduce them even with a dedicated Test (the new UnblockOnMainActorTest) therefore we declare the empty queue branch as unlikely.
Fixes #4 (closed).
Edited by Maxim Onciul