1c74c17f3SPavel Labath //===-- MainLoopBase.cpp --------------------------------------------------===// 2c74c17f3SPavel Labath // 3c74c17f3SPavel Labath // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4c74c17f3SPavel Labath // See https://llvm.org/LICENSE.txt for license information. 5c74c17f3SPavel Labath // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6c74c17f3SPavel Labath // 7c74c17f3SPavel Labath //===----------------------------------------------------------------------===// 8c74c17f3SPavel Labath 9c74c17f3SPavel Labath #include "lldb/Host/MainLoopBase.h" 10*55068dc3SPavel Labath #include <chrono> 11c74c17f3SPavel Labath 12c74c17f3SPavel Labath using namespace lldb; 13c74c17f3SPavel Labath using namespace lldb_private; 14c74c17f3SPavel Labath 15*55068dc3SPavel Labath void MainLoopBase::AddCallback(const Callback &callback, TimePoint point) { 16*55068dc3SPavel Labath bool interrupt_needed; 176a8bbd26SPavel Labath { 186a8bbd26SPavel Labath std::lock_guard<std::mutex> lock{m_callback_mutex}; 19*55068dc3SPavel Labath // We need to interrupt the main thread if this callback is scheduled to 20*55068dc3SPavel Labath // execute at an earlier time than the earliest callback registered so far. 21*55068dc3SPavel Labath interrupt_needed = m_callbacks.empty() || point < m_callbacks.top().first; 22*55068dc3SPavel Labath m_callbacks.emplace(point, callback); 236a8bbd26SPavel Labath } 24*55068dc3SPavel Labath if (interrupt_needed) 25*55068dc3SPavel Labath Interrupt(); 266a8bbd26SPavel Labath } 276a8bbd26SPavel Labath 28*55068dc3SPavel Labath void MainLoopBase::ProcessCallbacks() { 29*55068dc3SPavel Labath while (true) { 30*55068dc3SPavel Labath Callback callback; 316a8bbd26SPavel Labath { 326a8bbd26SPavel Labath std::lock_guard<std::mutex> lock{m_callback_mutex}; 33*55068dc3SPavel Labath if (m_callbacks.empty() || 34*55068dc3SPavel Labath std::chrono::steady_clock::now() < m_callbacks.top().first) 35*55068dc3SPavel Labath return; 36*55068dc3SPavel Labath callback = std::move(m_callbacks.top().second); 37*55068dc3SPavel Labath m_callbacks.pop(); 386a8bbd26SPavel Labath } 396a8bbd26SPavel Labath 40c74c17f3SPavel Labath callback(*this); 41c74c17f3SPavel Labath } 42*55068dc3SPavel Labath } 43*55068dc3SPavel Labath 44*55068dc3SPavel Labath std::optional<MainLoopBase::TimePoint> MainLoopBase::GetNextWakeupTime() { 45*55068dc3SPavel Labath std::lock_guard<std::mutex> lock(m_callback_mutex); 46*55068dc3SPavel Labath if (m_callbacks.empty()) 47*55068dc3SPavel Labath return std::nullopt; 48*55068dc3SPavel Labath return m_callbacks.top().first; 49*55068dc3SPavel Labath } 50