1 // Windows/Synchronization.h
2 
3 #ifndef __WINDOWS_SYNCHRONIZATION_H
4 #define __WINDOWS_SYNCHRONIZATION_H
5 
6 #include "../../C/Threads.h"
7 
8 #include "Defs.h"
9 
10 #ifdef _WIN32
11 #include "Handle.h"
12 #endif
13 
14 namespace NWindows {
15 namespace NSynchronization {
16 
17 class CBaseEvent
18 {
19 protected:
20   ::CEvent _object;
21 public:
IsCreated()22   bool IsCreated() { return Event_IsCreated(&_object) != 0; }
HANDLE()23   operator HANDLE() { return _object; }
CBaseEvent()24   CBaseEvent() { Event_Construct(&_object); }
~CBaseEvent()25   ~CBaseEvent() { Close(); }
Close()26   WRes Close() { return Event_Close(&_object); }
27   #ifdef _WIN32
28   WRes Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES sa = NULL)
29   {
30     _object = ::CreateEvent(sa, BoolToBOOL(manualReset), BoolToBOOL(initiallyOwn), name);
31     if (name == NULL && _object != 0)
32       return 0;
33     return ::GetLastError();
34   }
Open(DWORD desiredAccess,bool inheritHandle,LPCTSTR name)35   WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
36   {
37     _object = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name);
38     if (_object != 0)
39       return 0;
40     return ::GetLastError();
41   }
42   #endif
43 
Set()44   WRes Set() { return Event_Set(&_object); }
45   // bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); }
Reset()46   WRes Reset() { return Event_Reset(&_object); }
Lock()47   WRes Lock() { return Event_Wait(&_object); }
48 };
49 
50 class CManualResetEvent: public CBaseEvent
51 {
52 public:
53   WRes Create(bool initiallyOwn = false)
54   {
55     return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0);
56   }
CreateIfNotCreated()57   WRes CreateIfNotCreated()
58   {
59     if (IsCreated())
60       return 0;
61     return ManualResetEvent_CreateNotSignaled(&_object);
62   }
63   #ifdef _WIN32
CreateWithName(bool initiallyOwn,LPCTSTR name)64   WRes CreateWithName(bool initiallyOwn, LPCTSTR name)
65   {
66     return CBaseEvent::Create(true, initiallyOwn, name);
67   }
68   #endif
69 };
70 
71 class CAutoResetEvent: public CBaseEvent
72 {
73 public:
Create()74   WRes Create()
75   {
76     return AutoResetEvent_CreateNotSignaled(&_object);
77   }
CreateIfNotCreated()78   WRes CreateIfNotCreated()
79   {
80     if (IsCreated())
81       return 0;
82     return AutoResetEvent_CreateNotSignaled(&_object);
83   }
84 };
85 
86 #ifdef _WIN32
87 class CObject: public CHandle
88 {
89 public:
90   WRes Lock(DWORD timeoutInterval = INFINITE)
91     { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); }
92 };
93 class CMutex: public CObject
94 {
95 public:
96   WRes Create(bool initiallyOwn, LPCTSTR name = NULL, LPSECURITY_ATTRIBUTES sa = NULL)
97   {
98     _handle = ::CreateMutex(sa, BoolToBOOL(initiallyOwn), name);
99     if (name == NULL && _handle != 0)
100       return 0;
101     return ::GetLastError();
102   }
103   #ifndef UNDER_CE
Open(DWORD desiredAccess,bool inheritHandle,LPCTSTR name)104   WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
105   {
106     _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name);
107     if (_handle != 0)
108       return 0;
109     return ::GetLastError();
110   }
111   #endif
Release()112   WRes Release()
113   {
114     return ::ReleaseMutex(_handle) ? 0 : ::GetLastError();
115   }
116 };
117 class CMutexLock
118 {
119   CMutex *_object;
120 public:
CMutexLock(CMutex & object)121   CMutexLock(CMutex &object): _object(&object) { _object->Lock(); }
~CMutexLock()122   ~CMutexLock() { _object->Release(); }
123 };
124 #endif
125 
126 class CSemaphore
127 {
128   ::CSemaphore _object;
129 public:
CSemaphore()130   CSemaphore() { Semaphore_Construct(&_object); }
~CSemaphore()131   ~CSemaphore() { Close(); }
Close()132   WRes Close() {  return Semaphore_Close(&_object); }
HANDLE()133   operator HANDLE() { return _object; }
Create(UInt32 initiallyCount,UInt32 maxCount)134   WRes Create(UInt32 initiallyCount, UInt32 maxCount)
135   {
136     return Semaphore_Create(&_object, initiallyCount, maxCount);
137   }
Release()138   WRes Release() { return Semaphore_Release1(&_object); }
Release(UInt32 releaseCount)139   WRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); }
Lock()140   WRes Lock() { return Semaphore_Wait(&_object); }
141 };
142 
143 class CCriticalSection
144 {
145   ::CCriticalSection _object;
146 public:
CCriticalSection()147   CCriticalSection() { CriticalSection_Init(&_object); }
~CCriticalSection()148   ~CCriticalSection() { CriticalSection_Delete(&_object); }
Enter()149   void Enter() { CriticalSection_Enter(&_object); }
Leave()150   void Leave() { CriticalSection_Leave(&_object); }
151 };
152 
153 class CCriticalSectionLock
154 {
155   CCriticalSection *_object;
Unlock()156   void Unlock()  { _object->Leave(); }
157 public:
CCriticalSectionLock(CCriticalSection & object)158   CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); }
~CCriticalSectionLock()159   ~CCriticalSectionLock() { Unlock(); }
160 };
161 
162 }}
163 
164 #endif
165