reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
//===-- ThreadList.h --------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_ThreadList_h_
#define liblldb_ThreadList_h_

#include <mutex>
#include <vector>

#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadCollection.h"
#include "lldb/Utility/Iterable.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

// This is a thread list with lots of functionality for use only by the process
// for which this is the thread list.  A generic container class with iterator
// functionality is ThreadCollection.
class ThreadList : public ThreadCollection {
  friend class Process;

public:
  ThreadList(Process *process);

  ThreadList(const ThreadList &rhs);

  ~ThreadList() override;

  const ThreadList &operator=(const ThreadList &rhs);

  uint32_t GetSize(bool can_update = true);

  // Return the selected thread if there is one.  Otherwise, return the thread
  // selected at index 0.
  lldb::ThreadSP GetSelectedThread();

  // Manage the thread to use for running expressions.  This is usually the
  // Selected thread, but sometimes (e.g. when evaluating breakpoint conditions
  // & stop hooks) it isn't.
  class ExpressionExecutionThreadPusher {
  public:
    ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid)
        : m_thread_list(&thread_list), m_tid(tid) {
      m_thread_list->PushExpressionExecutionThread(m_tid);
    }

    ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp);

    ~ExpressionExecutionThreadPusher() {
      if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID)
        m_thread_list->PopExpressionExecutionThread(m_tid);
    }

  private:
    ThreadList *m_thread_list;
    lldb::tid_t m_tid;
  };

  lldb::ThreadSP GetExpressionExecutionThread();

protected:
  void PushExpressionExecutionThread(lldb::tid_t tid);

  void PopExpressionExecutionThread(lldb::tid_t tid);

public:
  bool SetSelectedThreadByID(lldb::tid_t tid, bool notify = false);

  bool SetSelectedThreadByIndexID(uint32_t index_id, bool notify = false);

  void Clear();

  void Flush();

  void Destroy();

  // Note that "idx" is not the same as the "thread_index". It is a zero based
  // index to accessing the current threads, whereas "thread_index" is a unique
  // index assigned
  lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update = true);

  lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update = true);

  lldb::ThreadSP FindThreadByProtocolID(lldb::tid_t tid,
                                        bool can_update = true);

  lldb::ThreadSP RemoveThreadByID(lldb::tid_t tid, bool can_update = true);

  lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid,
                                          bool can_update = true);

  lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update = true);

  lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr);

  lldb::ThreadSP GetBackingThread(const lldb::ThreadSP &real_thread);

  bool ShouldStop(Event *event_ptr);

  Vote ShouldReportStop(Event *event_ptr);

  Vote ShouldReportRun(Event *event_ptr);

  void RefreshStateAfterStop();

  /// The thread list asks tells all the threads it is about to resume.
  /// If a thread can "resume" without having to resume the target, it
  /// will return false for WillResume, and then the process will not be
  /// restarted.
  ///
  /// \return
  ///    \b true instructs the process to resume normally,
  ///    \b false means start & stopped events will be generated, but
  ///    the process will not actually run.  The thread must then return
  ///    the correct StopInfo when asked.
  ///
  bool WillResume();

  void DidResume();

  void DidStop();

  void DiscardThreadPlans();

  uint32_t GetStopID() const;

  void SetStopID(uint32_t stop_id);

  std::recursive_mutex &GetMutex() const override;

  void Update(ThreadList &rhs);

protected:
  void SetShouldReportStop(Vote vote);

  void NotifySelectedThreadChanged(lldb::tid_t tid);

  // Classes that inherit from Process can see and modify these
  Process *m_process; ///< The process that manages this thread list.
  uint32_t
      m_stop_id; ///< The process stop ID that this thread list is valid for.
  lldb::tid_t
      m_selected_tid; ///< For targets that need the notion of a current thread.
  std::vector<lldb::tid_t> m_expression_tid_stack;

private:
  ThreadList() = delete;
};

} // namespace lldb_private

#endif // liblldb_ThreadList_h_