Fast RTPS  Version 2.14.1
Fast RTPS
Loading...
Searching...
No Matches
TimedMutex.hpp
1// Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
19#ifndef _UTILS_TIMEDMUTEX_HPP_
20#define _UTILS_TIMEDMUTEX_HPP_
21
22#include <chrono>
23#include <iostream>
24
25#if defined(_WIN32)
26
27#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 193632528
28#include <mutex>
29#else
30#include <thread>
31extern int clock_gettime(
32 int,
33 struct timespec* tv);
34#endif // if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 193632528
35
36#elif _GTHREAD_USE_MUTEX_TIMEDLOCK
37#include <mutex>
38#else
39#include <pthread.h>
40#endif // if defined(_WIN32)
41
42namespace eprosima {
43namespace fastrtps {
44
45#if defined(_WIN32)
46
47#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 193632528
48using TimedMutex = std::timed_mutex;
49using RecursiveTimedMutex = std::recursive_timed_mutex;
50#else
51class TimedMutex
52{
53
54public:
55
57 {
58 _Mtx_init(&mutex_, _Mtx_timed);
59 }
60
62 const TimedMutex&) = delete;
63 TimedMutex& operator =(
64 const TimedMutex&) = delete;
65
66 ~TimedMutex()
67 {
68 _Mtx_destroy(mutex_);
69 }
70
71 void lock()
72 {
73 _Mtx_lock(mutex_);
74 }
75
76 void unlock()
77 {
78 _Mtx_unlock(mutex_);
79 }
80
81 template <class Rep, class Period>
82 bool try_lock_for(
83 const std::chrono::duration<Rep, Period>& rel_time)
84 {
85 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
86 }
87
88 template <class Clock, class Duration>
89 bool try_lock_until(
90 const std::chrono::time_point<Clock, Duration>& abs_time)
91 {
92 std::chrono::nanoseconds nsecs = abs_time - Clock::now();
93
94 if (0 < nsecs.count())
95 {
96 struct timespec max_wait = {
97 0, 0
98 };
99 clock_gettime(1, &max_wait);
100 nsecs = nsecs + std::chrono::nanoseconds(max_wait.tv_nsec);
101 auto secs = std::chrono::duration_cast<std::chrono::seconds>(nsecs);
102 nsecs -= secs;
103 max_wait.tv_sec += secs.count();
104 max_wait.tv_nsec = (long)nsecs.count();
105 return (_Thrd_success == _Mtx_timedlock(mutex_, (xtime*)&max_wait));
106 }
107 else
108 {
109 return (_Thrd_success == _Mtx_trylock(mutex_));
110 }
111 }
112
113 void* native_handle() noexcept
114 {
115 return mutex_;
116 }
117
118private:
119
120 _Mtx_t mutex_;
121};
122
124{
125public:
126
128 {
129 _Mtx_init(&mutex_, _Mtx_timed | _Mtx_recursive);
130 }
131
133 const TimedMutex&) = delete;
134 RecursiveTimedMutex& operator =(
135 const TimedMutex&) = delete;
136
137 ~RecursiveTimedMutex()
138 {
139 _Mtx_destroy(mutex_);
140 }
141
142 void lock()
143 {
144 _Mtx_lock(mutex_);
145 }
146
147 void unlock()
148 {
149 _Mtx_unlock(mutex_);
150 }
151
152 bool try_lock()
153 {
154 return (_Thrd_success == _Mtx_trylock(mutex_));
155 }
156
157 template <class Rep, class Period>
158 bool try_lock_for(
159 const std::chrono::duration<Rep, Period>& rel_time)
160 {
161 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
162 }
163
164 template <class Clock, class Duration>
165 bool try_lock_until(
166 const std::chrono::time_point<Clock, Duration>& abs_time)
167 {
168 std::chrono::nanoseconds nsecs = abs_time - Clock::now();
169 if (0 < nsecs.count())
170 {
171 struct timespec max_wait = {
172 0, 0
173 };
174 clock_gettime(1, &max_wait);
175 nsecs = nsecs + std::chrono::nanoseconds(max_wait.tv_nsec);
176 auto secs = std::chrono::duration_cast<std::chrono::seconds>(nsecs);
177 nsecs -= secs;
178 max_wait.tv_sec += secs.count();
179 max_wait.tv_nsec = (long)nsecs.count();
180 return (_Thrd_success == _Mtx_timedlock(mutex_, (xtime*)&max_wait));
181 }
182 else
183 {
184 return (_Thrd_success == _Mtx_trylock(mutex_));
185 }
186 }
187
188 void* native_handle() noexcept
189 {
190 return mutex_;
191 }
192
193private:
194
195 _Mtx_t mutex_;
196};
197#endif // if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 193632528
198
199#elif _GTHREAD_USE_MUTEX_TIMEDLOCK || !defined(__unix__)
200using TimedMutex = std::timed_mutex;
201using RecursiveTimedMutex = std::recursive_timed_mutex;
202#else
203class TimedMutex
204{
205public:
206
207 TimedMutex()
208 {
209 pthread_mutex_init(&mutex_, nullptr);
210 }
211
213 const TimedMutex&) = delete;
214 TimedMutex& operator =(
215 const TimedMutex&) = delete;
216
218 {
219 pthread_mutex_destroy(&mutex_);
220 }
221
222 void lock()
223 {
224 pthread_mutex_lock(&mutex_);
225 }
226
227 void unlock()
228 {
229 pthread_mutex_unlock(&mutex_);
230 }
231
232 template <class Rep, class Period>
233 bool try_lock_for(
234 const std::chrono::duration<Rep, Period>& rel_time)
235 {
236 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
237 }
238
239 template <class Clock, class Duration>
240 bool try_lock_until(
241 const std::chrono::time_point<Clock, Duration>& abs_time)
242 {
243 std::chrono::nanoseconds nsecs = abs_time - Clock::now();
244 struct timespec max_wait = {
245 0, 0
246 };
247 clock_gettime(CLOCK_REALTIME, &max_wait);
248 nsecs = nsecs + std::chrono::nanoseconds(max_wait.tv_nsec);
249 auto secs = std::chrono::duration_cast<std::chrono::seconds>(nsecs);
250 nsecs -= secs;
251 max_wait.tv_sec += secs.count();
252 max_wait.tv_nsec = (long)nsecs.count();
253 return (0 == pthread_mutex_timedlock(&mutex_, &max_wait));
254 }
255
256 pthread_mutex_t* native_handle() noexcept
257 {
258 return &mutex_;
259 }
260
261private:
262
263 pthread_mutex_t mutex_;
264};
265
267{
268public:
269
271 {
272 pthread_mutexattr_init(&mutex_attr_);
273 pthread_mutexattr_settype(&mutex_attr_, PTHREAD_MUTEX_RECURSIVE);
274 pthread_mutex_init(&mutex_, &mutex_attr_);
275 }
276
278 const RecursiveTimedMutex&) = delete;
279 RecursiveTimedMutex& operator =(
280 const RecursiveTimedMutex&) = delete;
281
282 ~RecursiveTimedMutex()
283 {
284 pthread_mutex_destroy(&mutex_);
285 pthread_mutexattr_destroy(&mutex_attr_);
286 }
287
288 void lock()
289 {
290 pthread_mutex_lock(&mutex_);
291 }
292
293 void unlock()
294 {
295 pthread_mutex_unlock(&mutex_);
296 }
297
298 bool try_lock()
299 {
300 return (0 == pthread_mutex_trylock(&mutex_));
301 }
302
303 template <class Rep, class Period>
304 bool try_lock_for(
305 const std::chrono::duration<Rep, Period>& rel_time)
306 {
307 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
308 }
309
310 template <class Clock, class Duration>
311 bool try_lock_until(
312 const std::chrono::time_point<Clock, Duration>& abs_time)
313 {
314 std::chrono::nanoseconds nsecs = abs_time - Clock::now();
315 struct timespec max_wait = {
316 0, 0
317 };
318 clock_gettime(CLOCK_REALTIME, &max_wait);
319 nsecs = nsecs + std::chrono::nanoseconds(max_wait.tv_nsec);
320 auto secs = std::chrono::duration_cast<std::chrono::seconds>(nsecs);
321 nsecs -= secs;
322 max_wait.tv_sec += secs.count();
323 max_wait.tv_nsec = (long)nsecs.count();
324 return (0 == pthread_mutex_timedlock(&mutex_, &max_wait));
325 }
326
327 pthread_mutex_t* native_handle() noexcept
328 {
329 return &mutex_;
330 }
331
332private:
333
334 pthread_mutexattr_t mutex_attr_;
335
336 pthread_mutex_t mutex_;
337};
338
339#endif //_WIN32
340
341} //namespace fastrtps
342} //namespace eprosima
343
344#endif // _UTILS_TIMEDMUTEX_HPP_
std::recursive_timed_mutex RecursiveTimedMutex
Definition TimedMutex.hpp:201
std::timed_mutex TimedMutex
Definition TimedMutex.hpp:200
eProsima namespace.
Definition LibrarySettingsAttributes.h:23