Coverage Report

Created: 2023-09-21 18:56

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Host/posix/MainLoopPosix.h
Line
Count
Source
1
//===-- MainLoopPosix.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_POSIX_MAINLOOPPOSIX_H
10
#define LLDB_HOST_POSIX_MAINLOOPPOSIX_H
11
12
#include "lldb/Host/Config.h"
13
#include "lldb/Host/MainLoopBase.h"
14
#include "lldb/Host/Pipe.h"
15
#include "llvm/ADT/DenseMap.h"
16
#include <atomic>
17
#include <csignal>
18
#include <list>
19
#include <vector>
20
21
namespace lldb_private {
22
23
// Implementation of the MainLoopBase class. It can monitor file descriptors for
24
// readability using ppoll, kqueue, or pselect. In addition to the common base,
25
// this class provides the ability to invoke a given handler when a signal is
26
// received.
27
class MainLoopPosix : public MainLoopBase {
28
private:
29
  class SignalHandle;
30
31
public:
32
  typedef std::unique_ptr<SignalHandle> SignalHandleUP;
33
34
  MainLoopPosix();
35
  ~MainLoopPosix() override;
36
37
  ReadHandleUP RegisterReadObject(const lldb::IOObjectSP &object_sp,
38
                                  const Callback &callback,
39
                                  Status &error) override;
40
41
  // Listening for signals from multiple MainLoop instances is perfectly safe
42
  // as long as they don't try to listen for the same signal. The callback
43
  // function is invoked when the control returns to the Run() function, not
44
  // when the hander is executed. This mean that you can treat the callback as
45
  // a normal function and perform things which would not be safe in a signal
46
  // handler. However, since the callback is not invoked synchronously, you
47
  // cannot use this mechanism to handle SIGSEGV and the like.
48
  SignalHandleUP RegisterSignal(int signo, const Callback &callback,
49
                                Status &error);
50
51
  Status Run() override;
52
53
protected:
54
  void UnregisterReadObject(IOObject::WaitableHandle handle) override;
55
  void UnregisterSignal(int signo, std::list<Callback>::iterator callback_it);
56
57
  void TriggerPendingCallbacks() override;
58
59
private:
60
  void ProcessReadObject(IOObject::WaitableHandle handle);
61
  void ProcessSignal(int signo);
62
63
  class SignalHandle {
64
  public:
65
9
    ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo, m_callback_it); }
66
67
  private:
68
    SignalHandle(MainLoopPosix &mainloop, int signo,
69
                 std::list<Callback>::iterator callback_it)
70
9
        : m_mainloop(mainloop), m_signo(signo), m_callback_it(callback_it) {}
71
72
    MainLoopPosix &m_mainloop;
73
    int m_signo;
74
    std::list<Callback>::iterator m_callback_it;
75
76
    friend class MainLoopPosix;
77
    SignalHandle(const SignalHandle &) = delete;
78
    const SignalHandle &operator=(const SignalHandle &) = delete;
79
  };
80
81
  struct SignalInfo {
82
    std::list<Callback> callbacks;
83
    struct sigaction old_action;
84
    bool was_blocked : 1;
85
  };
86
  class RunImpl;
87
88
  llvm::DenseMap<IOObject::WaitableHandle, Callback> m_read_fds;
89
  llvm::DenseMap<int, SignalInfo> m_signals;
90
  Pipe m_trigger_pipe;
91
  std::atomic<bool> m_triggering;
92
#if HAVE_SYS_EVENT_H
93
  int m_kqueue;
94
#endif
95
};
96
97
} // namespace lldb_private
98
99
#endif // LLDB_HOST_POSIX_MAINLOOPPOSIX_H