Creating an automatic-reset event from WaitOnAddress

Raymond Chen

Last time, we created a manual-reset event from Wait­On­Address. Today, it’s an automatic-reset event.

struct ALT_AEVENT
{
  LONG State;
};

void InitializeAltAutoEvent(ALT_AEVENT* Event,
                            bool InitialState)
{
  Semaphore->State = InitialState;
}

void SetAltAutoEvent(ALT_AEVENT* Event)
{
 if (InterlockedCompareExchange(&Event->State,
                                true, false) == false) {
  WakeByAddressSingle(&Event->State);
 }
}

void ResetAltAutoEvent(ALT_AEVENT* Event)
{
 InterlockedCompareExchange(&Event->State,
                            false, true);
}

void WaitForAltAutoEvent(ALT_AEVENT* Event)
{
 while (!InterlockedCompareExchange(&Event->State,
                                    false, true)) {
  LONG Waiting = 0;
  WaitOnAddress(&Event->State,
                &Waiting,
                sizeof(Waiting),
                INFINITE);
 }
}

Most of this code is the same as with manual-reset events. One difference is that when setting the event, we use Wake­By­Address­Single because signaling an auto-reset event releases at most one thread.

The interesting change is in thw code that waits. Instead of merely checking the state, we try to transition it from true to false, which simultaneously checks and claims the token.

Okay, next time, we’re going to put together what we’ve been learning this week to solve an actual problem.

0 comments

Discussion is closed.

Feedback usabilla icon