thread-iter.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /* Thread iterators and ranges for GDB, the GNU debugger.
  2. Copyright (C) 2018-2022 Free Software Foundation, Inc.
  3. This file is part of GDB.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  14. #ifndef THREAD_ITER_H
  15. #define THREAD_ITER_H
  16. #include "gdbsupport/filtered-iterator.h"
  17. #include "gdbsupport/iterator-range.h"
  18. #include "gdbsupport/next-iterator.h"
  19. #include "gdbsupport/reference-to-pointer-iterator.h"
  20. #include "gdbsupport/safe-iterator.h"
  21. /* A forward iterator that iterates over a given inferior's
  22. threads. */
  23. using inf_threads_iterator
  24. = reference_to_pointer_iterator<intrusive_list<thread_info>::iterator>;
  25. /* A forward iterator that iterates over all threads of all
  26. inferiors. */
  27. class all_threads_iterator
  28. {
  29. public:
  30. typedef all_threads_iterator self_type;
  31. typedef struct thread_info *value_type;
  32. typedef struct thread_info *&reference;
  33. typedef struct thread_info **pointer;
  34. typedef std::forward_iterator_tag iterator_category;
  35. typedef int difference_type;
  36. /* Tag type. */
  37. struct begin_t {};
  38. /* Create an iterator that points to the first thread of the first
  39. inferior. */
  40. explicit all_threads_iterator (begin_t);
  41. /* Create a one-past-end iterator. */
  42. all_threads_iterator ()
  43. : m_thr (nullptr)
  44. {}
  45. thread_info *operator* () const { return m_thr; }
  46. all_threads_iterator &operator++ ()
  47. {
  48. advance ();
  49. return *this;
  50. }
  51. bool operator== (const all_threads_iterator &other) const
  52. { return m_thr == other.m_thr; }
  53. bool operator!= (const all_threads_iterator &other) const
  54. { return m_thr != other.m_thr; }
  55. private:
  56. /* Advance to the next thread. */
  57. void advance ();
  58. private:
  59. /* The current inferior and thread. M_THR is NULL if we reached the
  60. end of the threads list of the last inferior. */
  61. inferior *m_inf;
  62. thread_info *m_thr;
  63. };
  64. /* Iterate over all threads that match a given PTID. */
  65. class all_matching_threads_iterator
  66. {
  67. public:
  68. typedef all_matching_threads_iterator self_type;
  69. typedef struct thread_info *value_type;
  70. typedef struct thread_info *&reference;
  71. typedef struct thread_info **pointer;
  72. typedef std::forward_iterator_tag iterator_category;
  73. typedef int difference_type;
  74. /* Creates an iterator that iterates over all threads that match
  75. FILTER_PTID. */
  76. all_matching_threads_iterator (process_stratum_target *filter_target,
  77. ptid_t filter_ptid);
  78. /* Create a one-past-end iterator. */
  79. all_matching_threads_iterator () = default;
  80. thread_info *operator* () const { return m_thr; }
  81. all_matching_threads_iterator &operator++ ()
  82. {
  83. advance ();
  84. return *this;
  85. }
  86. bool operator== (const all_matching_threads_iterator &other) const
  87. { return m_thr == other.m_thr; }
  88. bool operator!= (const all_matching_threads_iterator &other) const
  89. { return m_thr != other.m_thr; }
  90. private:
  91. /* Advance to next thread, skipping filtered threads. */
  92. void advance ();
  93. /* True if M_INF has the process target M_FILTER_TARGET. */
  94. bool m_inf_matches ();
  95. private:
  96. enum class mode
  97. {
  98. /* All threads, possibly filtered down to a single target. */
  99. ALL_THREADS,
  100. /* All threads of the given inferior. */
  101. ALL_THREADS_OF_INFERIOR,
  102. /* A specific thread. */
  103. SINGLE_THREAD,
  104. } m_mode;
  105. /* The current inferior. */
  106. inferior *m_inf = nullptr;
  107. /* The current thread. */
  108. thread_info *m_thr = nullptr;
  109. /* The target we filter on (may be nullptr). */
  110. process_stratum_target *m_filter_target;
  111. };
  112. /* Filter for filtered_iterator. Filters out exited threads. */
  113. struct non_exited_thread_filter
  114. {
  115. bool operator() (struct thread_info *thr) const
  116. {
  117. return thr->state != THREAD_EXITED;
  118. }
  119. };
  120. /* Iterate over all non-exited threads that match a given PTID. */
  121. using all_non_exited_threads_iterator
  122. = filtered_iterator<all_matching_threads_iterator, non_exited_thread_filter>;
  123. /* Iterate over all non-exited threads of an inferior. */
  124. using inf_non_exited_threads_iterator
  125. = filtered_iterator<inf_threads_iterator, non_exited_thread_filter>;
  126. /* Iterate over all threads of all inferiors, safely. */
  127. using all_threads_safe_iterator
  128. = basic_safe_iterator<all_threads_iterator>;
  129. /* Iterate over all threads of an inferior, safely. */
  130. using safe_inf_threads_iterator
  131. = basic_safe_iterator<inf_threads_iterator>;
  132. /* A range adapter that makes it possible to iterate over all threads
  133. of an inferior with range-for. */
  134. using inf_threads_range = iterator_range<inf_threads_iterator>;
  135. /* A range adapter that makes it possible to iterate over all
  136. non-exited threads of an inferior with range-for. */
  137. using inf_non_exited_threads_range
  138. = iterator_range<inf_non_exited_threads_iterator>;
  139. /* A range adapter that makes it possible to iterate over all threads
  140. of an inferior with range-for, safely. */
  141. using safe_inf_threads_range = iterator_range<safe_inf_threads_iterator>;
  142. /* A range adapter that makes it possible to iterate over all threads
  143. with range-for "safely". I.e., it is safe to delete the
  144. currently-iterated thread. */
  145. using all_threads_safe_range = iterator_range<all_threads_safe_iterator>;
  146. /* A range adapter that makes it possible to iterate over all threads
  147. that match a PTID filter with range-for. */
  148. struct all_matching_threads_range
  149. {
  150. public:
  151. all_matching_threads_range (process_stratum_target *filter_target,
  152. ptid_t filter_ptid)
  153. : m_filter_target (filter_target), m_filter_ptid (filter_ptid)
  154. {}
  155. all_matching_threads_range ()
  156. : m_filter_target (nullptr), m_filter_ptid (minus_one_ptid)
  157. {}
  158. all_matching_threads_iterator begin () const
  159. { return all_matching_threads_iterator (m_filter_target, m_filter_ptid); }
  160. all_matching_threads_iterator end () const
  161. { return all_matching_threads_iterator (); }
  162. private:
  163. /* The filter. */
  164. process_stratum_target *m_filter_target;
  165. ptid_t m_filter_ptid;
  166. };
  167. /* A range adapter that makes it possible to iterate over all
  168. non-exited threads of all inferiors, with range-for.
  169. Threads/inferiors that do not match FILTER_PTID are filtered
  170. out. */
  171. class all_non_exited_threads_range
  172. {
  173. public:
  174. all_non_exited_threads_range (process_stratum_target *filter_target,
  175. ptid_t filter_ptid)
  176. : m_filter_target (filter_target), m_filter_ptid (filter_ptid)
  177. {}
  178. all_non_exited_threads_range ()
  179. : m_filter_target (nullptr), m_filter_ptid (minus_one_ptid)
  180. {}
  181. all_non_exited_threads_iterator begin () const
  182. { return all_non_exited_threads_iterator (m_filter_target, m_filter_ptid); }
  183. all_non_exited_threads_iterator end () const
  184. { return all_non_exited_threads_iterator (); }
  185. private:
  186. process_stratum_target *m_filter_target;
  187. ptid_t m_filter_ptid;
  188. };
  189. #endif /* THREAD_ITER_H */