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

Contents of /innwebd/thread_pool.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show annotations)
Sun Jul 4 23:35:00 2004 UTC (21 years, 8 months ago) by sysadm
Branch: MAIN
Changes since 1.6: +2 -2 lines
Content type: text/x-c++src
no message

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 ulThreadId, int uStatus)
157 {
158 UINT 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 CloseHandle(hThreadCurrent);
279 syslog << logfile::log_head << "Create killer thread ... OK" << endl;
280 }
281 else
282 {
283 syslog << logfile::log_head << "Create killer thread ... Failed" << endl;
284 this->uLastErrorCode = E_KILLER_BEGIN_FAILED;
285 return E_KILLER_BEGIN_FAILED;
286 }
287
288 this->uLastErrorCode = E_NOERROR;
289 return E_NOERROR;
290 }
291
292 int thread_pool::DisableKillDeadThread(void)
293 {
294 HANDLE hThread;
295
296 if (this->ulThreadKillerId == 0)
297 {
298 this->uLastErrorCode = E_KILLER_END_FAILED;
299 return E_KILLER_END_FAILED;
300 }
301
302 this->bTerminateThreadKiller = true;
303
304 Sleep(1000);
305
306 if (!this->bTerminateThreadKiller)
307 {
308 syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
309 }
310 else
311 {
312 if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,this->ulThreadKillerId)) == NULL)
313 {
314 syslog << logfile::log_head << "Get thread handle error in DisableKillDeadThread()" << endl;
315 this->uLastErrorCode = E_INVALID_THREAD;
316 return E_INVALID_THREAD;
317 }
318 if (this->SetLock(true) == 0)
319 {
320 if (TerminateThread(hThread,0))
321 {
322 CloseHandle(hThread);
323 this->ulThreadKillerId = 0;
324 this->SetLock(false);
325 syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
326 this->uLastErrorCode = E_NOERROR;
327 return E_NOERROR;
328 }
329 }
330 CloseHandle(hThread);
331 this->SetLock(false);
332 syslog << logfile::log_head << "Terminate killer thread ... Failed" << endl;
333 this->uLastErrorCode = E_KILLER_END_FAILED;
334 return E_KILLER_END_FAILED;
335 }
336
337 this->uLastErrorCode = E_NOERROR;
338 return E_NOERROR;
339 }
340
341 int thread_pool::KillAllThread(void)
342 {
343 UINT i;
344 ULONG ulThreadId;
345 HANDLE hThread;
346
347 for (i=0; i < this->uThreadMax; i++)
348 {
349 if ((this->ulThreadIdList[i] != 0))
350 {
351 ulThreadId = this->ulThreadIdList[i];
352 // Remove dead thread from thread pool
353 if (this->RemoveThread(ulThreadId) != 0)
354 {
355 syslog << logfile::log_head << "Unregister thread ... Failed" << endl;
356 }
357 // Kill dead thread
358 if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,ulThreadId)) == NULL)
359 {
360 syslog << logfile::log_head << "Get thread handle error in KillAllThread()" << endl;
361 }
362 else
363 {
364 if (TerminateThread(hThread,-1))
365 {
366 syslog << logfile::log_head << "Terminate all thread ... OK" << endl;
367 }
368 else
369 {
370 syslog << logfile::log_head << "Terminate all thread ... Failed" << endl;
371 }
372 CloseHandle(hThread);
373 }
374 }
375 }
376
377 this->uLastErrorCode = E_NOERROR;
378 return E_NOERROR;
379 }

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