#pragma once
#ifndef __HWINSYNCH_H__
#define __HWINSYNCH_H__
#include "hwinhandle.h"
#include "hwinsecurity.h"
#include "hwindatetime.h"
#include "hwinexception.h"
namespace harlinn
{
namespace windows
{
class Timeout
{
public:
static const DWORD Infinite = INFINITE;
};
class AbandonedMutexException : public SystemException
{
public:
typedef SystemException Base;
HARLINN_WINDOWS_DECLARE_STANDARD_EXCEPTION_MEMBERS( AbandonedMutexException );
};
class WaitableHandle : public SystemHandle
{
public:
typedef SystemHandle Base;
static const int WaitTimeout = -1;
protected:
HWIN_EXPORT static void ThrowAbandonedMutexException();
explicit WaitableHandle(LPVOID theHandle, bool closeHandle = true)
: Base(theHandle, closeHandle)
{
HWIN_TRACE();
}
protected:
WaitableHandle()
{
HWIN_TRACE();
}
HWIN_EXPORT static int WaitForAnyOf(size_t numberOfHandles,HANDLE* handles,DWORD timeoutInMillis);
HWIN_EXPORT static int WaitForAnyOf(size_t numberOfHandles,HANDLE* handles,DWORD timeoutInMillis,bool alertable);
HWIN_EXPORT static int WaitForAllOf(size_t numberOfHandles,HANDLE* handles,DWORD timeoutInMillis);
HWIN_EXPORT static int WaitForAllOf(size_t numberOfHandles,HANDLE* handles,DWORD timeoutInMillis,bool alertable);
public:
HWIN_EXPORT bool Wait();
HWIN_EXPORT bool Wait(DWORD timeoutInMillis);
HWIN_EXPORT bool Wait(const TimeSpan& timeout);
HWIN_EXPORT bool Wait(bool alertable);
HWIN_EXPORT bool Wait(DWORD timeoutInMillis, bool alertable);
HWIN_EXPORT bool Wait(const TimeSpan& timeout, bool alertable);
HWIN_EXPORT static int WaitForAnyOf(const std::vector< std::shared_ptr< WaitableHandle > >& waitableHandles);
HWIN_EXPORT static int WaitForAnyOf(const std::vector< std::shared_ptr< WaitableHandle > >& waitableHandles,bool alertable);
HWIN_EXPORT static int WaitForAllOf(const std::vector< std::shared_ptr< WaitableHandle > >& waitableHandles);
HWIN_EXPORT static int WaitForAllOf(const std::vector< std::shared_ptr< WaitableHandle > >& waitableHandles,bool alertable);
HWIN_EXPORT static int WaitForAnyOf(const std::vector< std::shared_ptr< WaitableHandle > >& waitableHandles,DWORD timeoutInMillis);
HWIN_EXPORT static int WaitForAnyOf(const std::vector< std::shared_ptr< WaitableHandle > >& waitableHandles,DWORD timeoutInMillis,bool alertable);
HWIN_EXPORT static int WaitForAllOf(const std::vector< std::shared_ptr< WaitableHandle > >& waitableHandles,DWORD timeoutInMillis);
HWIN_EXPORT static int WaitForAllOf(const std::vector< std::shared_ptr< WaitableHandle > >& waitableHandles,DWORD timeoutInMillis,bool alertable);
};
enum class EventWaitHandleRights : DWORD
{
Modify = EVENT_MODIFY_STATE,
Delete = DELETE,
ReadPermissions = READ_CONTROL,
ChangePermissions = WRITE_DAC,
TakeOwnership = WRITE_OWNER,
Synchronize = SYNCHRONIZE,
FullControl = EVENT_ALL_ACCESS
};
DEFINE_ENUM_FLAG_OPERATORS(EventWaitHandleRights)
class EventWaitHandle : public WaitableHandle
{
public:
typedef WaitableHandle Base;
protected:
HWIN_EXPORT static HANDLE CreateEvent(SECURITY_ATTRIBUTES* eventAttributes, wchar_t* name, bool initiallySet, bool manualReset, EventWaitHandleRights desiredAccess);
HWIN_EXPORT static HANDLE Open(wchar_t* name,EventWaitHandleRights desiredAccess, bool inheritHandle);
public:
explicit EventWaitHandle(HANDLE theHandle, bool closeHandle = true)
: Base(theHandle, closeHandle)
{
HWIN_TRACE();
}
HWIN_EXPORT EventWaitHandle(SECURITY_ATTRIBUTES* eventAttributes, wchar_t* name, bool initiallySet, bool manualReset, EventWaitHandleRights desiredAccess = EventWaitHandleRights::FullControl);
HWIN_EXPORT EventWaitHandle(wchar_t* name, bool initiallySet, bool manualReset, EventWaitHandleRights desiredAccess = EventWaitHandleRights::FullControl);
HWIN_EXPORT EventWaitHandle(bool initiallySet, bool manualReset, EventWaitHandleRights desiredAccess = EventWaitHandleRights::FullControl);
HWIN_EXPORT static std::shared_ptr<EventWaitHandle> OpenExisting(wchar_t* name, EventWaitHandleRights desiredAccess = EventWaitHandleRights::Modify | EventWaitHandleRights::Synchronize, bool inheritHandle = false);
HWIN_EXPORT bool Set();
HWIN_EXPORT bool Reset();
};
class AutoResetEvent : public EventWaitHandle
{
public:
typedef EventWaitHandle Base;
HWIN_EXPORT AutoResetEvent(bool initiallySet);
};
class ManualResetEvent : public EventWaitHandle
{
public:
typedef EventWaitHandle Base;
HWIN_EXPORT ManualResetEvent(bool initiallySet);
};
enum class MutexRights
{
Modify = 0x000001,
Delete = 0x010000,
ReadPermissions = 0x020000,
ChangePermissions = 0x040000,
TakeOwnership = 0x080000,
Synchronize = 0x100000,
FullControl = 0x1F0001
};
DEFINE_ENUM_FLAG_OPERATORS(MutexRights)
class Mutex : public WaitableHandle
{
HWIN_EXPORT static HANDLE Create( SECURITY_ATTRIBUTES* eventAttributes, wchar_t* name, bool initiallyOwned, MutexRights desiredAccess );
HWIN_EXPORT static HANDLE Open(wchar_t* name, MutexRights desiredAccess = MutexRights::Modify | MutexRights::Synchronize , bool inheritHandle = false);
public:
typedef WaitableHandle Base;
explicit Mutex(HANDLE theHandle, bool closeHandle = true)
: Base(theHandle, closeHandle)
{
HWIN_TRACE();
}
HWIN_EXPORT Mutex( SECURITY_ATTRIBUTES* eventAttributes, wchar_t* name, bool initiallyOwned, MutexRights desiredAccess = MutexRights::FullControl );
HWIN_EXPORT Mutex( wchar_t* name, bool initiallyOwned , MutexRights desiredAccess = MutexRights::FullControl );
HWIN_EXPORT Mutex( bool initiallyOwned , MutexRights desiredAccess = MutexRights::FullControl );
HWIN_EXPORT static std::shared_ptr<Mutex> OpenExisting(wchar_t* name, MutexRights desiredAccess = MutexRights::Modify | MutexRights::Synchronize , bool inheritHandle = false);
HWIN_EXPORT Mutex& Release();
};
class CriticalSection : public Object
{
CRITICAL_SECTION criticalSection;
public:
HWIN_EXPORT CriticalSection();
HWIN_EXPORT CriticalSection(DWORD spinCount);
HWIN_EXPORT bool Wait();
HWIN_EXPORT bool TryWait();
HWIN_EXPORT CriticalSection& Release();
};
template<typename T>
class Lock
{
T& waitable;
public:
Lock(T& theWaitable)
: waitable(theWaitable)
{
waitable.Wait();
}
~Lock()
{
waitable.Release();
}
};
template< >
class Lock < std::shared_ptr< Mutex > >
{
std::shared_ptr< Mutex > mutex;
public:
Lock(std::shared_ptr< Mutex > theMutex)
: mutex(theMutex)
{
mutex->Wait();
}
~Lock()
{
mutex->Release();
}
};
template< >
class Lock < std::shared_ptr< CriticalSection > >
{
std::shared_ptr< CriticalSection > criticalSection;
public:
Lock(std::shared_ptr< CriticalSection > theCriticalSection)
: criticalSection(theCriticalSection)
{
criticalSection->Wait();
}
~Lock()
{
criticalSection->Release();
}
};
};
};
#endif //__HWINSYNCH_H__