blob: 6285cb1e0fb466634db5a0b159a9c93a1114d5e1 [file] [log] [blame]
//===-- ThreadList.h --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#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();
};
} // namespace lldb_private
#endif // liblldb_ThreadList_h_