xref: /llvm-project/lldb/source/Host/common/MainLoopBase.cpp (revision 55068dc3b7725f24de82dd4510162865c91a4f5e)
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