-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathThread.cpp
141 lines (121 loc) · 2.38 KB
/
Thread.cpp
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
// Thread.cpp
#include "Thread.h"
// Thread
// constructor
Thread::Thread(const char *name, int32 priority)
{
id = spawn_thread(run_thread, name, priority, this);
go = false;
}
// destructor
Thread::~Thread()
{
// the emergency brake:
// we've already left the destructors of derived classes, so
// if the thread is still running the thread function might misbehave
if (id >= B_NO_ERROR)
Die();
}
// Exit
void Thread::Exit(status_t ret_val)
{
go = false;
id = B_ERROR;
exit_thread(ret_val);
}
// Kill
status_t Thread::Kill()
{
status_t result = B_BAD_THREAD_ID;
if (id >= B_NO_ERROR)
{
result = kill_thread(id);
go = false;
id = B_ERROR;
}
return result;
};
// Die
void Thread::Die()
{
if (id >= B_NO_ERROR)
{
status_t exitval;
if (go)
{
go = false;
Terminate();
WaitFor(&exitval);
}
else
Kill();
}
}
// run_thread
int32 Thread::run_thread(void *data)
{
Thread *thread = reinterpret_cast<Thread *>(data);
thread->go = true;
int32 result = thread->ThreadFunction();
thread->id = B_ERROR;
thread->go = false;
return result;
}
// CmdThread
// ThreadFunction
int32 CmdThread::ThreadFunction()
{
int32 result = CmdThreadFunction();
// clean up the thread's message buffer (the unprocessed Commands)
Command *cmd;
while (HasData() && (cmd = ReceiveCommand()))
CommandProcessed(cmd);
return result;
}
// CmdThreadFunction
int32 CmdThread::CmdThreadFunction()
{
return 0;
}
// SendCommand
status_t CmdThread::SendCommand(CmdThread *thread, Command *cmd)
{
cmd->sender = this;
return SendData(thread, cmd->code, &cmd, sizeof(Command *));
}
// ReceiceCommand
Command *CmdThread::ReceiveCommand()
{
Command *cmd = 0; thread_id thread;
int32 code = ReceiveData(&thread, &cmd, sizeof(Command *));
// for compatibility with Thread::Terminate()
if (!cmd)
cmd = new Command(code);
return cmd;
}
// CheckForCommand
Command *CmdThread::CheckForCommand()
{
if (!HasData())
return 0;
return ReceiveCommand();
}
// ReplyCommand
void CmdThread::ReplyCommand(Command *cmd, bool ptr_valid)
{
if (cmd->sender)
{
if (ptr_valid)
SendCommand(cmd->sender, new CmdReply(cmd));
else
SendCommand(cmd->sender, new CmdReply(cmd->code));
}
}
// CommandProcessed
void CmdThread::CommandProcessed(Command *cmd)
{
if (cmd->process & PROCESS_REPLY)
ReplyCommand(cmd, cmd->process & PROCESS_DONT_DELETE);
if (!(cmd->process & PROCESS_DONT_DELETE))
delete cmd;
}