LLDB  mainline
MainLoop.h
Go to the documentation of this file.
1 //===-- MainLoop.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_MAINLOOP_H
10 #define LLDB_HOST_MAINLOOP_H
11 
12 #include "lldb/Host/Config.h"
13 #include "lldb/Host/MainLoopBase.h"
14 #include "llvm/ADT/DenseMap.h"
15 #include <csignal>
16 #include <list>
17 
18 #if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__)
19 #define SIGNAL_POLLING_UNSUPPORTED 1
20 #endif
21 
22 namespace lldb_private {
23 
24 // Implementation of the MainLoopBase class. It can monitor file descriptors
25 // for readability using ppoll, kqueue, poll or WSAPoll. On Windows it only
26 // supports polling sockets, and will not work on generic file handles or
27 // pipes. On systems without kqueue or ppoll handling singnals is not
28 // supported. In addition to the common base, this class provides the ability
29 // to invoke a given handler when a signal is received.
30 //
31 // Since this class is primarily intended to be used for single-threaded
32 // processing, it does not attempt to perform any internal synchronisation and
33 // any concurrent accesses must be protected externally. However, it is
34 // perfectly legitimate to have more than one instance of this class running on
35 // separate threads, or even a single thread (with some limitations on signal
36 // monitoring).
37 // TODO: Add locking if this class is to be used in a multi-threaded context.
38 class MainLoop : public MainLoopBase {
39 private:
40  class SignalHandle;
41 
42 public:
43  typedef std::unique_ptr<SignalHandle> SignalHandleUP;
44 
45  MainLoop();
46  ~MainLoop() override;
47 
48  ReadHandleUP RegisterReadObject(const lldb::IOObjectSP &object_sp,
49  const Callback &callback,
50  Status &error) override;
51 
52  // Listening for signals from multiple MainLoop instances is perfectly safe
53  // as long as they don't try to listen for the same signal. The callback
54  // function is invoked when the control returns to the Run() function, not
55  // when the hander is executed. This mean that you can treat the callback as
56  // a normal function and perform things which would not be safe in a signal
57  // handler. However, since the callback is not invoked synchronously, you
58  // cannot use this mechanism to handle SIGSEGV and the like.
59  SignalHandleUP RegisterSignal(int signo, const Callback &callback,
60  Status &error);
61 
62  Status Run() override;
63 
64  // This should only be performed from a callback. Do not attempt to terminate
65  // the processing from another thread.
66  // TODO: Add synchronization if we want to be terminated from another thread.
67  void RequestTermination() override { m_terminate_request = true; }
68 
69 protected:
70  void UnregisterReadObject(IOObject::WaitableHandle handle) override;
71 
72  void UnregisterSignal(int signo, std::list<Callback>::iterator callback_it);
73 
74 private:
76  void ProcessSignal(int signo);
77 
78  class SignalHandle {
79  public:
81 
82  private:
83  SignalHandle(MainLoop &mainloop, int signo,
84  std::list<Callback>::iterator callback_it)
85  : m_mainloop(mainloop), m_signo(signo), m_callback_it(callback_it) {}
86 
88  int m_signo;
89  std::list<Callback>::iterator m_callback_it;
90 
91  friend class MainLoop;
92  SignalHandle(const SignalHandle &) = delete;
93  const SignalHandle &operator=(const SignalHandle &) = delete;
94  };
95 
96  struct SignalInfo {
97  std::list<Callback> callbacks;
98 #ifndef SIGNAL_POLLING_UNSUPPORTED
99  struct sigaction old_action;
100 #endif
101  bool was_blocked : 1;
102  };
103  class RunImpl;
104 
105  llvm::DenseMap<IOObject::WaitableHandle, Callback> m_read_fds;
106  llvm::DenseMap<int, SignalInfo> m_signals;
107 #if HAVE_SYS_EVENT_H
108  int m_kqueue;
109 #endif
111 };
112 
113 } // namespace lldb_private
114 
115 #endif // LLDB_HOST_MAINLOOP_H
lldb_private::MainLoop::MainLoop
MainLoop()
Definition: MainLoop.cpp:258
lldb_private::MainLoop::RegisterReadObject
ReadHandleUP RegisterReadObject(const lldb::IOObjectSP &object_sp, const Callback &callback, Status &error) override
Definition: MainLoop.cpp:272
lldb_private::MainLoop::SignalHandle::m_callback_it
std::list< Callback >::iterator m_callback_it
Definition: MainLoop.h:89
lldb_private::MainLoop::Run
Status Run() override
Definition: MainLoop.cpp:390
lldb_private::MainLoop::ProcessSignal
void ProcessSignal(int signo)
Definition: MainLoop.cpp:408
lldb_private::MainLoop::ProcessReadObject
void ProcessReadObject(IOObject::WaitableHandle handle)
Definition: MainLoop.cpp:420
lldb_private::MainLoop::SignalHandle::~SignalHandle
~SignalHandle()
Definition: MainLoop.h:80
lldb_private::MainLoop::UnregisterSignal
void UnregisterSignal(int signo, std::list< Callback >::iterator callback_it)
Definition: MainLoop.cpp:356
lldb_private::MainLoopBase
Definition: MainLoopBase.h:31
lldb_private::MainLoop::RegisterSignal
SignalHandleUP RegisterSignal(int signo, const Callback &callback, Status &error)
Definition: MainLoop.cpp:300
lldb_private::MainLoopBase::ReadHandleUP
std::unique_ptr< ReadHandle > ReadHandleUP
Definition: MainLoopBase.h:39
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::MainLoop::m_terminate_request
bool m_terminate_request
Definition: MainLoop.h:110
lldb_private::MainLoop::SignalInfo::was_blocked
bool was_blocked
Definition: MainLoop.h:101
lldb_private::MainLoop::RunImpl
Definition: MainLoop.cpp:72
lldb_private::IOObject::WaitableHandle
int WaitableHandle
Definition: IOObject.h:29
lldb_private::MainLoop::m_signals
llvm::DenseMap< int, SignalInfo > m_signals
Definition: MainLoop.h:106
lldb_private::MainLoop::SignalHandle::m_mainloop
MainLoop & m_mainloop
Definition: MainLoop.h:87
lldb_private::Status
Definition: Status.h:44
lldb_private::MainLoop::SignalHandle
Definition: MainLoop.h:78
lldb_private::MainLoop::UnregisterReadObject
void UnregisterReadObject(IOObject::WaitableHandle handle) override
Definition: MainLoop.cpp:350
lldb_private::MainLoop::SignalInfo
Definition: MainLoop.h:96
lldb_private::MainLoop
Definition: MainLoop.h:38
lldb_private::MainLoop::SignalHandleUP
std::unique_ptr< SignalHandle > SignalHandleUP
Definition: MainLoop.h:40
lldb_private::MainLoop::m_read_fds
llvm::DenseMap< IOObject::WaitableHandle, Callback > m_read_fds
Definition: MainLoop.h:103
lldb_private::MainLoop::SignalHandle::m_signo
int m_signo
Definition: MainLoop.h:88
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::MainLoop::SignalInfo::callbacks
std::list< Callback > callbacks
Definition: MainLoop.h:97
lldb_private::MainLoopBase::Callback
std::function< void(MainLoopBase &)> Callback
Definition: MainLoopBase.h:41
lldb_private::MainLoop::SignalHandle::SignalHandle
SignalHandle(MainLoop &mainloop, int signo, std::list< Callback >::iterator callback_it)
Definition: MainLoop.h:83
MainLoopBase.h
lldb_private::MainLoop::~MainLoop
~MainLoop() override
Definition: MainLoop.cpp:264
lldb_private::MainLoop::RequestTermination
void RequestTermination() override
Definition: MainLoop.h:67
lldb_private::MainLoop::SignalHandle::operator=
const SignalHandle & operator=(const SignalHandle &)=delete