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