June 15th, 2017

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.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.