MRPT  1.9.9
event.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2019, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 /*
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright notice,
14  * this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright notice,
17  * this list of conditions and the following disclaimer in the documentation
18  * and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 
34 #pragma once
35 
36 #ifndef _WIN32
37 #include <pthread.h>
38 #include <sys/time.h>
39 #else
40 #include <windows.h>
41 #endif
42 #include <cassert>
43 #include <iostream>
44 
45 namespace rp::hal
46 {
47 class Event
48 {
49  public:
50  enum
51  {
52  EVENT_OK = 1,
55  };
56 
57  Event(bool isAutoReset = true, bool isSignal = false)
58 #ifdef _WIN32
59  : _event(nullptr)
60 #else
61  : _is_signalled(isSignal), _isAutoReset(isAutoReset)
62 #endif
63  {
64 #ifdef _WIN32
65  _event = CreateEvent(
66  nullptr, isAutoReset ? FALSE : TRUE, isSignal ? TRUE : FALSE,
67  nullptr);
68 #else
69  pthread_mutex_init(&_cond_locker, nullptr);
70  pthread_cond_init(&_cond_var, nullptr);
71 #endif
72  }
73 
74  ~Event() { release(); }
75  void set(bool isSignal = true)
76  {
77  if (isSignal)
78  {
79 #ifdef _WIN32
80  SetEvent(_event);
81 #else
82  pthread_mutex_lock(&_cond_locker);
83 
84  if (_is_signalled == false)
85  {
86  _is_signalled = true;
87  pthread_cond_signal(&_cond_var);
88  }
89  pthread_mutex_unlock(&_cond_locker);
90 #endif
91  }
92  else
93  {
94 #ifdef _WIN32
95  ResetEvent(_event);
96 #else
97  pthread_mutex_lock(&_cond_locker);
98  _is_signalled = false;
99  pthread_mutex_unlock(&_cond_locker);
100 #endif
101  }
102  }
103 
104  unsigned long wait(unsigned long timeout = 0xFFFFFFFF)
105  {
106 #ifdef _WIN32
107  switch (WaitForSingleObject(
108  _event, timeout == 0xFFFFFFF ? INFINITE : (DWORD)timeout))
109  {
110  case WAIT_FAILED:
111  return EVENT_FAILED;
112  case WAIT_OBJECT_0:
113  return EVENT_OK;
114  case WAIT_TIMEOUT:
115  return EVENT_TIMEOUT;
116  }
117  return EVENT_OK;
118 #else
119  unsigned long ans = EVENT_OK;
120  pthread_mutex_lock(&_cond_locker);
121 
122  if (!_is_signalled)
123  {
124  if (timeout == 0xFFFFFFFF)
125  {
126  pthread_cond_wait(&_cond_var, &_cond_locker);
127  }
128  else
129  {
130  timespec wait_time;
131  timeval now;
132  gettimeofday(&now, nullptr);
133 
134  wait_time.tv_sec = timeout / 1000 + now.tv_sec;
135  wait_time.tv_nsec =
136  (timeout % 1000) * 1000000ULL + now.tv_usec * 1000;
137 
138  if (wait_time.tv_nsec >= 1000000000)
139  {
140  ++wait_time.tv_sec;
141  wait_time.tv_nsec -= 1000000000;
142  }
143  switch (pthread_cond_timedwait(
144  &_cond_var, &_cond_locker, &wait_time))
145  {
146  case 0:
147  // signalled
148  break;
149  case ETIMEDOUT:
150  // time up
151  ans = EVENT_TIMEOUT;
152  goto _final;
153  break;
154  default:
155  ans = EVENT_FAILED;
156  goto _final;
157  }
158  }
159  }
160 
161  assert(_is_signalled);
162 
163  if (_isAutoReset)
164  {
165  _is_signalled = false;
166  }
167  _final:
168  pthread_mutex_unlock(&_cond_locker);
169 
170  return ans;
171 #endif
172  }
173 
174  protected:
175  void release()
176  {
177 #ifdef _WIN32
178  CloseHandle(_event);
179 #else
180  pthread_mutex_destroy(&_cond_locker);
181  pthread_cond_destroy(&_cond_var);
182 #endif
183  }
184 
185 #ifdef _WIN32
186  HANDLE _event;
187 #else
188  pthread_cond_t _cond_var;
189  pthread_mutex_t _cond_locker;
190  bool _is_signalled;
191  bool _isAutoReset;
192 #endif
193 };
194 } // namespace rp::hal
Event(bool isAutoReset=true, bool isSignal=false)
Definition: event.h:57
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:86
void release()
Definition: event.h:175
#define FALSE
Definition: xmlParser.h:230
unsigned long wait(unsigned long timeout=0xFFFFFFFF)
Definition: event.h:104
#define TRUE
Definition: xmlParser.h:233
HANDLE _event
Definition: event.h:186



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 8fe78517f Sun Jul 14 19:43:28 2019 +0200 at lun oct 28 02:10:00 CET 2019