jump to navigation

About Windows Events (synchronization) August 17, 2007

Posted by fahdk in Computing, Windows.
6 comments

Salaam.

I was trying to understand some C++ code on the Windows platform that uses the Windows Event synchronization object. Not being familiar with this object, I asked Shaikh Google about it but did not find an appropriate response.

Shaikh MSDN was also not very forthcoming about clarifying the issue, so I had to do a few experiments to figure it out myself. This blog entry sums up my understanding and should be helpful to those programmers who wish to know how the Windows Event object exactly works.

First we should discuss some terminology.

When an Event object is in signalled state, any thread issuing a Wait command on it will find the Wait successful (it will not block). In other words, signalled means unblocked.

When an Event object is in nonsignalled state, any thread issuing a Wait command on it will find the Wait blocking (assuming the timeout parameter for the wait was not 0). That means, nonsignalled can be thought of as blocked.

Now let us look at some APIs related to the Event object.

HANDLE WINAPI CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName
);

This call is used to create an Event object and returns a handle to it.
lpEventAttributes [in] is a pointer to a SECURITY_ATTRIBUTES structure. We will not go into the details of this parameter. It may be set to NULL.
bManualReset [in] is an interesting parameter and we will discuss this in more detail. If this parameter is TRUE, the function creates a manual-reset event object otherwise, it creates an auto-reset object.

Basically, Events in Windows can be of two types; manual-reset and auto-reset. A manual-reset Event object can be made to change its state from signalled to nonsignalled and vice-versa using the system calls SetEvent and ResetEvent respectively. This is fairly straightforward. To use this object, you will set it to nonsignalled (using ResetEvent) if you want the other thread to block on it, and you will set it to signalled (by calling SetEvent) if you want the other thread to proceed. As you can see, this is fairly simple.

Manual Reset Event (Pseudocode)

 

 

 

 

 

 

 

 

An auto-reset Event is not so straightforward initially. The idea behind this is that as soon as a thread unblocks on this object, the object will get blocked immediately and automatically for the other threads. So you do not need to call ResetEvent for this Event object. A Wait call on this object, when it succeeds, also does the ResetEvent (changing to nonsignalled) for you automatically. Notice that in this sense, it works like a semaphore with a max count of 1.

Auto Reset Event (Pseudocode)

 

 

 

 

 

 

 

 

lpName [in] The name of the event object. If this is NULL, the event object cannot be shared between processes. If it is not NULL, a global object will be created that can be shared between threads of different processes. Note that if an Event object was created previously by another thread, a handle to this object can be obtained using the OpenEvent API call.

Thanks.