KSquare Utilities
KKThreadManager.cpp
Go to the documentation of this file.
1 /* KKThreadManager.cpp -- Manages the threads that perform the image extraction process.
2  * Copyright (C) 2012-2014 Kurt Kramer
3  * For conditions of distribution and use, see copyright notice in KKB.h
4  */
5 #include "FirstIncludes.h"
6 #include <string>
7 #include <iostream>
8 #include <vector>
9 #include "MemoryDebug.h"
10 using namespace std;
11 
12 #include "MsgQueue.h"
13 #include "KKThread.h"
14 #include "OSservices.h"
15 #include "KKThreadManager.h"
16 using namespace KKB;
17 
18 
19 
20 
21 
22 
23 KKThreadManager::KKThreadManager (const KKStr& _managerName,
24  kkuint32 _maxNumThreads,
25  MsgQueuePtr _msgQueue
26  ):
27  KKThread (_managerName, NULL, _msgQueue),
28  crashed (false),
29  doneExecuting (false),
30  maxNumThreads (_maxNumThreads),
31  shutdownFlag (false),
32  shutdownRequested (false),
33  terminateFlag (false),
34  terminateRequested (false),
35  threads (NULL)
36 
37 {
38  threads = new KKThreadList (true);
39 }
40 
41 
42 
43 
45 {
46  delete threads;
47  threads = NULL;
48 }
49 
50 
51 
53 {
54  if (!threads)
55  threads = new KKThreadList (true);
56 
57  threads->PushOnBack (_thread);
58 }
59 
60 
61 
63 {
64  shutdownRequested = true;
65 }
66 
67 
69 {
70  terminateRequested = true;
71 }
72 
73 
74 
75 
77 {
78  terminateFlag = true;
79  if (threads)
80  {
81  KKThreadList::iterator idx;
82  for (idx = threads->begin (); idx != threads->end (); ++idx)
83  {
84  KKThreadPtr thread = *idx;
85  thread->TerminateThread ();
86  }
87  }
88 } /* TerminateProcessing */
89 
90 
91 
92 
94 {
95  shutdownFlag = true;
96 
97  if (!threads)
98  return;
99 
100  kkint32 numMiliSecsWaited = 0;
101  shutdownFlag = true;
102 
103  kkint32 lastNumThreadsRunning = 0;
104  kkint32 lastNumThreadsStopped = 0;
105 
106  bool allTreadsAreShutdown = false;
107 
108  while (!allTreadsAreShutdown)
109  {
110  allTreadsAreShutdown = true;
111  kkint32 numThreadsRunning = 0;
112  kkint32 numThreadsStopped = 0;
113 
114  KKThreadList::iterator idx;
115  for (idx = threads->begin (); idx != threads->end (); ++idx)
116  {
117  KKThreadPtr thread = *idx;
118 
119  switch (thread->Status ())
120  {
122  break;
123 
126  // Nothing to do; this thread is not running,
127  ++numThreadsStopped;
128  break;
129 
131  allTreadsAreShutdown = false;
132  ++numThreadsRunning;
133  break;
134 
136  {
137  allTreadsAreShutdown = false;
138  if (!(thread->ShutdownFlag ()))
139  {
140  if (thread->OkToShutdown ())
141  {
142  thread->ShutdownThread ();
143  numMiliSecsWaited = 0;
144  }
145  }
146  ++numThreadsRunning;
147  }
148  break;
149 
151  // Have to let it finish starting before we can flag it to shutdown.
152  ++numThreadsRunning;
153  break;
154  } /* End of Switch */
155  }
156 
157  if ((numThreadsRunning != lastNumThreadsRunning) ||
158  (numThreadsStopped != lastNumThreadsStopped)
159  )
160  {
161  // The status of one or more threads changed; can reset the 'numMiliSecsWaited' clock.
162  numMiliSecsWaited = 0;
163  }
164 
165  if (!allTreadsAreShutdown)
166  {
167  if ((miliSecsToWait > 0) && (numMiliSecsWaited > miliSecsToWait))
168  {
169  // The shutdown process is taking longer than the 'miliSecsToWait' parameter will allow for; we need to terminate
170  // all running threads now.
172  break;
173  }
174  else
175  {
176  osSleep (0.01f);
177  numMiliSecsWaited += 10;
178  }
179  }
180  }
181 } /* ShutdownProcessing */
182 
183 
184 
186 {
187  if (!threads)
188  return;
189 
190  KKThreadList::iterator idx;
191  for (idx = threads->begin (); idx != threads->end (); ++idx)
192  {
193  KKThreadPtr thread = *idx;
194  thread->Kill ();
195  }
196 } /* KillAllRunningThreads*/
197 
198 
199 
200 void KKThreadManager::StartThreads (bool& successful)
201 {
202  AddMsg ("KKThreadManager::StartThreads");
203 
204  successful = true;
205 
206  if (!threads)
207  return;
208 
209  bool allThreadsStarted = false;
210 
211  while (!allThreadsStarted)
212  {
213  allThreadsStarted = true;
214  KKThreadList::iterator idx;
215  for (idx = threads->begin (); idx != threads->end (); ++idx)
216  {
217  KKThreadPtr thread = *idx;
218  if (thread->Crashed ())
219  {
220  crashed = true;
221  successful = false;
222  break;
223  }
224 
226  {
227  if (thread->OkToStart ())
228  {
229  bool successfulStart = false;
230  thread->Start (ThreadPriority::Normal, successfulStart);
231  if (!successfulStart)
232  {
233  allThreadsStarted = false;
234  successful = false;
235  break;
236  }
237  }
238  else
239  {
240  allThreadsStarted = false;
241  }
242  }
243  }
244 
245  if (!allThreadsStarted)
246  {
247  osSleep (0.01f);
248  }
249  }
250 
251 } /* StartThreads */
252 
253 
254 
256 {
257  bool anyProcessorsCrashed = false;
258 
259  if (threads)
260  {
261  KKThreadList::iterator idx;
262  for (idx = threads->begin (); idx != threads->end (); ++idx)
263  {
264  KKThreadPtr t = *idx;
265  if (t->Crashed ())
266  {
267  anyProcessorsCrashed = true;
268  break;
269  }
270  }
271  }
272 
273  crashed = anyProcessorsCrashed;
274 
275  return anyProcessorsCrashed;
276 } /* AnyProcessorsCrash */
277 
278 
279 
281 {
282  bool allThreadsTerminated = true;
283 
284  if (threads)
285  {
286  KKThreadList::const_iterator idx;
287  for (idx = threads->begin (); idx != threads->end (); ++idx)
288  {
289  KKThreadPtr t = *idx;
291  {
292  allThreadsTerminated = false;
293  break;
294  }
295  }
296  }
297 
298  return allThreadsTerminated;
299 } /* AllThreadsTerminated */
300 
301 
302 
303 
304 
305 void KKThreadManager::ManageThreads (bool& successful)
306 {
307  successful= false;
308  if (!threads)
309  return;
310 
311  StartThreads (successful);
312  if (!successful)
313  return;
314 
315 
316  while (true)
317  {
318  if (shutdownRequested)
319  {
320  shutdownRequested = false;
322  break;
323  }
324 
325  else if (terminateRequested)
326  {
327  terminateRequested = false;
329  break;
330  }
331 
332  else
333  {
334  osSleep (0.05f);
335  }
336  }
337 
338 
340  {
341  AddMsg ("One or more processors crashed!!!");
342  crashed = true;
343  }
344 } /* ManageThreads */
345 
346 
347 
349 {
350 }
void Start(ThreadPriority _priority, bool &successful)
Definition: KKThread.cpp:352
ThreadStatus Status() const
Definition: KKThread.h:72
__int32 kkint32
Definition: KKBaseTypes.h:88
KKThread * KKThreadPtr
Definition: KKThread.h:30
bool Crashed() const
Definition: KKThread.h:62
KKThread(const KKStr &_threadName, KKThreadManagerPtr _threadManager, MsgQueuePtr _msgQueue)
Definition: KKThread.cpp:83
void ShutdownProcessing(kkint32 miliSecsToWait)
Shutdown all threads in a orderly way; observing prerequisite ordering.
unsigned __int32 kkuint32
Definition: KKBaseTypes.h:89
void osSleep(float numOfSecs)
KKThreadManager(const KKStr &_managerName, kkuint32 _maxNumThreads, MsgQueuePtr _msgQueue)
KKTHread * KKTHreadPtr
void TerminateThread()
Definition: KKThread.cpp:208
The base class to be used any thread.
Definition: KKThread.h:27
bool OkToShutdown() const
Definition: KKThread.cpp:519
static KKStr Concat(const std::vector< std::string > &values)
Concatenates the list of &#39;std::string&#39; strings.
Definition: KKStr.cpp:1082
KKThreadList(bool _owner=true)
Definition: KKThread.cpp:555
VolConstBool & ShutdownFlag() const
Definition: KKThread.h:75
void Kill()
stops the running thread and frees the thread handle
Definition: KKThread.cpp:427
void ShutdownThread()
Definition: KKThread.cpp:231
void AddThread(KKThreadPtr _thread)
void ManageThreads(bool &successful)
bool OkToStart() const
Definition: KKThread.cpp:536