1/*
2 * Copyright 2013-2016, Rene Gollent, rene@gollent.com.
3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Distributed under the terms of the MIT License.
5 */
6
7#include "model/Thread.h"
8
9#include <stdio.h>
10
11#include "CpuState.h"
12#include "StackTrace.h"
13#include "Team.h"
14
15
16Thread::Thread(Team* team, thread_id threadID)
17	:
18	fTeam(team),
19	fID(threadID),
20	fState(THREAD_STATE_UNKNOWN),
21	fReturnValueInfos(NULL),
22	fStopRequestPending(false),
23	fStoppedReason(THREAD_STOPPED_UNKNOWN),
24	fCpuState(NULL),
25	fStackTrace(NULL)
26{
27}
28
29
30Thread::~Thread()
31{
32	if (fCpuState != NULL)
33		fCpuState->ReleaseReference();
34	if (fStackTrace != NULL)
35		fStackTrace->ReleaseReference();
36
37	ClearReturnValueInfos();
38	delete fReturnValueInfos;
39}
40
41
42status_t
43Thread::Init()
44{
45	fReturnValueInfos = new(std::nothrow) ReturnValueInfoList;
46	if (fReturnValueInfos == NULL)
47		return B_NO_MEMORY;
48
49	return B_OK;
50}
51
52
53bool
54Thread::IsMainThread() const
55{
56	return fID == fTeam->ID();
57}
58
59
60void
61Thread::SetName(const BString& name)
62{
63	fName = name;
64}
65
66
67void
68Thread::SetState(uint32 state, uint32 reason, const BString& info)
69{
70	if (state == fState && reason == fStoppedReason)
71		return;
72
73	fState = state;
74	fStoppedReason = reason;
75	fStoppedReasonInfo = info;
76
77	// unset CPU state and stack trace, if the thread isn't stopped
78	if (fState != THREAD_STATE_STOPPED) {
79		SetCpuState(NULL);
80		SetStackTrace(NULL);
81		ClearReturnValueInfos();
82		fStopRequestPending = false;
83	}
84
85	fTeam->NotifyThreadStateChanged(this);
86}
87
88
89void
90Thread::SetCpuState(CpuState* state)
91{
92	if (state == fCpuState)
93		return;
94
95	if (fCpuState != NULL)
96		fCpuState->ReleaseReference();
97
98	fCpuState = state;
99
100	if (fCpuState != NULL)
101		fCpuState->AcquireReference();
102
103	fTeam->NotifyThreadCpuStateChanged(this);
104}
105
106
107void
108Thread::SetStackTrace(StackTrace* trace)
109{
110	if (trace == fStackTrace)
111		return;
112
113	if (fStackTrace != NULL)
114		fStackTrace->ReleaseReference();
115
116	fStackTrace = trace;
117
118	if (fStackTrace != NULL)
119		fStackTrace->AcquireReference();
120
121	fTeam->NotifyThreadStackTraceChanged(this);
122}
123
124void
125Thread::SetStopRequestPending()
126{
127	fStopRequestPending = true;
128}
129
130
131status_t
132Thread::AddReturnValueInfo(ReturnValueInfo* info)
133{
134	if (!fReturnValueInfos->AddItem(info))
135		return B_NO_MEMORY;
136
137	info->AcquireReference();
138	return B_OK;
139}
140
141
142void
143Thread::ClearReturnValueInfos()
144{
145	for (int32 i = 0; i < fReturnValueInfos->CountItems(); i++)
146		fReturnValueInfos->ItemAt(i)->ReleaseReference();
147
148	fReturnValueInfos->MakeEmpty();
149}
150