46 #ifndef TIMER_MONITOR_H 47 #define TIMER_MONITOR_H 49 #if (defined(__APPLE__) && defined(__MACH__)) || defined(__OpenBSD__) 50 #define USE_KQUEUE_TIMER 52 #include <sys/event.h> 53 #include <sys/types.h> 55 #define USE_POSIX_TIMER 63 #include "final/eventloop/monitor.h" 64 #include "final/eventloop/pipedata.h" 65 #include "final/ftypes.h" 71 class SigAlrmHandlerInstaller;
72 struct KqueueHandlerInstaller;
74 #if defined(UNIT_TEST) 75 auto useAlternativeKqueueTimerID() ->
bool&;
76 auto alternativeKqueueTimerID() ->
int&;
77 #endif // defined(UNIT_TEST) 86 using Monitor::Monitor;
92 virtual void setInterval ( std::chrono::nanoseconds
93 , std::chrono::nanoseconds ) = 0;
95 void validateIntervals ( std::chrono::nanoseconds
96 , std::chrono::nanoseconds )
const;
100 inline void TimerMonitorImpl::validateIntervals ( std::chrono::nanoseconds first,
101 std::chrono::nanoseconds periodic )
const 103 if ( first.count() == 0 && periodic.count() == 0 )
105 "both first and periodic cannot be zero"};
107 if ( first.count() < 0 )
109 "must be >= 0 nanoseconds"};
111 if ( periodic.count() < 0 )
113 "must be >= 0 nanoseconds"};
124 using TimerMonitorImpl::TimerMonitorImpl;
145 template <
typename T>
146 void init (handler_t, T&&);
147 void setInterval ( std::chrono::nanoseconds
148 , std::chrono::nanoseconds )
override;
149 void trigger(
short)
override;
151 #if defined(UNIT_TEST) 152 void ReinstallSigAlrmHandler();
153 #endif // defined(UNIT_TEST) 157 void validate (
const handler_t& hdl)
const;
158 void createAlarmPipe();
160 void cleanupResources() noexcept;
162 #if defined(USE_POSIX_TIMER) 165 PipeData alarm_pipe{NO_FILE_DESCRIPTOR, NO_FILE_DESCRIPTOR};
167 #endif // defined(USE_POSIX_TIMER) 170 #if defined(USE_POSIX_TIMER) 172 template <
typename T>
173 inline void PosixTimer::init (handler_t hdl, T&& uc)
179 setHandler (std::move(hdl));
180 setUserContext (std::forward<T>(uc));
185 setHandler(handler_t{});
192 inline void PosixTimer::validate (
const handler_t& hdl)
const 194 if ( isInitialized() )
195 throw monitor_error{
"This instance has already been initialised."};
200 #endif // defined(USE_POSIX_TIMER) 211 using TimerMonitorImpl::TimerMonitorImpl;
232 template <
typename T>
233 void init (handler_t, T&&);
234 void setInterval ( std::chrono::nanoseconds
235 , std::chrono::nanoseconds )
override;
236 void trigger (
short)
override;
240 void validate (
const handler_t& hdl)
const;
241 void cleanupResources() noexcept;
243 #if defined(USE_KQUEUE_TIMER) || defined(UNIT_TEST) 251 static constexpr
int NO_TIMER_ID{-1};
254 int timer_id{NO_TIMER_ID};
255 bool first_interval{
true};
256 TimerSpec timer_spec{};
257 handler_t timer_handler{};
258 static KqueueHandlerInstaller* kqueue_handler_installer;
261 friend class KqueueHandler;
262 #endif // defined(USE_KQUEUE_TIMER) || defined(UNIT_TEST) 265 #if defined(USE_KQUEUE_TIMER) || defined(UNIT_TEST) 267 template <
typename T>
268 inline void KqueueTimer::init (handler_t hdl, T&& uc)
274 timer_handler = std::move(hdl);
275 setUserContext (std::forward<T>(uc));
280 timer_handler = handler_t{};
287 inline void KqueueTimer::validate (
const handler_t& hdl)
const 289 if ( isInitialized() )
290 throw monitor_error{
"This instance has already been initialised."};
295 if ( timer_id != NO_TIMER_ID )
298 #endif // defined(USE_KQUEUE_TIMER) || defined(UNIT_TEST) 307 #if defined(__APPLE__) && defined(__MACH__) 309 #elif defined(__OpenBSD__) 326 using base_class::base_class;
346 auto getClassName()
const ->
FString override;
351 inline auto TimerMonitor::getClassName()
const ->
FString 352 {
return "TimerMonitor"; }
356 #endif // TIMER_MONITOR_H Definition: timer_monitor.h:321
Definition: eventloop.h:49
Definition: class_template.cpp:25
Definition: timer_monitor.h:82
Definition: posix_timer.cpp:179
Definition: timer_monitor.h:120
Definition: timer_monitor.h:207
Definition: pipedata.h:48
Definition: timer_monitor.h:305