Listing 2: Win32Synchronizer.h
/*===========================================================*\
Class to allow blocking on any Win32 synchronization handle
such as events, semaphores, process handles, etc.
\*===========================================================*/
#if !defined(__WIN32_EVENT_SYNCHRONIZER_H__)
#define __WIN32_EVENT_SYNCHRONIZER_H__
#include <windows.h>
namespace Tx
{
template <class Exception, class Mutex>
class Win32Synchronizer
{
public:
typedef HANDLE SyncObject_t; // What to wait on
typedef Exception Exception_t;
typedef DWORD TimeDuration_t;
typedef Mutex Mutex_t;
enum {TIME_INFINITE = INFINITE};
Win32Synchronizer()
{
_signalObject =
::CreateEvent(NULL, true, false, NULL);
}
virtual ~Win32Synchronizer()
{
::CloseHandle(_signalObject);
}
//-----------------------------------------------------
// Blocking interruptible wait for syncObject
bool Wait( const SyncObject_t & syncObject,
TimeDuration_t timeout
) const
{
SyncObject_t handles[2];
handles[0] = _signalObject;
handles[1] = syncObject;
return WaitImpl(handles, 2, timeout);
}
//-----------------------------------------------------
// Blocking idle sleep that is interruptible
void Sleep(TimeDuration_t timeout) const
{
WaitImpl(&_signalObject, 1, timeout);
}
void Signal()
{
::SetEvent(_signalObject);
}
void Reset()
{
::ResetEvent(_signalObject);
}
private:
//-----------------------------------------------------
// Actual implementation of "multiple listening" wait
// behavior relying on WaitForMultipleObjects().
bool WaitImpl(
const SyncObject_t * handles,
int numHandles,
TimeDuration_t timeout // ms or TIME_INFINITE
) const
{
// Wait on both event objects simultaneously
DWORD status = ::WaitForMultipleObjects(
numHandles, handles, false, timeout
);
if (status == WAIT_TIMEOUT)
return false; // Nothing happened
else if (status == WAIT_OBJECT_0)
throw Exception_t(); // Thread signalled
else if (status == (WAIT_OBJECT_0 + 1))
return true; // Desired event is signaled
else if (status == WAIT_ABANDONED_0)
throw Exception_t();// signal event abandoned
else
return true; // Desired event is abandoned
}
// Disallow copy constructor/assignment operators
Win32Synchronizer(const Win32Synchronizer &);
Win32Synchronizer & operator=(
const Win32Synchronizer &);
SyncObject_t _signalObject;
};
}
#endif // __WIN32_EVENT_SYNCHRONIZER_H__