LLDB mainline
MainLoopBase.h
Go to the documentation of this file.
1//===-- MainLoopBase.h ------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_HOST_MAINLOOPBASE_H
10#define LLDB_HOST_MAINLOOPBASE_H
11
13#include "lldb/Utility/Status.h"
14#include "llvm/ADT/DenseMap.h"
15#include "llvm/Support/ErrorHandling.h"
16#include <chrono>
17#include <functional>
18#include <mutex>
19#include <queue>
20
21namespace lldb_private {
22
23// The purpose of this class is to enable multiplexed processing of data from
24// different sources without resorting to multi-threading. Clients can register
25// IOObjects, which will be monitored for readability, and when they become
26// ready, the specified callback will be invoked. Monitoring for writability is
27// not supported, but can be easily added if needed.
28//
29// The RegisterReadObject function return a handle, which controls the duration
30// of the monitoring. When this handle is destroyed, the callback is
31// deregistered.
32//
33// Since this class is primarily intended to be used for single-threaded
34// processing, it does not attempt to perform any internal synchronisation and
35// any concurrent accesses must be protected externally. However, it is
36// perfectly legitimate to have more than one instance of this class running on
37// separate threads, or even a single thread.
39private:
40 class ReadHandle;
41
42public:
43 using TimePoint = std::chrono::time_point<std::chrono::steady_clock,
44 std::chrono::nanoseconds>;
45
47 virtual ~MainLoopBase() = default;
48
49 typedef std::unique_ptr<ReadHandle> ReadHandleUP;
50
51 typedef std::function<void(MainLoopBase &)> Callback;
52
54 const Callback &callback,
55 Status &error) = 0;
56
57 // Add a pending callback that will be executed once after all the pending
58 // events are processed. The callback will be executed even if termination
59 // was requested.
60 void AddPendingCallback(const Callback &callback) {
61 AddCallback(callback, std::chrono::steady_clock::time_point());
62 }
63
64 // Add a callback that will be executed after a certain amount of time has
65 // passed.
66 void AddCallback(const Callback &callback, std::chrono::nanoseconds delay) {
67 AddCallback(callback, std::chrono::steady_clock::now() + delay);
68 }
69
70 // Add a callback that will be executed after a given point in time.
71 void AddCallback(const Callback &callback, TimePoint point);
72
73 // Waits for registered events and invoke the proper callbacks. Returns when
74 // all callbacks deregister themselves or when someone requests termination.
75 virtual Status Run() { llvm_unreachable("Not implemented"); }
76
77 // This should only be performed from a callback. Do not attempt to terminate
78 // the processing from another thread.
79 virtual void RequestTermination() { m_terminate_request = true; }
80
81protected:
83 return ReadHandleUP(new ReadHandle(*this, object_sp->GetWaitableHandle()));
84 }
85
87
88 // Interrupt the loop that is currently waiting for events.
89 virtual void Interrupt() = 0;
90
91 void ProcessCallbacks();
92
93 std::optional<TimePoint> GetNextWakeupTime();
94
95 std::mutex m_callback_mutex;
96 std::priority_queue<std::pair<TimePoint, Callback>,
97 std::vector<std::pair<TimePoint, Callback>>,
98 llvm::on_first<std::greater<TimePoint>>>
101
102private:
104 public:
106
107 private:
109 : m_mainloop(mainloop), m_handle(handle) {}
110
113
114 friend class MainLoopBase;
115 ReadHandle(const ReadHandle &) = delete;
116 const ReadHandle &operator=(const ReadHandle &) = delete;
117 };
118
119 MainLoopBase(const MainLoopBase &) = delete;
120 const MainLoopBase &operator=(const MainLoopBase &) = delete;
121};
122
123} // namespace lldb_private
124
125#endif // LLDB_HOST_MAINLOOPBASE_H
static llvm::raw_ostream & error(Stream &strm)
IOObject::WaitableHandle m_handle
Definition: MainLoopBase.h:112
ReadHandle(const ReadHandle &)=delete
ReadHandle(MainLoopBase &mainloop, IOObject::WaitableHandle handle)
Definition: MainLoopBase.h:108
const ReadHandle & operator=(const ReadHandle &)=delete
std::unique_ptr< ReadHandle > ReadHandleUP
Definition: MainLoopBase.h:49
virtual void UnregisterReadObject(IOObject::WaitableHandle handle)=0
const MainLoopBase & operator=(const MainLoopBase &)=delete
void AddCallback(const Callback &callback, std::chrono::nanoseconds delay)
Definition: MainLoopBase.h:66
void AddPendingCallback(const Callback &callback)
Definition: MainLoopBase.h:60
std::priority_queue< std::pair< TimePoint, Callback >, std::vector< std::pair< TimePoint, Callback > >, llvm::on_first< std::greater< TimePoint > > > m_callbacks
Definition: MainLoopBase.h:99
virtual Status Run()
Definition: MainLoopBase.h:75
std::optional< TimePoint > GetNextWakeupTime()
virtual ReadHandleUP RegisterReadObject(const lldb::IOObjectSP &object_sp, const Callback &callback, Status &error)=0
ReadHandleUP CreateReadHandle(const lldb::IOObjectSP &object_sp)
Definition: MainLoopBase.h:82
virtual ~MainLoopBase()=default
MainLoopBase(const MainLoopBase &)=delete
std::function< void(MainLoopBase &)> Callback
Definition: MainLoopBase.h:51
virtual void RequestTermination()
Definition: MainLoopBase.h:79
virtual void Interrupt()=0
std::chrono::time_point< std::chrono::steady_clock, std::chrono::nanoseconds > TimePoint
Definition: MainLoopBase.h:44
An error handling class.
Definition: Status.h:115
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::IOObject > IOObjectSP
Definition: lldb-forward.h:362