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

Contents of /innwebd/thread_pool.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations)
Sun Jul 4 06:45:23 2004 UTC (21 years, 8 months ago) by sysadm
Branch: MAIN
Changes since 1.4: +145 -79 lines
Content type: text/x-c++src
Version 1.4.2

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

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