MLIB
Loading...
Searching...
No Matches
syncbase.h
Go to the documentation of this file.
1/*
2 Copyright (c) Mircea Neacsu (2014-2025) Licensed under MIT License.
3 This file is part of MLIB project. See LICENSE file for full license terms.
4*/
5
7
8#pragma once
9
10#if __has_include("defs.h")
11#include "defs.h"
12#endif
13
14#include "safe_winsock.h"
15
16#include <string>
17#include <atomic>
18#include <vector>
19#include <chrono>
20#include <assert.h>
21
22namespace mlib {
23
26{
27public:
28 syncbase ();
29 syncbase (const syncbase& e);
30 syncbase (syncbase&& e) noexcept;
31 virtual ~syncbase ();
32
33 syncbase& operator= (const syncbase& rhs);
34 syncbase& operator= (syncbase&& rhs) noexcept;
35 int operator== (const syncbase& rhs) const;
36
37 virtual void wait ();
38
40 virtual DWORD wait (DWORD limit_msec);
41
43 virtual DWORD wait (std::chrono::milliseconds limit);
44
45 virtual DWORD wait_alertable (DWORD limit_msec = INFINITE);
46
48 virtual DWORD wait_msg (DWORD limit_msec = INFINITE, DWORD mask = QS_ALLINPUT);
49 operator bool ();
50 virtual bool is_signaled ();
51
53 HANDLE handle () const
54 {
55 return hl->handle_;
56 };
57
59 virtual const std::string& name () const
60 {
61 return name_;
62 };
63
64protected:
65 syncbase (const std::string& name); // protected constructor
66 void set_handle (HANDLE h);
67 virtual void name (const std::string& nam);
68
69private:
70 struct handle_life
71 {
72 HANDLE handle_;
73 std::atomic_int lives;
74 }* hl;
75 std::string name_;
76};
77
79inline void syncbase::name (const std::string& nam)
80{
81 name_ = nam;
82}
83
85inline void syncbase::wait ()
86{
87 assert (hl && hl->handle_);
88 WaitForSingleObject (hl->handle_, INFINITE);
89}
90
96inline DWORD syncbase::wait (DWORD limit_msec)
97{
98 assert (hl && hl->handle_);
99 return WaitForSingleObject (hl->handle_, limit_msec);
100}
101
107inline DWORD syncbase::wait (std::chrono::milliseconds limit)
108{
109 assert (hl && hl->handle_);
110 auto limit_msec = limit.count ();
111 assert (0 < limit_msec && limit_msec < INFINITE); // must be a 32 bit value
112 return WaitForSingleObject (hl->handle_, (DWORD)limit_msec);
113}
114
117inline DWORD syncbase::wait_alertable (DWORD limit_msec)
118{
119 assert (hl && hl->handle_);
120 return WaitForSingleObjectEx (hl->handle_, limit_msec, TRUE);
121}
122
136inline DWORD syncbase::wait_msg (DWORD limit_msec, DWORD mask)
137{
138 return MsgWaitForMultipleObjects (1, &hl->handle_, FALSE, limit_msec, mask);
139}
140
142inline syncbase::operator bool ()
143{
144 return is_signaled ();
145}
146
153{
154 return (WaitForSingleObject (hl->handle_, 0) == WAIT_OBJECT_0);
155}
156
169template <typename T>
170DWORD wait_all (const T* objs, int count, DWORD msec = INFINITE)
171{
172 assert (count < MAXIMUM_WAIT_OBJECTS);
173 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
174 for (int i = 0; i < count; i++)
175 harr[i] = objs[i]->handle ();
176
177 DWORD result = WaitForMultipleObjects (count, harr, true, msec);
178 return result;
179}
180
192template <typename T>
193DWORD wait_all (std::initializer_list<const T*> objs, DWORD msec = INFINITE)
194{
195 assert (objs.size () < MAXIMUM_WAIT_OBJECTS);
196 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
197 int i = 0;
198 for (auto& p : objs)
199 harr[i++] = p->handle ();
200
201 DWORD result = WaitForMultipleObjects ((DWORD)objs.size (), harr, true, msec);
202 return result;
203}
204
216template <typename T>
217DWORD wait_all (std::initializer_list<const T*> objs, std::chrono::milliseconds limit)
218{
219 assert (objs.size () < MAXIMUM_WAIT_OBJECTS);
220 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
221 int i = 0;
222 for (auto& p : objs)
223 harr[i++] = p->handle ();
224
225 DWORD msec = (DWORD)limit.count ();
226 DWORD result = WaitForMultipleObjects ((DWORD)objs.size (), harr, true, msec);
227 return result;
228}
229
242template <typename T>
243DWORD wait_any (const T* objs, int count, DWORD msec = INFINITE)
244{
245 assert (count < MAXIMUM_WAIT_OBJECTS);
246 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
247 for (int i = 0; i < count; i++)
248 harr[i] = objs[i].handle ();
249
250 DWORD result = WaitForMultipleObjects (count, harr, false, msec);
251 return result;
252}
253
265template <typename T>
266DWORD wait_any (std::initializer_list<const T*> objs, DWORD msec = INFINITE)
267{
268 assert (objs.size () < MAXIMUM_WAIT_OBJECTS);
269 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
270 int i = 0;
271 for (auto& p : objs)
272 harr[i++] = p->handle ();
273
274 DWORD result = WaitForMultipleObjects ((DWORD)objs.size (), harr, false, msec);
275 return result;
276}
277
289template <typename T>
290DWORD wait_any (std::initializer_list<const T*> objs, std::chrono::milliseconds timeout)
291{
292 assert (objs.size () < MAXIMUM_WAIT_OBJECTS);
293 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
294 int i = 0;
295 for (auto& p : objs)
296 harr[i++] = p->handle ();
297 DWORD msec = (DWORD)timeout.count ();
298 DWORD result = WaitForMultipleObjects ((DWORD)objs.size (), harr, false, msec);
299 return result;
300}
301
316template <typename T>
317DWORD wait_msg (const T* objs, int count, bool all = true, DWORD msec = INFINITE,
318 DWORD mask = QS_ALLINPUT)
319{
320 assert (count < MAXIMUM_WAIT_OBJECTS);
321 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
322 for (int i = 0; i < count; i++)
323 harr[i] = objs[i]->handle ();
324
325 DWORD result = MsgWaitForMultipleObjects (count, harr, all, msec, mask);
326 return result;
327}
328
342template <typename T>
343DWORD wait_msg (std::initializer_list<const T*> objs, bool all = true, DWORD msec = INFINITE,
344 DWORD mask = QS_ALLINPUT)
345{
346 assert (objs.size () < MAXIMUM_WAIT_OBJECTS);
347 HANDLE harr[MAXIMUM_WAIT_OBJECTS];
348 int i = 0;
349 for (auto& p : objs)
350 harr[i++] = p->handle ();
351
352 DWORD result = MsgWaitForMultipleObjects ((DWORD)objs.size (), harr, all, msec, mask);
353 return result;
354}
355
356} // namespace mlib
HANDLE handle() const
Return OS handle of this object.
Definition syncbase.h:53
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:85
syncbase & operator=(const syncbase &rhs)
Assignment operator.
Definition syncbase.cpp:81
virtual DWORD wait_alertable(DWORD limit_msec=INFINITE)
Definition syncbase.h:117
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:59
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:136
virtual ~syncbase()
Destructor.
Definition syncbase.cpp:69
virtual bool is_signaled()
Try to wait on the object.
Definition syncbase.h:152
DWORD wait_any(const T *objs, int count, DWORD msec=INFINITE)
Wait for multiple objects until any of them becomes signaled.
Definition syncbase.h:243
DWORD wait_all(const T *objs, int count, DWORD msec=INFINITE)
Wait for multiple objects until all become signaled.
Definition syncbase.h:170
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:317