/* * @copyright Copyright (c) 2022 Woven Alpha, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include struct timer_task { void (*run)(timer_task const* task, uint32_t events); void* data; }; typedef void (*evtimer_cb)(void*); class EventTimer { public: /** * @brief Constructor of EventTimer * @param[in] clock The type of clock for a timer * @param[in] callback a callback to run when a timer alarmes * @param[in] callback_data an arument for a callback * @return EventTimer * @retval an instance of EventTimer * @relation * internal */ explicit EventTimer(int clock, evtimer_cb callback, void* callback_data); ~EventTimer(); EventTimer(const EventTimer&) = delete; const EventTimer& operator=(const EventTimer&) = delete; static uint32_t watched_fd; static int evfd; int m_timerfd; struct itimerspec m_timerspec{}; struct timer_task m_task{}; evtimer_cb m_callback; void* m_callback_data; /** * @brief clock epoll fd * @return void * @relation * internal */ static void close_evfd(); /** * @brief specify timer spec * @param[in] rate repeat rate * @param[in] delay repeat delay * @return void * @relation * internal */ void set_timerspec(int32_t rate, int32_t delay); /** * @brief run when a timer alarmes * @return void * @relation * internal */ void arm() const; /** * @brief run when a timer is stopped * @return void * @relation * internal */ void disarm() const; /** * @brief register timerfd * @return void * @relation * internal */ void watch_timerfd(); /** * @brief unregister timerfd * @return void * @relation * internal */ void unwatch_timerfd() const; /** * @brief run callback * @param[in] task the set of data for callback * @param[in] events triggered events on epoll() * @return void * @relation * internal */ static void run(timer_task const* task, uint32_t events); /** * @brief check epoll events * @return void * @relation * internal */ static void wait_event(); private: /** * @brief an internal func for arm/disarm * @param[in] fd timer fd * @param[in] timerspec timerspec * @return void * @relation * internal */ static void _arm(int fd, itimerspec const* timerspec); /** * @brief an internal func for watch_timerfd * @param[in] fd timer fd * @param[in] events observed events * @param[in] task the set of data for callback * @return void * @relation * internal */ static void _watch_fd(int fd, uint32_t events, struct timer_task* task); /** * @brief an internal func for unwatch_timerfd * @param[in] fd timer fd * @return void * @relation * internal */ static void _unwatch_fd(int fd); };