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



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020