Creating an automatic-reset event from WaitOnAddress


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.

Comments (2)

  1. Tobias Langer says:

    If you look closely in the code, you’ll find a STD hidden in the letters.

  2. CarlD says:

    Typo in InitializeAltAutoEvent – you meant Event->State

Skip to main content