/[LeafOK_CVS]/innwebd/thread_pool.cpp
ViewVC logotype

Contents of /innwebd/thread_pool.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (show annotations)
Fri Apr 11 17:14:49 2008 UTC (17 years, 11 months ago) by sysadm
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +2 -6 lines
Content type: text/x-c++src
Update copyright
Add extra log for exception

1 /*******************************************************/
2 /* */
3 /* LeafOK Innbbsd */
4 /* */
5 /* Copyright (C) LeafOK.com, 2003-2008 */
6 /* */
7 /* http://www.leafok.com */
8 /* */
9 /*******************************************************/
10
11 #include "StdAfx.h"
12 #include ".\thread_pool.h"
13
14 thread_pool::thread_pool(UINT uThreadMax)
15 {
16 UINT i;
17
18 this->uLastErrorCode = E_NOERROR;
19 this->uThreadCount = 0;
20 this->uThreadMax = uThreadMax;
21 this->ulThreadKillerId = 0;
22
23 if (this->uThreadMax > TS_MAX_THREAD)
24 {
25 this->uThreadMax = 0;
26 this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
27 }
28
29 for (i=0; i < this->uThreadMax; i++)
30 {
31 this->ulThreadIdList[i] = 0;
32 this->uThreadStatusList[i] = S_UNUSED;
33 this->time_status_set[i] = clock();
34 }
35
36 this->SetLock(false);
37
38 this->EnableKillDeadThread();
39 }
40
41 thread_pool::~thread_pool(void)
42 {
43 this->DisableKillDeadThread();
44 this->KillAllThread();
45 }
46
47 int thread_pool::AddThread(ULONG ulThreadId, clock_t thread_timeout)
48 {
49 UINT i;
50
51 if (this->uThreadCount >= this->uThreadMax)
52 {
53 this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
54 return E_MAX_THREAD_EXCEEDED;
55 }
56
57 if (thread_timeout < 0)
58 {
59 this->uLastErrorCode = E_INVALID_TIMEOUT;
60 return E_INVALID_TIMEOUT;
61 }
62
63 if (this->SetLock(true) == 0)
64 {
65 for (i=0; i < this->uThreadMax; i++)
66 {
67 if (this->uThreadStatusList[i] == S_UNUSED)
68 {
69 this->ulThreadIdList[i] = ulThreadId;
70 this->uThreadStatusList[i] = S_WAITING;
71 this->thread_timeout[i] = thread_timeout;
72 this->time_status_set[i] = clock();
73 this->uThreadCount++;
74 this->SetLock(false);
75 this->uLastErrorCode = E_NOERROR;
76 return E_NOERROR;
77 }
78 }
79 this->SetLock(false);
80 this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
81 return E_MAX_THREAD_EXCEEDED;
82 }
83
84 return E_LOCK_TIMEOUT;
85 }
86
87 int thread_pool::SetLock(bool bLock, clock_t tTimeout)
88 {
89 clock_t wait = 0;
90
91 if (!bLock) // Free lock
92 {
93 this->bProcessLock = false;
94 this->uLastErrorCode = E_NOERROR;
95 return E_NOERROR;
96 }
97
98 while (this->bProcessLock) // Locked by others
99 {
100 Sleep(10);
101 wait += 10;
102 if (wait > tTimeout) // Timeout
103 {
104 this->uLastErrorCode = E_LOCK_TIMEOUT;
105 return E_LOCK_TIMEOUT;
106 }
107 }
108 this->bProcessLock = true;
109 this->uLastErrorCode = E_NOERROR;
110
111 return E_NOERROR;
112 }
113
114 int thread_pool::GetLastError(void) const
115 {
116 return this->uLastErrorCode;
117 }
118
119 int thread_pool::RemoveThread(ULONG ulThreadId)
120 {
121 UINT i;
122
123 if (this->uThreadCount <= 0)
124 {
125 this->uLastErrorCode = E_THREAD_NOT_FOUND;
126 return E_THREAD_NOT_FOUND;
127 }
128
129 if (this->SetLock(true) == 0)
130 {
131 for (i=0; i < this->uThreadMax; i++)
132 {
133 if (this->ulThreadIdList[i] == ulThreadId)
134 {
135 this->ulThreadIdList[i] = 0;
136 this->uThreadStatusList[i] = S_UNUSED;
137 this->uThreadCount--;
138 this->SetLock(false);
139 this->uLastErrorCode = E_NOERROR;
140 return E_NOERROR;
141 }
142 }
143 this->SetLock(false);
144 this->uLastErrorCode = E_THREAD_NOT_FOUND;
145 return E_THREAD_NOT_FOUND;
146 }
147
148 return E_LOCK_TIMEOUT;
149 }
150
151
152 int thread_pool::SetThreadStatus(ULONG ulThreadId, int uStatus)
153 {
154 UINT i;
155
156 if (this->uThreadCount <= 0)
157 {
158 this->uLastErrorCode = E_THREAD_NOT_FOUND;
159 return E_THREAD_NOT_FOUND;
160 }
161
162 for (i=0; i < this->uThreadMax; i++)
163 {
164 if (this->ulThreadIdList[i] == ulThreadId)
165 {
166 this->uThreadStatusList[i] = (thread_status)uStatus;
167 this->time_status_set[i] = clock();
168 this->uLastErrorCode = E_NOERROR;
169 return this->uLastErrorCode;
170 }
171 }
172
173 this->uLastErrorCode = E_THREAD_NOT_FOUND;
174 return E_THREAD_NOT_FOUND;
175 }
176
177 int thread_pool::GetThreadStatus(ULONG ulThreadId)
178 {
179 UINT i;
180
181 if (this->uThreadCount <= 0)
182 {
183 this->uLastErrorCode = E_THREAD_NOT_FOUND;
184 return S_UNKNOWN;
185 }
186
187 for (i=0; i < this->uThreadMax; i++)
188 {
189 if (this->ulThreadIdList[i] == ulThreadId)
190 {
191 this->uLastErrorCode = E_NOERROR;
192 return this->uThreadStatusList[i];
193 }
194 }
195
196 this->uLastErrorCode = E_THREAD_NOT_FOUND;
197 return S_UNKNOWN;
198 }
199
200 DWORD thread_pool::KillDeadThread(LPVOID pParam)
201 {
202 thread_pool *p;
203 UINT i;
204 HANDLE hThread;
205 ULONG ulThreadId;
206 int t_count = 0;
207
208 p = (thread_pool*)pParam;
209
210 p->ulThreadKillerId = GetCurrentThreadId();
211
212 while(!p->bTerminateThreadKiller)
213 {
214 if (t_count>=100)
215 {
216 t_count=0;
217
218 for (i=0; i < p->uThreadMax; i++)
219 {
220 if ((p->ulThreadIdList[i] != 0) &&
221 (p->uThreadStatusList[i] == S_WORKING) &&
222 (clock() - p->time_status_set[i] > p->thread_timeout[i]))
223 {
224 ulThreadId = p->ulThreadIdList[i];
225 // Remove dead thread from thread pool
226 if (p->RemoveThread(ulThreadId) != 0)
227 {
228 syslog << logfile::log_head << "Unregister thread (" << ulThreadId << ") ... Failed" << endl;
229 }
230 // Kill dead thread
231 if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,ulThreadId)) == NULL)
232 {
233 syslog << logfile::log_head << "Get thread handle error in KillDeadThread()" << endl;
234 }
235 else
236 {
237 if (TerminateThread(hThread,-1))
238 {
239 syslog << logfile::log_head << "Terminate dead thread (" << ulThreadId << ") ... OK" << endl;
240 }
241 else
242 {
243 syslog << logfile::log_head << "Terminate dead thread (" << ulThreadId << ") ... Failed" << endl;
244 }
245 CloseHandle(hThread);
246 }
247 }
248 }
249 }
250
251 Sleep(100);
252 t_count++;
253 }
254
255 p->bTerminateThreadKiller = false;
256 p->ulThreadKillerId = 0;
257
258 return (E_NOERROR);
259 }
260
261 int thread_pool::GetThreadCount(void) const
262 {
263 return this->uThreadCount;
264 }
265
266 int thread_pool::EnableKillDeadThread(void)
267 {
268 HANDLE hThreadCurrent;
269 ULONG ulThreadId;
270
271 this->bTerminateThreadKiller = false;
272 if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_pool::KillDeadThread,(LPVOID)this,0,&ulThreadId))
273 {
274 CloseHandle(hThreadCurrent);
275 syslog << logfile::log_head << "Create killer thread ... OK" << endl;
276 }
277 else
278 {
279 syslog << logfile::log_head << "Create killer thread ... Failed" << endl;
280 this->uLastErrorCode = E_KILLER_BEGIN_FAILED;
281 return E_KILLER_BEGIN_FAILED;
282 }
283
284 this->uLastErrorCode = E_NOERROR;
285 return E_NOERROR;
286 }
287
288 int thread_pool::DisableKillDeadThread(void)
289 {
290 HANDLE hThread;
291
292 if (this->ulThreadKillerId == 0)
293 {
294 this->uLastErrorCode = E_KILLER_END_FAILED;
295 return E_KILLER_END_FAILED;
296 }
297
298 this->bTerminateThreadKiller = true;
299
300 Sleep(1000);
301
302 if (!this->bTerminateThreadKiller)
303 {
304 syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
305 }
306 else
307 {
308 if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,this->ulThreadKillerId)) == NULL)
309 {
310 syslog << logfile::log_head << "Get thread handle error in DisableKillDeadThread()" << endl;
311 this->uLastErrorCode = E_INVALID_THREAD;
312 return E_INVALID_THREAD;
313 }
314 if (this->SetLock(true) == 0)
315 {
316 if (TerminateThread(hThread,0))
317 {
318 CloseHandle(hThread);
319 this->ulThreadKillerId = 0;
320 this->SetLock(false);
321 syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
322 this->uLastErrorCode = E_NOERROR;
323 return E_NOERROR;
324 }
325 }
326 CloseHandle(hThread);
327 this->SetLock(false);
328 syslog << logfile::log_head << "Terminate killer thread ... Failed" << endl;
329 this->uLastErrorCode = E_KILLER_END_FAILED;
330 return E_KILLER_END_FAILED;
331 }
332
333 this->uLastErrorCode = E_NOERROR;
334 return E_NOERROR;
335 }
336
337 int thread_pool::KillAllThread(void)
338 {
339 UINT i;
340 ULONG ulThreadId;
341 HANDLE hThread;
342
343 for (i=0; i < this->uThreadMax; i++)
344 {
345 if ((this->ulThreadIdList[i] != 0))
346 {
347 ulThreadId = this->ulThreadIdList[i];
348 // Remove dead thread from thread pool
349 if (this->RemoveThread(ulThreadId) != 0)
350 {
351 syslog << logfile::log_head << "Unregister thread ... Failed" << endl;
352 }
353 // Kill dead thread
354 if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,ulThreadId)) == NULL)
355 {
356 syslog << logfile::log_head << "Get thread handle error in KillAllThread()" << endl;
357 }
358 else
359 {
360 if (TerminateThread(hThread,-1))
361 {
362 syslog << logfile::log_head << "Terminate all thread (" << ulThreadId << ") ... OK" << endl;
363 }
364 else
365 {
366 syslog << logfile::log_head << "Terminate all thread (" << ulThreadId << ") ... Failed" << endl;
367 }
368 CloseHandle(hThread);
369 }
370 }
371 }
372
373 this->uLastErrorCode = E_NOERROR;
374 return E_NOERROR;
375 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1