MLIB
Loading...
Searching...
No Matches
syncbase.h
Go to the documentation of this file.
1
6#pragma once
7
8#if __has_include("defs.h")
9#include "defs.h"
10#endif
11
12#include "safe_winsock.h"
13
14#ifndef _INC_WINDOWS
15#include <windows.h>
16#endif
17#include <string>
18#include <atomic>
19#include <vector>
20#include <chrono>
21#include <assert.h>
22
23namespace mlib {
24
27{
28public:
29 syncbase ();
30 syncbase (const syncbase& e);
31 syncbase (syncbase&& e) noexcept;
32 virtual ~syncbase ();
33
34 syncbase& operator= (const syncbase& rhs);
35 syncbase& operator= (syncbase&& rhs) noexcept;
36 int operator== (const syncbase& rhs) const;
37
38 virtual void wait ();
39
41 virtual DWORD wait (DWORD limit_msec);
42
44 virtual DWORD wait (std::chrono::milliseconds limit);
45
46 virtual DWORD wait_alertable (DWORD limit_msec = INFINITE);
47
49 virtual DWORD wait_msg (DWORD limit_msec = INFINITE, DWORD mask = QS_ALLINPUT);
50 operator bool ();
51 virtual bool is_signaled ();
52
54 HANDLE handle () const
55 {
56 return hl->handle_;
57 };
58
60 virtual const std::string& name () const
61 {
62 return name_;
63 };
64
65protected:
66 syncbase (const std::string& name); // protected constructor
67 void set_handle (HANDLE h);
68 virtual void name (const std::string& nam);
69
70private:
71 struct handle_life
72 {
73 HANDLE handle_;
74 std::atomic_int lives;
75 }* hl;
76 std::string name_;
77};
78
80inline void syncbase::name (const std::string& nam)
81{
82 name_ = nam;
83}
84
86inline void syncbase::wait ()
87{
88 assert (hl && hl->handle_);
89 WaitForSingleObject (hl->handle_, INFINITE);
90}
91
97inline DWORD syncbase::wait (DWORD limit_msec)
98{
99 assert (hl && hl->handle_);
100 return WaitForSingleObject (hl->handle_, limit_msec);
101}
102
108inline DWORD syncbase::wait (std::chrono::milliseconds limit)
109{
110 assert (hl && hl->handle_);
111 auto limit_msec = limit.count ();
112 assert (0 < limit_msec && limit_msec < INFINITE); // must be a 32 bit value
113 return WaitForSingleObject (hl->handle_, (DWORD)limit_msec);
114}
115
118inline DWORD syncbase::wait_alertable (DWORD limit_msec)
119{
120 assert (hl && hl->handle_);
121 return WaitForSingleObjectEx (hl->handle_, limit_msec, TRUE);
122}
123
137inline DWORD syncbase::wait_msg (DWORD limit_msec, DWORD mask)
138{
139 return MsgWaitForMultipleObjects (1, &hl->handle_, FALSE, limit_msec, mask);
140}
141
143inline syncbase::operator bool ()
144{
145 return is_signaled ();
146}
147
154{
155 return (WaitForSingleObject (hl->handle_, 0) == WAIT_OBJECT_0);
156}
157
170template <typename T>
171DWORD wait_all (const T* objs, int count, DWORD msec = INFINITE)
172{
173 assert (count < MAXIMUM_WAIT_OBJECTS);
174 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
175 for (int i = 0; i < count; i++)
176 harr[i] = objs[i]->handle ();
177
178 DWORD result = WaitForMultipleObjects (count, harr, true, msec);
179 return result;
180}
181
193template <typename T>
194DWORD wait_all (std::initializer_list<const T*> objs, DWORD msec = INFINITE)
195{
196 assert (objs.size () < MAXIMUM_WAIT_OBJECTS);
197 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
198 int i = 0;
199 for (auto& p : objs)
200 harr[i++] = p->handle ();
201
202 DWORD result = WaitForMultipleObjects ((DWORD)objs.size (), harr, true, msec);
203 return result;
204}
205
217template <typename T>
218DWORD wait_all (std::initializer_list<const T*> objs, std::chrono::milliseconds limit)
219{
220 assert (objs.size () < MAXIMUM_WAIT_OBJECTS);
221 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
222 int i = 0;
223 for (auto& p : objs)
224 harr[i++] = p->handle ();
225
226 DWORD msec = (DWORD)limit.count ();
227 DWORD result = WaitForMultipleObjects ((DWORD)objs.size (), harr, true, msec);
228 return result;
229}
230
243template <typename T>
244DWORD wait_any (const T* objs, int count, DWORD msec = INFINITE)
245{
246 assert (count < MAXIMUM_WAIT_OBJECTS);
247 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
248 for (int i = 0; i < count; i++)
249 harr[i] = objs[i].handle ();
250
251 DWORD result = WaitForMultipleObjects (count, harr, false, msec);
252 return result;
253}
254
266template <typename T>
267DWORD wait_any (std::initializer_list<const T*> objs, DWORD msec = INFINITE)
268{
269 assert (objs.size () < MAXIMUM_WAIT_OBJECTS);
270 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
271 int i = 0;
272 for (auto& p : objs)
273 harr[i++] = p->handle ();
274
275 DWORD result = WaitForMultipleObjects ((DWORD)objs.size (), harr, false, msec);
276 return result;
277}
278
290template <typename T>
291DWORD wait_any (std::initializer_list<const T*> objs, std::chrono::milliseconds timeout)
292{
293 assert (objs.size () < MAXIMUM_WAIT_OBJECTS);
294 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
295 int i = 0;
296 for (auto& p : objs)
297 harr[i++] = p->handle ();
298 DWORD msec = (DWORD)timeout.count ();
299 DWORD result = WaitForMultipleObjects ((DWORD)objs.size (), harr, false, msec);
300 return result;
301}
302
317template <typename T>
318DWORD wait_msg (const T* objs, int count, bool all = true, DWORD msec = INFINITE,
319 DWORD mask = QS_ALLINPUT)
320{
321 assert (count < MAXIMUM_WAIT_OBJECTS);
322 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
323 for (int i = 0; i < count; i++)
324 harr[i] = objs[i]->handle ();
325
326 DWORD result = MsgWaitForMultipleObjects (count, harr, all, msec, mask);
327 return result;
328}
329
343template <typename T>
344DWORD wait_msg (std::initializer_list<const T*> objs, bool all = true, DWORD msec = INFINITE,
345 DWORD mask = QS_ALLINPUT)
346{
347 assert (objs.size () < MAXIMUM_WAIT_OBJECTS);
348 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
349 int i = 0;
350 for (auto& p : objs)
351 harr[i++] = p->handle ();
352
353 DWORD result = MsgWaitForMultipleObjects ((DWORD)objs.size (), harr, all, msec, mask);
354 return result;
355}
356
357} // namespace mlib
Base class for all named synchronization objects.
Definition syncbase.h:27
HANDLE handle() const
Return OS handle of this object.
Definition syncbase.h:54
void set_handle(HANDLE h)
Change object's handle. Closes the previous one.
Definition syncbase.cpp:125
syncbase()
Default constructor.
Definition syncbase.cpp:37
virtual void wait()
Wait for object to become signaled.
Definition syncbase.h:86
syncbase & operator=(const syncbase &rhs)
Assignment operator.
Definition syncbase.cpp:81
virtual DWORD wait_alertable(DWORD limit_msec=INFINITE)
Definition syncbase.h:118
int operator==(const syncbase &rhs) const
Equality operator.
Definition syncbase.cpp:119
virtual const std::string & name() const
Return object's name.
Definition syncbase.h:60
virtual DWORD wait_msg(DWORD limit_msec=INFINITE, DWORD mask=QS_ALLINPUT)
Wait for object to become signaled or a message to be queued.
Definition syncbase.h:137
virtual ~syncbase()
Destructor.
Definition syncbase.cpp:69
virtual bool is_signaled()
Try to wait on the object.
Definition syncbase.h:153
DWORD wait_any(const T *objs, int count, DWORD msec=INFINITE)
Wait for multiple objects until any of them becomes signaled.
Definition syncbase.h:244
DWORD wait_all(const T *objs, int count, DWORD msec=INFINITE)
Wait for multiple objects until all become signaled.
Definition syncbase.h:171
DWORD wait_msg(const T *objs, int count, bool all=true, DWORD msec=INFINITE, DWORD mask=QS_ALLINPUT)
Wait for multiple objects or a message to be queued.
Definition syncbase.h:318