19 #ifndef FASTDDS_UTILS__TIMEDMUTEX_HPP
20 #define FASTDDS_UTILS__TIMEDMUTEX_HPP
27 #if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 193632528
29 #elif defined(MINGW_COMPILER)
33 extern int clock_gettime(
38 #elif _GTHREAD_USE_MUTEX_TIMEDLOCK
49 #if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 193632528
50 using TimedMutex = std::timed_mutex;
51 using RecursiveTimedMutex = std::recursive_timed_mutex;
52 #elif defined(MINGW_COMPILER)
53 using TimedMutex = std::timed_mutex;
54 using RecursiveTimedMutex = std::recursive_timed_mutex;
63 _Mtx_init(&mutex_, _Mtx_timed);
67 const TimedMutex&) =
delete;
68 TimedMutex& operator =(
69 const TimedMutex&) =
delete;
86 template<
class Rep,
class Period>
88 const std::chrono::duration<Rep, Period>& rel_time)
90 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
93 template<
class Clock,
class Duration>
95 const std::chrono::time_point<Clock, Duration>& abs_time)
97 std::chrono::nanoseconds nsecs = abs_time - Clock::now();
99 if (0 < nsecs.count())
101 struct timespec max_wait = {
104 clock_gettime(1, &max_wait);
105 nsecs = nsecs + std::chrono::nanoseconds(max_wait.tv_nsec);
106 auto secs = std::chrono::duration_cast<std::chrono::seconds>(nsecs);
108 max_wait.tv_sec += secs.count();
109 max_wait.tv_nsec = (long)nsecs.count();
110 return (_Thrd_success == _Mtx_timedlock(mutex_, (xtime*)&max_wait));
114 return (_Thrd_success == _Mtx_trylock(mutex_));
118 void* native_handle() noexcept
128 class RecursiveTimedMutex
132 RecursiveTimedMutex()
134 _Mtx_init(&mutex_, _Mtx_timed | _Mtx_recursive);
138 const TimedMutex&) =
delete;
139 RecursiveTimedMutex& operator =(
140 const TimedMutex&) =
delete;
142 ~RecursiveTimedMutex()
144 _Mtx_destroy(mutex_);
159 return (_Thrd_success == _Mtx_trylock(mutex_));
162 template<
class Rep,
class Period>
164 const std::chrono::duration<Rep, Period>& rel_time)
166 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
169 template<
class Clock,
class Duration>
171 const std::chrono::time_point<Clock, Duration>& abs_time)
173 std::chrono::nanoseconds nsecs = abs_time - Clock::now();
174 if (0 < nsecs.count())
176 struct timespec max_wait = {
179 clock_gettime(1, &max_wait);
180 nsecs = nsecs + std::chrono::nanoseconds(max_wait.tv_nsec);
181 auto secs = std::chrono::duration_cast<std::chrono::seconds>(nsecs);
183 max_wait.tv_sec += secs.count();
184 max_wait.tv_nsec = (long)nsecs.count();
185 return (_Thrd_success == _Mtx_timedlock(mutex_, (xtime*)&max_wait));
189 return (_Thrd_success == _Mtx_trylock(mutex_));
193 void* native_handle() noexcept
204 #elif _GTHREAD_USE_MUTEX_TIMEDLOCK || !defined(__unix__)
205 using TimedMutex = std::timed_mutex;
206 using RecursiveTimedMutex = std::recursive_timed_mutex;
214 pthread_mutex_init(&mutex_,
nullptr);
218 const TimedMutex&) =
delete;
219 TimedMutex& operator =(
220 const TimedMutex&) =
delete;
224 pthread_mutex_destroy(&mutex_);
229 pthread_mutex_lock(&mutex_);
234 pthread_mutex_unlock(&mutex_);
237 template<
class Rep,
class Period>
239 const std::chrono::duration<Rep, Period>& rel_time)
241 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
244 template<
class Clock,
class Duration>
246 const std::chrono::time_point<Clock, Duration>& abs_time)
248 std::chrono::nanoseconds nsecs = abs_time - Clock::now();
249 struct timespec max_wait = {
252 clock_gettime(CLOCK_REALTIME, &max_wait);
253 nsecs = nsecs + std::chrono::nanoseconds(max_wait.tv_nsec);
254 auto secs = std::chrono::duration_cast<std::chrono::seconds>(nsecs);
256 max_wait.tv_sec += secs.count();
257 max_wait.tv_nsec = (long)nsecs.count();
258 return (0 == pthread_mutex_timedlock(&mutex_, &max_wait));
261 pthread_mutex_t* native_handle() noexcept
268 pthread_mutex_t mutex_;
271 class RecursiveTimedMutex
275 RecursiveTimedMutex()
277 pthread_mutexattr_init(&mutex_attr_);
278 pthread_mutexattr_settype(&mutex_attr_, PTHREAD_MUTEX_RECURSIVE);
279 pthread_mutex_init(&mutex_, &mutex_attr_);
283 const RecursiveTimedMutex&) =
delete;
284 RecursiveTimedMutex& operator =(
285 const RecursiveTimedMutex&) =
delete;
287 ~RecursiveTimedMutex()
289 pthread_mutex_destroy(&mutex_);
290 pthread_mutexattr_destroy(&mutex_attr_);
295 pthread_mutex_lock(&mutex_);
300 pthread_mutex_unlock(&mutex_);
305 return (0 == pthread_mutex_trylock(&mutex_));
308 template<
class Rep,
class Period>
310 const std::chrono::duration<Rep, Period>& rel_time)
312 return try_lock_until(std::chrono::steady_clock::now() + rel_time);
315 template<
class Clock,
class Duration>
317 const std::chrono::time_point<Clock, Duration>& abs_time)
319 std::chrono::nanoseconds nsecs = abs_time - Clock::now();
320 struct timespec max_wait = {
323 clock_gettime(CLOCK_REALTIME, &max_wait);
324 nsecs = nsecs + std::chrono::nanoseconds(max_wait.tv_nsec);
325 auto secs = std::chrono::duration_cast<std::chrono::seconds>(nsecs);
327 max_wait.tv_sec += secs.count();
328 max_wait.tv_nsec = (long)nsecs.count();
329 return (0 == pthread_mutex_timedlock(&mutex_, &max_wait));
332 pthread_mutex_t* native_handle() noexcept
339 pthread_mutexattr_t mutex_attr_;
341 pthread_mutex_t mutex_;