Change inferior thread list to be a thread map
[deliverable/binutils-gdb.git] / gdb / thread-iter.h
1 /* Thread iterators and ranges for GDB, the GNU debugger.
2 Copyright (C) 2018-2019 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19 #ifndef THREAD_ITER_H
20 #define THREAD_ITER_H
21
22 #include "gdbsupport/filtered-iterator.h"
23 #include "gdbsupport/next-iterator.h"
24 #include "gdbsupport/safe-iterator.h"
25 #include "thread-map.h"
26
27 /* A forward iterator that iterates over a given inferior's
28 threads. */
29
30 using inf_threads_iterator = next_iterator<thread_info>;
31
32 /* A forward iterator that iterates over all threads of all
33 inferiors. */
34
35 class all_threads_iterator
36 {
37 public:
38 typedef all_threads_iterator self_type;
39 typedef struct thread_info *value_type;
40 typedef struct thread_info *&reference;
41 typedef struct thread_info **pointer;
42 typedef std::forward_iterator_tag iterator_category;
43 typedef int difference_type;
44
45 /* Tag type. */
46 struct begin_t {};
47
48 /* Create an iterator that points to the first thread of the first
49 inferior. */
50 explicit all_threads_iterator (begin_t);
51
52 /* Create a one-past-end iterator. */
53 all_threads_iterator ()
54 : m_inf (nullptr)
55 {}
56
57 thread_info *operator* () const;
58
59 all_threads_iterator &operator++ ()
60 {
61 advance ();
62 return *this;
63 }
64
65 bool operator== (const all_threads_iterator &other) const
66 {
67 if (m_inf != other.m_inf)
68 return false;
69
70 /* Inferiors of both iterators are equal. */
71 if (m_inf == NULL) {
72 /* They are both ended iterators. */
73 return true;
74 } else {
75 /* Do they both point to the same thread? */
76 return m_thr_iter == other.m_thr_iter;
77 }
78 }
79
80 bool operator!= (const all_threads_iterator &other) const
81 {
82 return !(*this == other);
83 }
84
85 private:
86 /* Advance to the next thread. */
87 void advance ();
88
89 private:
90 /* The current inferior and thread. M_INF is NULL if we reached the
91 end of the threads list of the last inferior. */
92 inferior *m_inf;
93 ptid_thread_map::const_iterator m_thr_iter;
94 };
95
96 /* Iterate over all threads that match a given PTID. */
97
98 class all_matching_threads_iterator
99 {
100 public:
101 typedef all_matching_threads_iterator self_type;
102 typedef struct thread_info *value_type;
103 typedef struct thread_info *&reference;
104 typedef struct thread_info **pointer;
105 typedef std::forward_iterator_tag iterator_category;
106 typedef int difference_type;
107
108 /* Creates an iterator that iterates over all threads that match
109 FILTER_PTID. */
110 explicit all_matching_threads_iterator (ptid_t filter_ptid);
111
112 /* Create a one-past-end iterator. */
113 all_matching_threads_iterator ()
114 : m_inf (nullptr),
115 m_filter_ptid (minus_one_ptid)
116 {}
117
118 thread_info *operator* () const;
119
120 all_matching_threads_iterator &operator++ ()
121 {
122 advance ();
123 return *this;
124 }
125
126 bool operator== (const all_matching_threads_iterator &other) const
127 {
128 if (m_inf != other.m_inf)
129 return false;
130
131 /* Inferiors of both iterators are equal. */
132 if (m_inf == NULL) {
133 /* They are both ended iterators. */
134 return true;
135 } else {
136 /* Do they both point to the same thread? */
137 return m_thr_iter == other.m_thr_iter;
138 }
139 }
140
141 bool operator!= (const all_matching_threads_iterator &other) const
142 {
143 return !(* this == other);
144 }
145
146 private:
147 /* Advance to next thread, skipping filtered threads. */
148 void advance ();
149
150 /* True if M_INF matches the process identified by
151 M_FILTER_PTID. */
152 bool m_inf_matches ();
153
154 private:
155 /* The current inferior. */
156 inferior *m_inf;
157
158 /* The current thread. */
159 ptid_thread_map::const_iterator m_thr_iter;
160
161 /* The filter. */
162 ptid_t m_filter_ptid;
163 };
164
165 /* Filter for filtered_iterator. Filters out exited threads. */
166
167 struct non_exited_thread_filter
168 {
169 bool operator() (struct thread_info *thr) const
170 {
171 return thr->state != THREAD_EXITED;
172 }
173 };
174
175 /* Iterate over all non-exited threads that match a given PTID. */
176
177 using all_non_exited_threads_iterator
178 = filtered_iterator<all_matching_threads_iterator, non_exited_thread_filter>;
179
180 /* Iterate over all non-exited threads of an inferior. */
181
182 using inf_non_exited_threads_iterator
183 = filtered_iterator<inf_threads_iterator, non_exited_thread_filter>;
184
185 /* Iterate over all threads of all inferiors, safely. */
186
187 using all_threads_safe_iterator
188 = basic_safe_iterator<all_threads_iterator>;
189
190 /* Iterate over all threads of an inferior, safely. */
191
192 using safe_inf_threads_iterator
193 = basic_safe_iterator<inf_threads_iterator>;
194
195 /* A range adapter that makes it possible to iterate over all threads
196 of an inferior with range-for. */
197
198 using inf_threads_range
199 = next_adapter<thread_info, inf_threads_iterator>;
200
201 /* A range adapter that makes it possible to iterate over all
202 non-exited threads of an inferior with range-for. */
203
204 using inf_non_exited_threads_range
205 = next_adapter<thread_info, inf_non_exited_threads_iterator>;
206
207 /* A range adapter that makes it possible to iterate over all threads
208 of an inferior with range-for, safely. */
209
210 using safe_inf_threads_range
211 = next_adapter<thread_info, safe_inf_threads_iterator>;
212
213 /* A range adapter that makes it possible to iterate over all threads
214 of all inferiors with range-for. */
215
216 struct all_threads_range
217 {
218 all_threads_iterator begin () const
219 { return all_threads_iterator (all_threads_iterator::begin_t {}); }
220 all_threads_iterator end () const
221 { return all_threads_iterator (); }
222 };
223
224 /* A range adapter that makes it possible to iterate over all threads
225 with range-for "safely". I.e., it is safe to delete the
226 currently-iterated thread. */
227
228 struct all_threads_safe_range
229 {
230 all_threads_safe_iterator begin () const
231 { return all_threads_safe_iterator (all_threads_iterator::begin_t {}); }
232 all_threads_safe_iterator end () const
233 { return all_threads_safe_iterator (); }
234 };
235
236 /* A range adapter that makes it possible to iterate over all threads
237 that match a PTID filter with range-for. */
238
239 struct all_matching_threads_range
240 {
241 public:
242 explicit all_matching_threads_range (ptid_t filter_ptid)
243 : m_filter_ptid (filter_ptid)
244 {}
245 all_matching_threads_range ()
246 : m_filter_ptid (minus_one_ptid)
247 {}
248
249 all_matching_threads_iterator begin () const
250 { return all_matching_threads_iterator (m_filter_ptid); }
251 all_matching_threads_iterator end () const
252 { return all_matching_threads_iterator (); }
253
254 private:
255 /* The filter. */
256 ptid_t m_filter_ptid;
257 };
258
259 /* A range adapter that makes it possible to iterate over all
260 non-exited threads of all inferiors, with range-for.
261 Threads/inferiors that do not match FILTER_PTID are filtered
262 out. */
263
264 class all_non_exited_threads_range
265 {
266 public:
267 explicit all_non_exited_threads_range (ptid_t filter_ptid)
268 : m_filter_ptid (filter_ptid)
269 {}
270
271 all_non_exited_threads_range ()
272 : m_filter_ptid (minus_one_ptid)
273 {}
274
275 all_non_exited_threads_iterator begin () const
276 { return all_non_exited_threads_iterator (m_filter_ptid); }
277 all_non_exited_threads_iterator end () const
278 { return all_non_exited_threads_iterator (); }
279
280 private:
281 ptid_t m_filter_ptid;
282 };
283
284 #endif /* THREAD_ITER_H */
This page took 0.042813 seconds and 4 git commands to generate.