// SPDX-License-Identifier: BSD-2-Clause // Copyright CM4all GmbH // author: Max Kellermann #pragma once #include "Chrono.hxx" #include "util/BindMethod.hxx" #include "util/IntrusiveList.hxx" class EventLoop; /** * This class invokes a callback function after a certain amount of * time. Use Schedule() to start the timer or Cancel() to cancel it. * * Unlike #FineTimerEvent, this class has a granularity of about 1 * second, and is optimized for timeouts between 1 and 60 seconds * which are often canceled before they expire (i.e. optimized for * fast insertion and deletion, at the cost of granularity). * * This class is not thread-safe, all methods must be called from the * thread that runs the #EventLoop, except where explicitly documented * as thread-safe. */ class CoarseTimerEvent final : AutoUnlinkIntrusiveListHook { friend class TimerWheel; friend struct IntrusiveListBaseHookTraits; EventLoop &loop; using Callback = BoundMethod; const Callback callback; /** * When is this timer due? This is only valid if IsPending() * returns true. */ Event::TimePoint due; public: CoarseTimerEvent(EventLoop &_loop, Callback _callback) noexcept :loop(_loop), callback(_callback) {} auto &GetEventLoop() const noexcept { return loop; } constexpr auto GetDue() const noexcept { return due; } /** * Was this timer scheduled? */ bool IsPending() const noexcept { return is_linked(); } void Schedule(Event::Duration d) noexcept; /** * Like Schedule(), but is a no-op if there is a due time * earlier than the given one. */ void ScheduleEarlier(Event::Duration d) noexcept; void Cancel() noexcept { if (IsPending()) unlink(); } private: void Run() noexcept { callback(); } };