-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathThreadManager.cpp
166 lines (133 loc) · 4.57 KB
/
ThreadManager.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/***************************************************************************
ThreadManager.h - description
-------------------
begin : Sun Mar 13 2011
copyright : (C) 2010 by Knut-Helge Vik
email : knuthelge@vik.gs
***************************************************************************/
#include "BaseLib/ThreadManager.h"
#include "BaseLib/CommonDefines.h"
#include "BaseLib/Exception.h"
#include "BaseLib/LogDebug.h"
#include "BaseLib/Debug.h"
using namespace std;
namespace BaseLib
{
Singleton<ThreadManager> ThreadManager::threadManager_;
// ---------------------------------------------------------------------
// TODO: Deadlock when RemoveThread (or any mutexed function) is called and then inside IDEBUG() this->GetThread is called!
// To resolve use thread-safe collection
// ---------------------------------------------------------------------
ThreadManager::ThreadManager(std::string name)
: Thread(name, false)
, managerMutex_(MutexPolicy::No())
, threadIdAssigner_(0)
{
//start();
}
ThreadManager::~ThreadManager()
{ }
ThreadManager& ThreadManager::GetInstance()
{
return threadManager_.GetRef();
}
// TODO: Check out system_manager.h in planetlab to see what can be added
void ThreadManager::run()
{
try
{
//IDEBUG() << "Thread manager is up!"; ;
while(true)
{
// do something!
// Wait out all threads!
// TODO: Set flag in all threads and make them use pause() to suspend themselves!
sleep(1);
}
ICRITICAL() << "ThreadManager stopped!";
}
catch(Exception ex)
{
ICRITICAL() << "Unhandled exception " << ex.msg();
}
}
bool ThreadManager::AddThread(Thread *thread)
{
Locker lock(&managerMutex_);
if(mapIdThread_.count(thread->threadId()) > 0)
{
//ICRITICAL() << "Thread " << thread->threadId() << " already registered!";
return false;
}
thread->humanReadableId(threadIdAssigner_++);
mapIdThread_[thread->threadId()] = thread;
//IDEBUG() << "Thread " << thread->threadId() << " started ";
return true;
}
bool ThreadManager::AddThread(Thread *thread, ThreadId id)
{
Locker lock(&managerMutex_);
if(mapIdThread_.count(id) > 0)
{
//ICRITICAL() << "Thread " << id << " already registered!";
return false;
}
thread->humanReadableId(threadIdAssigner_++);
mapIdThread_[id] = thread;
//IDEBUG() << "Thread " << id << " " << thread->threadName() << " started ";
return true;
}
bool ThreadManager::AddThread(ThreadId id, std::string name)
{
Locker lock(&managerMutex_);
if(mapIdThread_.count(id) > 0)
{
//ICRITICAL() << "Thread " << id << " already registered!";
return false;
}
mapIdThread_[id] = NULL;
if(mapIdThreadName_.count(id) > 0)
{
//ICRITICAL() << "Thread " << id << " already registered!";
return false;
}
mapIdThreadName_[id] = name;
//IDEBUG() << "Thread " << id << " " << name << " registered ";
return true;
}
// ---------------------------------------------------------------------
// TODO: Deadlock when RemoveThread is called and then inside IDEBUG() this->GetThread is called!
// To resolve use thread-safe collection -- NO!
// Cannot be resolved as long as CurrentThread is accessed inside IDEBUG() etc,,
// but attempted to check if this->threadId() equals calling thread id
// ---------------------------------------------------------------------
bool ThreadManager::RemoveThread(Thread *thread)
{
if(thread->threadId() == this->threadId()) return true;
Locker lock(&managerMutex_);
if(mapIdThread_.count(thread->threadId()) <= 0)
{
//IWARNING() << "Thread " << thread->threadName() << "(" << thread->threadId() << ")" << " already stopped!";
return false;
}
mapIdThread_.erase(thread->threadId());
//IDEBUG() << "Thread stopped: " << thread->threadId() << " " << thread->threadName(); //thread->getThreadDetails();
return true;
}
Thread* ThreadManager::GetThread(ThreadId id)
{
if(id == this->threadId()) return this;
{
Locker lock(&managerMutex_);
MapIdThread::iterator entry = mapIdThread_.find(id);
if(entry != mapIdThread_.end())
{
return entry->second;
}
}
ThreadNoOp* threadNoOp = new ThreadNoOp(std::string("main.thread"), false);
threadNoOp->getThreadDetails().threadId(id);
BaseLib::ThreadManager::GetInstance().AddThread(threadNoOp);
return threadNoOp;
}
}