NVIDIA Iray API Home  Up
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
condition.h
Go to the documentation of this file.
1 //*****************************************************************************
2 // Copyright 1986, 2016 NVIDIA Corporation. All rights reserved.
3 //*****************************************************************************
9 //*****************************************************************************
10 
11 #ifndef MI_BASE_CONDITION_H
12 #define MI_BASE_CONDITION_H
13 
14 #include <mi/base/config.h>
15 #include <mi/base/types.h>
16 
17 #ifndef MI_PLATFORM_WINDOWS
18 #include <cerrno>
19 #include <pthread.h>
20 #include <sys/time.h>
21 #else
22 #include <mi/base/miwindows.h>
23 #endif
24 
25 namespace mi {
26 
27 namespace base {
28 
33 class Condition
35 {
36 public:
39  {
40 #ifndef MI_PLATFORM_WINDOWS
41  m_signaled = false;
42  pthread_mutex_init( &m_mutex, NULL);
43  pthread_cond_init( &m_condvar, NULL);
44 #else
45  m_handle = CreateEvent( NULL, false, false, NULL);
46 #endif
47  }
48 
51  {
52 #ifndef MI_PLATFORM_WINDOWS
53  pthread_mutex_destroy( &m_mutex);
54  pthread_cond_destroy( &m_condvar);
55 #else
56  CloseHandle( m_handle);
57 #endif
58  }
59 
63  void wait()
64  {
65 #ifndef MI_PLATFORM_WINDOWS
66  pthread_mutex_lock( &m_mutex);
67  while( !m_signaled)
68  pthread_cond_wait( &m_condvar, &m_mutex);
69  m_signaled = false;
70  pthread_mutex_unlock( &m_mutex);
71 #else
72  WaitForSingleObject( m_handle, INFINITE);
73 #endif
74  }
75 
83  bool timed_wait( Float64 timeout) {
84 #ifndef MI_PLATFORM_WINDOWS
85  struct timeval now;
86  gettimeofday( &now, NULL);
87  struct timespec timeout_abs;
88  timeout_abs.tv_sec = now.tv_sec + static_cast<long>( floor( timeout));
89  timeout_abs.tv_nsec
90  = 1000 * now.tv_usec + static_cast<long>( 1E9 * ( timeout - floor( timeout)));
91  if( timeout_abs.tv_nsec > 1000000000) {
92  timeout_abs.tv_sec += 1;
93  timeout_abs.tv_nsec -= 1000000000;
94  }
95 
96  bool timed_out = false;
97  pthread_mutex_lock( &m_mutex);
98  while( !m_signaled)
99  {
100  int result = pthread_cond_timedwait( &m_condvar, &m_mutex, &timeout_abs);
101  timed_out = result == ETIMEDOUT;
102  if( result != EINTR)
103  break;
104  }
105  m_signaled = false;
106  pthread_mutex_unlock( &m_mutex);
107  return timed_out;
108 #else
109  DWORD timeout_ms = static_cast<DWORD>( 1000 * timeout);
110  DWORD result = WaitForSingleObject( m_handle, timeout_ms);
111  return result == WAIT_TIMEOUT;
112 #endif
113  }
114 
123  void signal()
124  {
125 #ifndef MI_PLATFORM_WINDOWS
126  pthread_mutex_lock( &m_mutex);
127  m_signaled = true;
128  pthread_cond_signal( &m_condvar);
129  pthread_mutex_unlock( &m_mutex);
130 #else
131  SetEvent( m_handle);
132 #endif
133  }
134 
138  void reset()
139  {
140 #ifndef MI_PLATFORM_WINDOWS
141  pthread_mutex_lock( &m_mutex);
142  m_signaled = false;
143  pthread_mutex_unlock( &m_mutex);
144 #else
145  ResetEvent( m_handle);
146 #endif
147  }
148 
149 private:
150 #ifndef MI_PLATFORM_WINDOWS
151  pthread_mutex_t m_mutex;
154  pthread_cond_t m_condvar;
156  bool m_signaled;
157 #else
158  HANDLE m_handle;
160 #endif
161 };
162  // end group mi_base_threads
164 
165 } // namespace base
166 
167 } // namespace mi
168 
169 #endif // MI_BASE_CONDITION_H