Search code examples
c#.net.net-3.5waithandle

Does EventWaitHandle have to deal with spurious wakes?


Note: I am constrained to .NET 3.5, so I can't use ManualResetEventSlim.

Do I have to deal with Spurious wakeups when doing something like this:

var waitHandle = new EventWaitHandle();
new Thread(() =>
{
    Thread.Sleep(TimeSpan.FromSeconds(5));
    waitHandler.Set();
});
waitHandle.WaitOne();

If so, are the correct memory barrier set when calling Set and/or WaitOne such that this would be safe:

var reallyDone = false;
var waitHandle = new EventWaitHandle();
new Thread(() =>
{
    Thread.Sleep(TimeSpan.FromSeconds(5));
    reallyDone = true;
    waitHandler.Set();
});
while (!reallyDone)
    waitHandle.WaitOne();

In particular, is it possible that the main thread in this example might not see that reallyDone is set to true due to instruction reordering or caching? Does reallyDone need to be volatile in this case or is that unnecessary?


Solution

  • There are no spurious wakeups for events (MRE, ARE, and the slim versions). Almost all Windows programs would break if there was such a thing with those objects. You are fighting windmills. But yes, many of the synchronization functions including waiting and setting events perform a full memory barrier (which is well understood but nowhere documented). Condition variables to allow spurious wakeups (as the docs state). They are unrelated to events.

    Also, why would there be spurious wakeups? Doesn't make sense from an API standpoint. The event could just loop internally and hide the spurious wakeups from you (indeed, MRESlim does that). I can only repeat: Almost all programs would break. That is not reality.

    The docs say:

    Blocks the current thread until the current WaitHandle receives a signal. The caller of this method blocks indefinitely until the current instance receives a signal.

    These statements would be false if spurious wakeups were to exist in the context of events.

    You are misinterpreting what you saw. You have a bug but it is not caused by the event. The reallyDone technique is not required.