YDLIDAR SDK  V1.4.5
locker.h
1 #pragma once
2 #ifdef _WIN32
3 #include <conio.h>
4 #include <windows.h>
5 #include <process.h>
6 #include <tlhelp32.h>
7 #include <sys/utime.h>
8 #include <io.h>
9 #include <direct.h>
10 #else
11 #include <assert.h>
12 #include <pthread.h>
13 #include <sys/time.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <errno.h>
17 #endif
18 
19 
20 class Locker {
21  public:
22  enum LOCK_STATUS {
23  LOCK_OK = 0,
24  LOCK_TIMEOUT = -1,
25  LOCK_FAILED = -2
26  };
27 
28  Locker() {
29 #ifdef _WIN32
30  _lock = NULL;
31 #endif
32  init();
33  }
34 
35  ~Locker() {
36  release();
37  }
38 
39  Locker::LOCK_STATUS lock(unsigned long timeout = 0xFFFFFFFF) {
40 #ifdef _WIN32
41 
42  switch (WaitForSingleObject(_lock,
43  timeout == 0xFFFFFFF ? INFINITE : (DWORD)timeout)) {
44  case WAIT_ABANDONED:
45  return LOCK_FAILED;
46 
47  case WAIT_OBJECT_0:
48  return LOCK_OK;
49 
50  case WAIT_TIMEOUT:
51  return LOCK_TIMEOUT;
52  }
53 
54 #else
55 #ifdef _MACOS
56 
57  if (timeout != 0) {
58  if (pthread_mutex_lock(&_lock) == 0) {
59  return LOCK_OK;
60  }
61  }
62 
63 #else
64 
65  if (timeout == 0xFFFFFFFF) {
66  if (pthread_mutex_lock(&_lock) == 0) {
67  return LOCK_OK;
68  }
69  }
70 
71 #endif
72  else if (timeout == 0) {
73  if (pthread_mutex_trylock(&_lock) == 0) {
74  return LOCK_OK;
75  }
76  }
77 
78 #ifndef _MACOS
79  else {
80  timespec wait_time;
81  timeval now;
82  gettimeofday(&now, NULL);
83 
84  wait_time.tv_sec = timeout / 1000 + now.tv_sec;
85  wait_time.tv_nsec = (timeout % 1000) * 1000000 + now.tv_usec * 1000;
86 
87  if (wait_time.tv_nsec >= 1000000000) {
88  ++wait_time.tv_sec;
89  wait_time.tv_nsec -= 1000000000;
90  }
91 
92 #if !defined(__ANDROID__)
93 
94  switch (pthread_mutex_timedlock(&_lock, &wait_time)) {
95  case 0:
96  return LOCK_OK;
97 
98  case ETIMEDOUT:
99  return LOCK_TIMEOUT;
100  }
101 
102 #else
103  struct timeval timenow;
104  struct timespec sleepytime;
105  /* This is just to avoid a completely busy wait */
106  sleepytime.tv_sec = 0;
107  sleepytime.tv_nsec = 10000000; /* 10ms */
108 
109  while (pthread_mutex_trylock(&_lock) == EBUSY) {
110  gettimeofday(&timenow, NULL);
111 
112  if (timenow.tv_sec >= wait_time.tv_sec &&
113  (timenow.tv_usec * 1000) >= wait_time.tv_nsec) {
114  return LOCK_TIMEOUT;
115  }
116 
117  nanosleep(&sleepytime, NULL);
118  }
119 
120  return LOCK_OK;
121 
122 #endif
123 
124  }
125 
126 #endif
127 #endif
128 
129  return LOCK_FAILED;
130  }
131 
132 
133  void unlock() {
134 #ifdef _WIN32
135  ReleaseMutex(_lock);
136 #else
137  pthread_mutex_unlock(&_lock);
138 #endif
139  }
140 
141 #ifdef _WIN32
142  HANDLE getLockHandle() {
143  return _lock;
144  }
145 #else
146  pthread_mutex_t *getLockHandle() {
147  return &_lock;
148  }
149 #endif
150 
151 
152 
153  protected:
154  void init() {
155 #ifdef _WIN32
156  _lock = CreateMutex(NULL, FALSE, NULL);
157 #else
158  pthread_mutex_init(&_lock, NULL);
159 #endif
160  }
161 
162  void release() {
163  unlock();
164 #ifdef _WIN32
165 
166  if (_lock) {
167  CloseHandle(_lock);
168  }
169 
170  _lock = NULL;
171 #else
172  pthread_mutex_destroy(&_lock);
173 #endif
174  }
175 
176 #ifdef _WIN32
177  HANDLE _lock;
178 #else
179  pthread_mutex_t _lock;
180 #endif
181 };
182 
183 
184 class Event {
185  public:
186 
187  enum {
188  EVENT_OK = 1,
189  EVENT_TIMEOUT = 2,
190  EVENT_FAILED = 0,
191  };
192 
193  explicit Event(bool isAutoReset = true, bool isSignal = false)
194 #ifdef _WIN32
195  : _event(NULL)
196 #else
197  : _is_signalled(isSignal)
198  , _isAutoReset(isAutoReset)
199 #endif
200  {
201 #ifdef _WIN32
202  _event = CreateEvent(NULL, isAutoReset ? FALSE : TRUE, isSignal ? TRUE : FALSE,
203  NULL);
204 #else
205  int ret = pthread_condattr_init(&_cond_cattr);
206 
207  if (ret != 0) {
208  fprintf(stderr, "Failed to init condattr...\n");
209  fflush(stderr);
210  }
211 
212  ret = pthread_condattr_setclock(&_cond_cattr, CLOCK_MONOTONIC);
213  pthread_mutex_init(&_cond_locker, NULL);
214  ret = pthread_cond_init(&_cond_var, &_cond_cattr);
215 #endif
216  }
217 
218  ~ Event() {
219  release();
220  }
221 
222  void set(bool isSignal = true) {
223  if (isSignal) {
224 #ifdef _WIN32
225  SetEvent(_event);
226 #else
227  pthread_mutex_lock(&_cond_locker);
228 
229  if (_is_signalled == false) {
230  _is_signalled = true;
231  pthread_cond_signal(&_cond_var);
232  }
233 
234  pthread_mutex_unlock(&_cond_locker);
235 #endif
236  } else {
237 #ifdef _WIN32
238  ResetEvent(_event);
239 #else
240  pthread_mutex_lock(&_cond_locker);
241  _is_signalled = false;
242  pthread_mutex_unlock(&_cond_locker);
243 #endif
244  }
245  }
246 
247  unsigned long wait(unsigned long timeout = 0xFFFFFFFF) {
248 #ifdef _WIN32
249 
250  switch (WaitForSingleObject(_event,
251  timeout == 0xFFFFFFF ? INFINITE : (DWORD)timeout)) {
252  case WAIT_FAILED:
253  return EVENT_FAILED;
254 
255  case WAIT_OBJECT_0:
256  return EVENT_OK;
257 
258  case WAIT_TIMEOUT:
259  return EVENT_TIMEOUT;
260  }
261 
262  return EVENT_OK;
263 #else
264  unsigned long ans = EVENT_OK;
265  pthread_mutex_lock(&_cond_locker);
266 
267  if (!_is_signalled) {
268  if (timeout == 0xFFFFFFFF) {
269  pthread_cond_wait(&_cond_var, &_cond_locker);
270  } else {
271  struct timespec wait_time;
272  clock_gettime(CLOCK_MONOTONIC, &wait_time);
273 
274 
275  wait_time.tv_sec += timeout / 1000;
276  wait_time.tv_nsec += (timeout % 1000) * 1000000ULL;
277 
278  if (wait_time.tv_nsec >= 1000000000) {
279  ++wait_time.tv_sec;
280  wait_time.tv_nsec -= 1000000000;
281  }
282 
283  switch (pthread_cond_timedwait(&_cond_var, &_cond_locker, &wait_time)) {
284  case 0:
285  // signalled
286  break;
287 
288  case ETIMEDOUT:
289  // time up
290  ans = EVENT_TIMEOUT;
291  goto _final;
292  break;
293 
294  default:
295  ans = EVENT_FAILED;
296  goto _final;
297  }
298 
299  }
300  }
301 
302  assert(_is_signalled);
303 
304  if (_isAutoReset) {
305  _is_signalled = false;
306  }
307 
308 _final:
309  pthread_mutex_unlock(&_cond_locker);
310 
311  return ans;
312 #endif
313 
314  }
315  protected:
316 
317  void release() {
318 #ifdef _WIN32
319  CloseHandle(_event);
320 #else
321  pthread_condattr_destroy(&_cond_cattr);
322  pthread_mutex_destroy(&_cond_locker);
323  pthread_cond_destroy(&_cond_var);
324 #endif
325  }
326 
327 #ifdef _WIN32
328  HANDLE _event;
329 #else
330  pthread_condattr_t _cond_cattr;
331  pthread_cond_t _cond_var;
332  pthread_mutex_t _cond_locker;
333  bool _is_signalled;
334  bool _isAutoReset;
335 #endif
336 };
337 
339  public :
340  explicit ScopedLocker(Locker &l): _binded(l) {
341  _binded.lock();
342  }
343 
344  void forceUnlock() {
345  _binded.unlock();
346  }
347  ~ScopedLocker() {
348  _binded.unlock();
349  }
350  Locker &_binded;
351 };
352 
353 
Definition: locker.h:184
Definition: locker.h:338
Definition: locker.h:20