]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/lldb/Host/posix/MainLoopPosix.h
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / include / lldb / Host / posix / MainLoopPosix.h
1 //===-- MainLoopPosix.h -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef lldb_Host_posix_MainLoopPosix_h_
11 #define lldb_Host_posix_MainLoopPosix_h_
12
13 #include "lldb/Host/MainLoopBase.h"
14
15 #include "llvm/ADT/DenseMap.h"
16
17 namespace lldb_private {
18
19 // Posix implementation of the MainLoopBase class. It can monitor file
20 // descriptors for
21 // readability using pselect. In addition to the common base, this class
22 // provides the ability to
23 // invoke a given handler when a signal is received.
24 //
25 // Since this class is primarily intended to be used for single-threaded
26 // processing, it does not
27 // attempt to perform any internal synchronisation and any concurrent accesses
28 // must be protected
29 // externally. However, it is perfectly legitimate to have more than one
30 // instance of this class
31 // running on separate threads, or even a single thread (with some limitations
32 // on signal
33 // monitoring).
34 // TODO: Add locking if this class is to be used in a multi-threaded context.
35 class MainLoopPosix : public MainLoopBase {
36 private:
37   class SignalHandle;
38
39 public:
40   typedef std::unique_ptr<SignalHandle> SignalHandleUP;
41
42   ~MainLoopPosix() override;
43
44   ReadHandleUP RegisterReadObject(const lldb::IOObjectSP &object_sp,
45                                   const Callback &callback,
46                                   Error &error) override;
47
48   // Listening for signals from multiple MainLoopPosix instances is perfectly
49   // safe as long as they
50   // don't try to listen for the same signal. The callback function is invoked
51   // when the control
52   // returns to the Run() function, not when the hander is executed. This means
53   // that you can
54   // treat the callback as a normal function and perform things which would not
55   // be safe in a
56   // signal handler. However, since the callback is not invoked synchronously,
57   // you cannot use
58   // this mechanism to handle SIGSEGV and the like.
59   SignalHandleUP RegisterSignal(int signo, const Callback &callback,
60                                 Error &error);
61
62   Error Run() override;
63
64   // This should only be performed from a callback. Do not attempt to terminate
65   // the processing
66   // from another thread.
67   // TODO: Add synchronization if we want to be terminated from another thread.
68   void RequestTermination() override { m_terminate_request = true; }
69
70 protected:
71   void UnregisterReadObject(IOObject::WaitableHandle handle) override;
72
73   void UnregisterSignal(int signo);
74
75 private:
76   class SignalHandle {
77   public:
78     ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo); }
79
80   private:
81     SignalHandle(MainLoopPosix &mainloop, int signo)
82         : m_mainloop(mainloop), m_signo(signo) {}
83
84     MainLoopPosix &m_mainloop;
85     int m_signo;
86
87     friend class MainLoopPosix;
88     DISALLOW_COPY_AND_ASSIGN(SignalHandle);
89   };
90
91   struct SignalInfo {
92     Callback callback;
93     struct sigaction old_action;
94     bool was_blocked : 1;
95   };
96
97   llvm::DenseMap<IOObject::WaitableHandle, Callback> m_read_fds;
98   llvm::DenseMap<int, SignalInfo> m_signals;
99   bool m_terminate_request : 1;
100 };
101
102 } // namespace lldb_private
103
104 #endif // lldb_Host_posix_MainLoopPosix_h_