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
14namespace NWindows {
15namespace NSynchronization {
16
17class CBaseEvent
18{
19protected:
20  ::CEvent _object;
21public:
22  bool IsCreated() { return Event_IsCreated(&_object) != 0; }
23  operator HANDLE() { return _object; }
24  CBaseEvent() { Event_Construct(&_object); }
25  ~CBaseEvent() { 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  }
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
44  WRes Set() { return Event_Set(&_object); }
45  // bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); }
46  WRes Reset() { return Event_Reset(&_object); }
47  WRes Lock() { return Event_Wait(&_object); }
48};
49
50class CManualResetEvent: public CBaseEvent
51{
52public:
53  WRes Create(bool initiallyOwn = false)
54  {
55    return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0);
56  }
57  WRes CreateIfNotCreated()
58  {
59    if (IsCreated())
60      return 0;
61    return ManualResetEvent_CreateNotSignaled(&_object);
62  }
63  #ifdef _WIN32
64  WRes CreateWithName(bool initiallyOwn, LPCTSTR name)
65  {
66    return CBaseEvent::Create(true, initiallyOwn, name);
67  }
68  #endif
69};
70
71class CAutoResetEvent: public CBaseEvent
72{
73public:
74  WRes Create()
75  {
76    return AutoResetEvent_CreateNotSignaled(&_object);
77  }
78  WRes CreateIfNotCreated()
79  {
80    if (IsCreated())
81      return 0;
82    return AutoResetEvent_CreateNotSignaled(&_object);
83  }
84};
85
86#ifdef _WIN32
87class CObject: public CHandle
88{
89public:
90  WRes Lock(DWORD timeoutInterval = INFINITE)
91    { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); }
92};
93class CMutex: public CObject
94{
95public:
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
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
112  WRes Release()
113  {
114    return ::ReleaseMutex(_handle) ? 0 : ::GetLastError();
115  }
116};
117class CMutexLock
118{
119  CMutex *_object;
120public:
121  CMutexLock(CMutex &object): _object(&object) { _object->Lock(); }
122  ~CMutexLock() { _object->Release(); }
123};
124#endif
125
126class CSemaphore
127{
128  ::CSemaphore _object;
129public:
130  CSemaphore() { Semaphore_Construct(&_object); }
131  ~CSemaphore() { Close(); }
132  WRes Close() {  return Semaphore_Close(&_object); }
133  operator HANDLE() { return _object; }
134  WRes Create(UInt32 initiallyCount, UInt32 maxCount)
135  {
136    return Semaphore_Create(&_object, initiallyCount, maxCount);
137  }
138  WRes Release() { return Semaphore_Release1(&_object); }
139  WRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); }
140  WRes Lock() { return Semaphore_Wait(&_object); }
141};
142
143class CCriticalSection
144{
145  ::CCriticalSection _object;
146public:
147  CCriticalSection() { CriticalSection_Init(&_object); }
148  ~CCriticalSection() { CriticalSection_Delete(&_object); }
149  void Enter() { CriticalSection_Enter(&_object); }
150  void Leave() { CriticalSection_Leave(&_object); }
151};
152
153class CCriticalSectionLock
154{
155  CCriticalSection *_object;
156  void Unlock()  { _object->Leave(); }
157public:
158  CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); }
159  ~CCriticalSectionLock() { Unlock(); }
160};
161
162}}
163
164#endif
165