//===-- Alarm.h -------------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLDB_HOST_ALARM_H #define LLDB_HOST_ALARM_H #include "lldb/Host/HostThread.h" #include "lldb/lldb-types.h" #include "llvm/Support/Chrono.h" #include #include namespace lldb_private { /// \class Alarm abstraction that enables scheduling a callback function after a /// specified timeout. Creating an alarm for a callback returns a Handle that /// can be used to restart or cancel the alarm. class Alarm { public: using Handle = uint64_t; using Callback = std::function; using TimePoint = llvm::sys::TimePoint<>; using Duration = std::chrono::milliseconds; Alarm(Duration timeout, bool run_callback_on_exit = false); ~Alarm(); /// Create an alarm for the given callback. The alarm will expire and the /// callback will be called after the timeout. /// /// \returns /// Handle which can be used to restart or cancel the alarm. Handle Create(Callback callback); /// Restart the alarm for the given Handle. The alarm will expire and the /// callback will be called after the timeout. /// /// \returns /// True if the alarm was successfully restarted. False if there is no alarm /// for the given Handle or the alarm already expired. bool Restart(Handle handle); /// Cancel the alarm for the given Handle. The alarm and its handle will be /// removed. /// /// \returns /// True if the alarm was successfully canceled and the Handle removed. /// False if there is no alarm for the given Handle or the alarm already /// expired. bool Cancel(Handle handle); static constexpr Handle INVALID_HANDLE = 0; private: /// Helper functions to start, stop and check the status of the alarm thread. /// @{ void StartAlarmThread(); void StopAlarmThread(); bool AlarmThreadRunning(); /// @} /// Return an unique, monotonically increasing handle. static Handle GetNextUniqueHandle(); /// Helper to compute the next time the alarm thread needs to wake up. TimePoint GetNextExpiration() const; /// Alarm entry. struct Entry { Handle handle; Callback callback; TimePoint expiration; Entry(Callback callback, TimePoint expiration); bool operator==(const Entry &rhs) { return handle == rhs.handle; } }; /// List of alarm entries. std::vector m_entries; /// Timeout between when an alarm is created and when it fires. Duration m_timeout; /// The alarm thread. /// @{ HostThread m_alarm_thread; lldb::thread_result_t AlarmThread(); /// @} /// Synchronize access between the alarm thread and the main thread. std::mutex m_alarm_mutex; /// Condition variable used to wake up the alarm thread. std::condition_variable m_alarm_cv; /// Flag to signal the alarm thread that something changed and we need to /// recompute the next alarm. bool m_recompute_next_alarm = false; /// Flag to signal the alarm thread to exit. bool m_exit = false; /// Flag to signal we should run all callbacks on exit. bool m_run_callbacks_on_exit = false; }; } // namespace lldb_private #endif // LLDB_HOST_ALARM_H