0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / Standard / Standard_Condition.cxx
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 }