6f498847 |
1 | // Created by: Kirill Gavrilov |
2 | // Copyright (c) 2018 OPEN CASCADE SAS |
3 | // |
4 | // This file is part of Open CASCADE Technology software library. |
5 | // |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
11 | // |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
14 | |
15 | #ifdef _WIN32 |
16 | #include <windows.h> |
17 | #else |
18 | #include <pthread.h> |
19 | #include <unistd.h> |
20 | #include <errno.h> |
21 | #include <sys/time.h> |
22 | #endif |
23 | |
24 | #include "Standard_Condition.hxx" |
25 | |
26 | namespace |
27 | { |
28 | #ifndef _WIN32 |
29 | //! clock_gettime() wrapper. |
30 | static void conditionGetRealTime (struct timespec& theTime) |
31 | { |
32 | #if defined(__APPLE__) |
33 | struct timeval aTime; |
34 | gettimeofday (&aTime, NULL); |
35 | theTime.tv_sec = aTime.tv_sec; |
36 | theTime.tv_nsec = aTime.tv_usec * 1000; |
37 | #else |
38 | clock_gettime (CLOCK_REALTIME, &theTime); |
39 | #endif |
40 | } |
41 | #endif |
42 | } |
43 | |
44 | // ======================================================================= |
45 | // function : Standard_Condition |
46 | // purpose : |
47 | // ======================================================================= |
48 | Standard_Condition::Standard_Condition (bool theIsSet) |
49 | #ifdef _WIN32 |
50 | : myEvent((void* )::CreateEvent (0, true, theIsSet, NULL)) |
51 | #else |
52 | : myFlag (theIsSet) |
53 | #endif |
54 | { |
55 | #ifndef _WIN32 |
56 | pthread_mutex_init(&myMutex, 0); |
57 | pthread_cond_init (&myCond, 0); |
58 | #endif |
59 | } |
60 | |
61 | // ======================================================================= |
62 | // function : ~Standard_Condition |
63 | // purpose : |
64 | // ======================================================================= |
65 | Standard_Condition::~Standard_Condition() |
66 | { |
67 | #ifdef _WIN32 |
68 | ::CloseHandle ((HANDLE )myEvent); |
69 | #else |
70 | pthread_mutex_destroy(&myMutex); |
71 | pthread_cond_destroy (&myCond); |
72 | #endif |
73 | } |
74 | |
75 | // ======================================================================= |
76 | // function : Set |
77 | // purpose : |
78 | // ======================================================================= |
79 | void Standard_Condition::Set() |
80 | { |
81 | #ifdef _WIN32 |
82 | ::SetEvent ((HANDLE )myEvent); |
83 | #else |
84 | pthread_mutex_lock(&myMutex); |
85 | myFlag = true; |
86 | pthread_cond_broadcast(&myCond); |
87 | pthread_mutex_unlock (&myMutex); |
88 | #endif |
89 | } |
90 | |
91 | // ======================================================================= |
92 | // function : Reset |
93 | // purpose : |
94 | // ======================================================================= |
95 | void Standard_Condition::Reset() |
96 | { |
97 | #ifdef _WIN32 |
98 | ::ResetEvent ((HANDLE )myEvent); |
99 | #else |
100 | pthread_mutex_lock (&myMutex); |
101 | myFlag = false; |
102 | pthread_mutex_unlock (&myMutex); |
103 | #endif |
104 | } |
105 | |
106 | // ======================================================================= |
107 | // function : Wait |
108 | // purpose : |
109 | // ======================================================================= |
110 | void Standard_Condition::Wait() |
111 | { |
112 | #ifdef _WIN32 |
113 | ::WaitForSingleObject ((HANDLE )myEvent, INFINITE); |
114 | #else |
115 | pthread_mutex_lock (&myMutex); |
116 | if (!myFlag) |
117 | { |
118 | pthread_cond_wait (&myCond, &myMutex); |
119 | } |
120 | pthread_mutex_unlock (&myMutex); |
121 | #endif |
122 | } |
123 | |
124 | // ======================================================================= |
125 | // function : Wait |
126 | // purpose : |
127 | // ======================================================================= |
128 | bool Standard_Condition::Wait (int theTimeMilliseconds) |
129 | { |
130 | #ifdef _WIN32 |
131 | return (::WaitForSingleObject ((HANDLE )myEvent, (DWORD )theTimeMilliseconds) != WAIT_TIMEOUT); |
132 | #else |
133 | bool isSignalled = true; |
134 | pthread_mutex_lock (&myMutex); |
135 | if (!myFlag) |
136 | { |
137 | struct timespec aNow; |
138 | struct timespec aTimeout; |
139 | conditionGetRealTime (aNow); |
140 | aTimeout.tv_sec = (theTimeMilliseconds / 1000); |
141 | aTimeout.tv_nsec = (theTimeMilliseconds - aTimeout.tv_sec * 1000) * 1000000; |
142 | if (aTimeout.tv_nsec > 1000000000) |
143 | { |
144 | aTimeout.tv_sec += 1; |
145 | aTimeout.tv_nsec -= 1000000000; |
146 | } |
147 | aTimeout.tv_sec += aNow.tv_sec; |
148 | aTimeout.tv_nsec += aNow.tv_nsec; |
149 | isSignalled = (pthread_cond_timedwait (&myCond, &myMutex, &aTimeout) != ETIMEDOUT); |
150 | } |
151 | pthread_mutex_unlock (&myMutex); |
152 | return isSignalled; |
153 | #endif |
154 | } |
155 | |
156 | // ======================================================================= |
157 | // function : Check |
158 | // purpose : |
159 | // ======================================================================= |
160 | bool Standard_Condition::Check() |
161 | { |
162 | #ifdef _WIN32 |
163 | return (::WaitForSingleObject ((HANDLE )myEvent, (DWORD )0) != WAIT_TIMEOUT); |
164 | #else |
165 | bool isSignalled = true; |
166 | pthread_mutex_lock (&myMutex); |
167 | if (!myFlag) |
168 | { |
169 | struct timespec aNow; |
170 | struct timespec aTimeout; |
171 | conditionGetRealTime (aNow); |
172 | aTimeout.tv_sec = aNow.tv_sec; |
173 | aTimeout.tv_nsec = aNow.tv_nsec + 100; |
174 | isSignalled = (pthread_cond_timedwait (&myCond, &myMutex, &aTimeout) != ETIMEDOUT); |
175 | } |
176 | pthread_mutex_unlock (&myMutex); |
177 | return isSignalled; |
178 | #endif |
179 | } |
180 | |
181 | // ======================================================================= |
182 | // function : CheckReset |
183 | // purpose : |
184 | // ======================================================================= |
185 | bool Standard_Condition::CheckReset() |
186 | { |
187 | #ifdef _WIN32 |
188 | const bool wasSignalled = (::WaitForSingleObject ((HANDLE )myEvent, (DWORD )0) != WAIT_TIMEOUT); |
189 | ::ResetEvent ((HANDLE )myEvent); |
190 | return wasSignalled; |
191 | #else |
192 | pthread_mutex_lock (&myMutex); |
193 | bool wasSignalled = myFlag; |
194 | if (!myFlag) |
195 | { |
196 | struct timespec aNow; |
197 | struct timespec aTimeout; |
198 | conditionGetRealTime (aNow); |
199 | aTimeout.tv_sec = aNow.tv_sec; |
200 | aTimeout.tv_nsec = aNow.tv_nsec + 100; |
201 | wasSignalled = (pthread_cond_timedwait (&myCond, &myMutex, &aTimeout) != ETIMEDOUT); |
202 | } |
203 | myFlag = false; |
204 | pthread_mutex_unlock (&myMutex); |
205 | return wasSignalled; |
206 | #endif |
207 | } |