1 //===-- ThreadList.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 liblldb_ThreadList_h_
10 #define liblldb_ThreadList_h_
11 
12 #include <mutex>
13 #include <vector>
14 
15 #include "lldb/Target/Thread.h"
16 #include "lldb/Target/ThreadCollection.h"
17 #include "lldb/Utility/Iterable.h"
18 #include "lldb/Utility/UserID.h"
19 #include "lldb/lldb-private.h"
20 
21 namespace lldb_private {
22 
23 // This is a thread list with lots of functionality for use only by the process
24 // for which this is the thread list.  A generic container class with iterator
25 // functionality is ThreadCollection.
26 class ThreadList : public ThreadCollection {
27   friend class Process;
28 
29 public:
30   ThreadList(Process *process);
31 
32   ThreadList(const ThreadList &rhs);
33 
34   ~ThreadList() override;
35 
36   const ThreadList &operator=(const ThreadList &rhs);
37 
38   uint32_t GetSize(bool can_update = true);
39 
40   // Return the selected thread if there is one.  Otherwise, return the thread
41   // selected at index 0.
42   lldb::ThreadSP GetSelectedThread();
43 
44   // Manage the thread to use for running expressions.  This is usually the
45   // Selected thread, but sometimes (e.g. when evaluating breakpoint conditions
46   // & stop hooks) it isn't.
47   class ExpressionExecutionThreadPusher {
48   public:
49     ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid)
50         : m_thread_list(&thread_list), m_tid(tid) {
51       m_thread_list->PushExpressionExecutionThread(m_tid);
52     }
53 
54     ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp);
55 
56     ~ExpressionExecutionThreadPusher() {
57       if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID)
58         m_thread_list->PopExpressionExecutionThread(m_tid);
59     }
60 
61   private:
62     ThreadList *m_thread_list;
63     lldb::tid_t m_tid;
64   };
65 
66   lldb::ThreadSP GetExpressionExecutionThread();
67 
68 protected:
69   void PushExpressionExecutionThread(lldb::tid_t tid);
70 
71   void PopExpressionExecutionThread(lldb::tid_t tid);
72 
73 public:
74   bool SetSelectedThreadByID(lldb::tid_t tid, bool notify = false);
75 
76   bool SetSelectedThreadByIndexID(uint32_t index_id, bool notify = false);
77 
78   void Clear();
79 
80   void Flush();
81 
82   void Destroy();
83 
84   // Note that "idx" is not the same as the "thread_index". It is a zero based
85   // index to accessing the current threads, whereas "thread_index" is a unique
86   // index assigned
87   lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update = true);
88 
89   lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update = true);
90 
91   lldb::ThreadSP FindThreadByProtocolID(lldb::tid_t tid,
92                                         bool can_update = true);
93 
94   lldb::ThreadSP RemoveThreadByID(lldb::tid_t tid, bool can_update = true);
95 
96   lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid,
97                                           bool can_update = true);
98 
99   lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update = true);
100 
101   lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr);
102 
103   lldb::ThreadSP GetBackingThread(const lldb::ThreadSP &real_thread);
104 
105   bool ShouldStop(Event *event_ptr);
106 
107   Vote ShouldReportStop(Event *event_ptr);
108 
109   Vote ShouldReportRun(Event *event_ptr);
110 
111   void RefreshStateAfterStop();
112 
113   /// The thread list asks tells all the threads it is about to resume.
114   /// If a thread can "resume" without having to resume the target, it
115   /// will return false for WillResume, and then the process will not be
116   /// restarted.
117   ///
118   /// \return
119   ///    \b true instructs the process to resume normally,
120   ///    \b false means start & stopped events will be generated, but
121   ///    the process will not actually run.  The thread must then return
122   ///    the correct StopInfo when asked.
123   ///
124   bool WillResume();
125 
126   void DidResume();
127 
128   void DidStop();
129 
130   void DiscardThreadPlans();
131 
132   uint32_t GetStopID() const;
133 
134   void SetStopID(uint32_t stop_id);
135 
136   std::recursive_mutex &GetMutex() const override;
137 
138   void Update(ThreadList &rhs);
139 
140 protected:
141   void SetShouldReportStop(Vote vote);
142 
143   void NotifySelectedThreadChanged(lldb::tid_t tid);
144 
145   // Classes that inherit from Process can see and modify these
146   Process *m_process; ///< The process that manages this thread list.
147   uint32_t
148       m_stop_id; ///< The process stop ID that this thread list is valid for.
149   lldb::tid_t
150       m_selected_tid; ///< For targets that need the notion of a current thread.
151   std::vector<lldb::tid_t> m_expression_tid_stack;
152 
153 private:
154   ThreadList() = delete;
155 };
156 
157 } // namespace lldb_private
158 
159 #endif // liblldb_ThreadList_h_
160