1 //===-- ThreadSpec.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_ThreadSpec_h_
10 #define liblldb_ThreadSpec_h_
11 
12 #include "lldb/Utility/StructuredData.h"
13 #include "lldb/lldb-private.h"
14 #include <string>
15 
16 namespace lldb_private {
17 
18 // Note: For now the thread spec has only fixed elements -
19 //   Thread ID
20 //   Thread Index
21 //   Thread Name
22 //   Thread Queue Name
23 //
24 //  But if we need more generality, we can hang a key/value map off of this
25 //  structure.
26 //  That's why the thread matches spec test is done as a virtual method in
27 //  Thread::MatchesSpec,
28 //  since it is the native thread that would know how to interpret the keys.
29 //  I was going to do the Queue Name this way out of sheer orneriness, but that
30 //  seems a
31 //  sufficiently general concept, so I put it in here on its own.
32 
33 class ThreadSpec {
34 public:
35   ThreadSpec();
36 
37   static std::unique_ptr<ThreadSpec>
38   CreateFromStructuredData(const StructuredData::Dictionary &data_dict,
39                            Status &error);
40 
41   StructuredData::ObjectSP SerializeToStructuredData();
42 
43   static const char *GetSerializationKey() { return "ThreadSpec"; }
44 
45   void SetIndex(uint32_t index) { m_index = index; }
46 
47   void SetTID(lldb::tid_t tid) { m_tid = tid; }
48 
49   void SetName(llvm::StringRef name) { m_name = name; }
50 
51   void SetQueueName(llvm::StringRef queue_name) { m_queue_name = queue_name; }
52 
53   uint32_t GetIndex() const { return m_index; }
54 
55   lldb::tid_t GetTID() const { return m_tid; }
56 
57   const char *GetName() const;
58 
59   const char *GetQueueName() const;
60 
61   bool TIDMatches(lldb::tid_t thread_id) const {
62     if (m_tid == LLDB_INVALID_THREAD_ID || thread_id == LLDB_INVALID_THREAD_ID)
63       return true;
64     else
65       return thread_id == m_tid;
66   }
67 
68   bool TIDMatches(Thread &thread) const;
69 
70   bool IndexMatches(uint32_t index) const {
71     if (m_index == UINT32_MAX || index == UINT32_MAX)
72       return true;
73     else
74       return index == m_index;
75   }
76 
77   bool IndexMatches(Thread &thread) const;
78 
79   bool NameMatches(const char *name) const {
80     if (m_name.empty())
81       return true;
82     else if (name == nullptr)
83       return false;
84     else
85       return m_name == name;
86   }
87 
88   bool NameMatches(Thread &thread) const;
89 
90   bool QueueNameMatches(const char *queue_name) const {
91     if (m_queue_name.empty())
92       return true;
93     else if (queue_name == nullptr)
94       return false;
95     else
96       return m_queue_name == queue_name;
97   }
98 
99   bool QueueNameMatches(Thread &thread) const;
100 
101   bool ThreadPassesBasicTests(Thread &thread) const;
102 
103   bool HasSpecification() const;
104 
105   void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
106 
107 private:
108   enum class OptionNames {
109     ThreadIndex = 0,
110     ThreadID,
111     ThreadName,
112     QueueName,
113     LastOptionName
114   };
115   static const char *g_option_names[(size_t)OptionNames::LastOptionName];
116 
117   static const char *GetKey(OptionNames enum_value) {
118     return g_option_names[(size_t) enum_value];
119   }
120 
121   uint32_t m_index;
122   lldb::tid_t m_tid;
123   std::string m_name;
124   std::string m_queue_name;
125 };
126 
127 } // namespace lldb_private
128 
129 #endif // liblldb_ThreadSpec_h_
130