Welcome to MSDN Blogs Sign in | Join | Help

MSDK Synchronization Primitives - Event

Normally event should not deserve any special attention as a synchronization primitive. However, the MSDK event compensates the inconsistent/incomplete behavior of both Win32- and POSIX event primitives.

 

 

Win32 Event

A Win32 event has one of two types:

  • Manual           - once signaled, the event remains signaled until explicitly reset. While the event is in signaled state, threads consume it without blocking.
  • Automatic     - a signal is consumed exactly once. If one or more threads are blocked when an automatic event is signaled, exactly one thread is unblocked, and the event is reset immediately after that. If no thread is waiting on the event when it is signaled, the event remains signaled until a thread wants to consume it. That thread consumes the event without blocking, and the event is reset immediately after that.

Additionally Win32 has an interesting function, PulseEvent(), that has different effect over different types of events, and which, unfortunately, is documented as unreliable. Pulsing an automatic event releases one blocked thread, or the signal is lost. Pulsing a manual event releases all blocked threads, or the signal is lost. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/pulseevent.asp

 

 

POSIX Condition

The corresponding primitive in POSIX is Condition. Conditions are only pulsing, i.e. if no thread is waiting on the condition, the signal is lost. POSIX has a method, pthread_cond_broadcast(), that explicitly releases all blocked threads. Additionally a POSIX condition is always combined with a mutex, which turns out very convenient for modeling complex behaviors like MSDK Event.

http://www.die.net/doc/linux/man/man3/pthread_cond_signal.3.html

http://www.die.net/doc/linux/man/man3/pthread_cond_broadcast.3.html

 

 

MSDK Event

As I stated in my initial post on multithreading, I bet on Win32 as the main threading platform (http://blogs.msdn.com/zlatkom/archive/2006/03/08/Multithreading_WinPosix.aspx). Therefore I keep the terminology as close to Win32 as possible. However, I disagree with the concept that events should have a fixed a type and all the signaling they get is based on that type. So I changed that in the following manner: events have no specific type. Instead, the signaler specifies how it wants to signal the event. There are three possible ways to signal an event:

  • Pulse           – if one or more threads are blocked waiting on this event, exactly one thread gets unblocked and the event is reset. If no thread is waiting in this event, the signal is lost. This is the equivalent of a POSIX condition and pulsing a Win32 automatic event.
  • Signal           – if one or more threads are blocked waiting on this event, exactly one thread gets unblocked and the event is reset. If no thread is waiting in this event, the event remains in signaled state until a thread wants to consume it. That thread continues execution without blocking and the event is reset immediately after that. This is the default. This is the equivalent of a Win32 automatic event.
  • Permanent   – the event remains signaled until explicitly reset or signaled with Pulse or Signal. During that time all threads that want to consume the event continue their execution without blocking. This is the equivalent of a Win32 manual event and broadcasting a POSIX signal plus remaining signaled.

 

Source code:

http://cvs.sourceforge.net/viewcvs.py/msdk/include/event.h?rev=1.3&view=auto

 

Download MSDK:

          http://prdownloads.sourceforge.net/msdk/msdk-2.10.053.tar.gz?download (37K)

 

 

As I was writing this post, I discovered a bug and an enhancement:

  • Bug: possible racing condition while setting the event state in line 186. To resolve it line 186 should be moved between lines 152 and 153.
  • Enhancement: Replace the call to PulseEvent() with SetEvent() ResetEvent() on line 166 since the MSDN help states against using PulseEvent(). Generally, that replacement is not equivalent. However, in MSDK that is fine because access to an Event instance is serialized.

 

 

Next are the extended synchronization primitives – Blocking Counter and Semi-Mutex.

 

Published Tuesday, March 14, 2006 9:08 AM by Zlatko Michailov
Filed under:

Comments

Anonymous comments are disabled
 
Page view tracker