Main MRPT website > C++ reference for MRPT 1.9.9
event.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://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 namespace rp
36 {
37 namespace hal
38 {
39 class Event
40 {
41  public:
42  enum
43  {
44  EVENT_OK = 1,
47  };
48 
49  Event(bool isAutoReset = true, bool isSignal = false)
50 #ifdef _WIN32
51  : _event(nullptr)
52 #else
53  : _is_signalled(isSignal), _isAutoReset(isAutoReset)
54 #endif
55  {
56 #ifdef _WIN32
57  _event = CreateEvent(
58  nullptr, isAutoReset ? FALSE : TRUE, isSignal ? TRUE : FALSE,
59  nullptr);
60 #else
61  pthread_mutex_init(&_cond_locker, nullptr);
62  pthread_cond_init(&_cond_var, nullptr);
63 #endif
64  }
65 
66  ~Event() { release(); }
67  void set(bool isSignal = true)
68  {
69  if (isSignal)
70  {
71 #ifdef _WIN32
72  SetEvent(_event);
73 #else
74  pthread_mutex_lock(&_cond_locker);
75 
76  if (_is_signalled == false)
77  {
78  _is_signalled = true;
79  pthread_cond_signal(&_cond_var);
80  }
81  pthread_mutex_unlock(&_cond_locker);
82 #endif
83  }
84  else
85  {
86 #ifdef _WIN32
87  ResetEvent(_event);
88 #else
89  pthread_mutex_lock(&_cond_locker);
90  _is_signalled = false;
91  pthread_mutex_unlock(&_cond_locker);
92 #endif
93  }
94  }
95 
96  unsigned long wait(unsigned long timeout = 0xFFFFFFFF)
97  {
98 #ifdef _WIN32
99  switch (WaitForSingleObject(
100  _event, timeout == 0xFFFFFFF ? INFINITE : (DWORD)timeout))
101  {
102  case WAIT_FAILED:
103  return EVENT_FAILED;
104  case WAIT_OBJECT_0:
105  return EVENT_OK;
106  case WAIT_TIMEOUT:
107  return EVENT_TIMEOUT;
108  }
109  return EVENT_OK;
110 #else
111  unsigned long ans = EVENT_OK;
112  pthread_mutex_lock(&_cond_locker);
113 
114  if (!_is_signalled)
115  {
116  if (timeout == 0xFFFFFFFF)
117  {
118  pthread_cond_wait(&_cond_var, &_cond_locker);
119  }
120  else
121  {
122  timespec wait_time;
123  timeval now;
124  gettimeofday(&now, nullptr);
125 
126  wait_time.tv_sec = timeout / 1000 + now.tv_sec;
127  wait_time.tv_nsec =
128  (timeout % 1000) * 1000000ULL + now.tv_usec * 1000;
129 
130  if (wait_time.tv_nsec >= 1000000000)
131  {
132  ++wait_time.tv_sec;
133  wait_time.tv_nsec -= 1000000000;
134  }
135  switch (pthread_cond_timedwait(
136  &_cond_var, &_cond_locker, &wait_time))
137  {
138  case 0:
139  // signalled
140  break;
141  case ETIMEDOUT:
142  // time up
143  ans = EVENT_TIMEOUT;
144  goto _final;
145  break;
146  default:
147  ans = EVENT_FAILED;
148  goto _final;
149  }
150  }
151  }
152 
153  assert(_is_signalled);
154 
155  if (_isAutoReset)
156  {
157  _is_signalled = false;
158  }
159  _final:
160  pthread_mutex_unlock(&_cond_locker);
161 
162  return ans;
163 #endif
164  }
165 
166  protected:
167  void release()
168  {
169 #ifdef _WIN32
170  CloseHandle(_event);
171 #else
172  pthread_mutex_destroy(&_cond_locker);
173  pthread_cond_destroy(&_cond_var);
174 #endif
175  }
176 
177 #ifdef _WIN32
178  HANDLE _event;
179 #else
180  pthread_cond_t _cond_var;
181  pthread_mutex_t _cond_locker;
182  bool _is_signalled;
183  bool _isAutoReset;
184 #endif
185 };
186 }
187 }
Event(bool isAutoReset=true, bool isSignal=false)
Definition: event.h:49
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:76
#define FALSE
Definition: jmorecfg.h:216
void release()
Definition: event.h:167
#define TRUE
Definition: jmorecfg.h:219
unsigned long wait(unsigned long timeout=0xFFFFFFFF)
Definition: event.h:96
HANDLE _event
Definition: event.h:178



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019