1 // Copyright Maciej Sobczak 2008-2019.
2 // This file is part of YAMI4.
3 //
4 // YAMI4 is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // YAMI4 is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with YAMI4. If not, see <http://www.gnu.org/licenses/>.
16
17 #include "flag.h"
18 #include <yami4-core/fatal_errors.h>
19 #include <sys/timeb.h>
20
21 using namespace yami;
22 using namespace details;
23
flag()24 details::flag::flag()
25 {
26 event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
27 if (event_ == NULL)
28 {
29 fatal_failure(__FILE__, __LINE__);
30 }
31 }
32
~flag()33 details::flag::~flag()
34 {
35 CloseHandle(event_);
36 }
37
notify()38 void details::flag::notify()
39 {
40 // note: this object acts as a latch,
41 // which means that once notified it stays in this state until suppressed
42
43 BOOL cc = SetEvent(event_);
44 if (cc == FALSE)
45 {
46 fatal_failure(__FILE__, __LINE__);
47 }
48 }
49
suppress()50 void details::flag::suppress()
51 {
52 // note: this object acts as a latch,
53 // which means that once suppressed it stays in this state until notified
54
55 BOOL cc = ResetEvent(event_);
56 if (cc == FALSE)
57 {
58 fatal_failure(__FILE__, __LINE__);
59 }
60 }
61
wait()62 void details::flag::wait()
63 {
64 DWORD cc = WaitForSingleObject(event_, INFINITE);
65 if (cc != WAIT_OBJECT_0)
66 {
67 fatal_failure(__FILE__, __LINE__);
68 }
69 }
70
wait(std::size_t relative_timeout)71 bool details::flag::wait(std::size_t relative_timeout)
72 {
73 DWORD cc = WaitForSingleObject(event_, relative_timeout);
74 if (cc != WAIT_OBJECT_0 && cc != WAIT_TIMEOUT)
75 {
76 fatal_failure(__FILE__, __LINE__);
77 }
78
79 return cc == WAIT_OBJECT_0;
80 }
81
wait_absolute(unsigned long long timeout)82 bool details::flag::wait_absolute(unsigned long long timeout)
83 {
84 _timeb now;
85
86 _ftime(&now);
87
88 const long long now_millisecs =
89 static_cast<long long>(now.time) * 1000 + now.millitm / 1000;
90
91 std::size_t relative_timeout;
92 if (timeout > now_millisecs)
93 {
94 // assume that the difference fits in size_t
95 relative_timeout = timeout - now_millisecs;
96 }
97 else
98 {
99 relative_timeout = 0;
100 }
101
102 return wait(relative_timeout);
103 }
104