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

Annotation of /innwebd/thread_pool.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (hide 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 sysadm 1.1 /*******************************************************/
2     /* */
3 sysadm 1.5 /* LeafOK Innbbsd */
4 sysadm 1.1 /* */
5 sysadm 1.10 /* Copyright (C) LeafOK.com, 2003-2008 */
6 sysadm 1.1 /* */
7 sysadm 1.10 /* http://www.leafok.com */
8 sysadm 1.1 /* */
9     /*******************************************************/
10    
11     #include "StdAfx.h"
12     #include ".\thread_pool.h"
13    
14 sysadm 1.3 thread_pool::thread_pool(UINT uThreadMax)
15 sysadm 1.1 {
16     UINT i;
17    
18     this->uLastErrorCode = E_NOERROR;
19     this->uThreadCount = 0;
20     this->uThreadMax = uThreadMax;
21 sysadm 1.5 this->ulThreadKillerId = 0;
22 sysadm 1.1
23 sysadm 1.3 if (this->uThreadMax > TS_MAX_THREAD)
24 sysadm 1.2 {
25 sysadm 1.3 this->uThreadMax = 0;
26 sysadm 1.2 this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
27     }
28    
29 sysadm 1.1 for (i=0; i < this->uThreadMax; i++)
30     {
31 sysadm 1.5 this->ulThreadIdList[i] = 0;
32 sysadm 1.1 this->uThreadStatusList[i] = S_UNUSED;
33 sysadm 1.2 this->time_status_set[i] = clock();
34 sysadm 1.1 }
35    
36     this->SetLock(false);
37 sysadm 1.3
38     this->EnableKillDeadThread();
39 sysadm 1.1 }
40    
41     thread_pool::~thread_pool(void)
42     {
43 sysadm 1.3 this->DisableKillDeadThread();
44 sysadm 1.5 this->KillAllThread();
45 sysadm 1.1 }
46    
47 sysadm 1.5 int thread_pool::AddThread(ULONG ulThreadId, clock_t thread_timeout)
48 sysadm 1.1 {
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 sysadm 1.3 if (thread_timeout < 0)
58     {
59     this->uLastErrorCode = E_INVALID_TIMEOUT;
60     return E_INVALID_TIMEOUT;
61     }
62    
63 sysadm 1.5 if (this->SetLock(true) == 0)
64 sysadm 1.1 {
65 sysadm 1.5 for (i=0; i < this->uThreadMax; i++)
66 sysadm 1.1 {
67 sysadm 1.5 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 sysadm 1.1 }
79 sysadm 1.5 this->SetLock(false);
80     this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
81     return E_MAX_THREAD_EXCEEDED;
82 sysadm 1.1 }
83    
84 sysadm 1.5 return E_LOCK_TIMEOUT;
85 sysadm 1.1 }
86    
87 sysadm 1.2 int thread_pool::SetLock(bool bLock, clock_t tTimeout)
88 sysadm 1.1 {
89 sysadm 1.2 clock_t wait = 0;
90 sysadm 1.1
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 sysadm 1.3 int thread_pool::GetLastError(void) const
115 sysadm 1.1 {
116     return this->uLastErrorCode;
117     }
118    
119 sysadm 1.5 int thread_pool::RemoveThread(ULONG ulThreadId)
120 sysadm 1.1 {
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 sysadm 1.5 if (this->SetLock(true) == 0)
130 sysadm 1.1 {
131 sysadm 1.5 for (i=0; i < this->uThreadMax; i++)
132 sysadm 1.1 {
133 sysadm 1.5 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 sysadm 1.1 }
143 sysadm 1.5 this->SetLock(false);
144     this->uLastErrorCode = E_THREAD_NOT_FOUND;
145     return E_THREAD_NOT_FOUND;
146 sysadm 1.1 }
147    
148 sysadm 1.5 return E_LOCK_TIMEOUT;
149 sysadm 1.1 }
150    
151    
152 sysadm 1.7 int thread_pool::SetThreadStatus(ULONG ulThreadId, int uStatus)
153 sysadm 1.1 {
154 sysadm 1.7 UINT i;
155 sysadm 1.1
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 sysadm 1.5 if (this->ulThreadIdList[i] == ulThreadId)
165 sysadm 1.1 {
166     this->uThreadStatusList[i] = (thread_status)uStatus;
167 sysadm 1.2 this->time_status_set[i] = clock();
168 sysadm 1.1 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 sysadm 1.5 int thread_pool::GetThreadStatus(ULONG ulThreadId)
178 sysadm 1.1 {
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 sysadm 1.5 if (this->ulThreadIdList[i] == ulThreadId)
190 sysadm 1.1 {
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 sysadm 1.2
200 sysadm 1.3 DWORD thread_pool::KillDeadThread(LPVOID pParam)
201 sysadm 1.2 {
202 sysadm 1.3 thread_pool *p;
203     UINT i;
204 sysadm 1.5 HANDLE hThread;
205     ULONG ulThreadId;
206 sysadm 1.4 int t_count = 0;
207 sysadm 1.3
208     p = (thread_pool*)pParam;
209 sysadm 1.2
210 sysadm 1.5 p->ulThreadKillerId = GetCurrentThreadId();
211    
212 sysadm 1.4 while(!p->bTerminateThreadKiller)
213 sysadm 1.2 {
214 sysadm 1.4 if (t_count>=100)
215     {
216     t_count=0;
217 sysadm 1.2
218 sysadm 1.5 for (i=0; i < p->uThreadMax; i++)
219 sysadm 1.2 {
220 sysadm 1.5 if ((p->ulThreadIdList[i] != 0) &&
221     (p->uThreadStatusList[i] == S_WORKING) &&
222     (clock() - p->time_status_set[i] > p->thread_timeout[i]))
223 sysadm 1.4 {
224 sysadm 1.5 ulThreadId = p->ulThreadIdList[i];
225     // Remove dead thread from thread pool
226     if (p->RemoveThread(ulThreadId) != 0)
227     {
228 sysadm 1.9 syslog << logfile::log_head << "Unregister thread (" << ulThreadId << ") ... Failed" << endl;
229 sysadm 1.5 }
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 sysadm 1.4 {
237 sysadm 1.5 if (TerminateThread(hThread,-1))
238 sysadm 1.4 {
239 sysadm 1.9 syslog << logfile::log_head << "Terminate dead thread (" << ulThreadId << ") ... OK" << endl;
240 sysadm 1.4 }
241     else
242     {
243 sysadm 1.9 syslog << logfile::log_head << "Terminate dead thread (" << ulThreadId << ") ... Failed" << endl;
244 sysadm 1.4 }
245 sysadm 1.5 CloseHandle(hThread);
246 sysadm 1.4 }
247     }
248 sysadm 1.2 }
249     }
250 sysadm 1.4
251     Sleep(100);
252     t_count++;
253 sysadm 1.2 }
254    
255 sysadm 1.5 p->bTerminateThreadKiller = false;
256     p->ulThreadKillerId = 0;
257    
258 sysadm 1.4 return (E_NOERROR);
259 sysadm 1.2 }
260 sysadm 1.3
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 sysadm 1.4
271     this->bTerminateThreadKiller = false;
272 sysadm 1.3 if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_pool::KillDeadThread,(LPVOID)this,0,&ulThreadId))
273     {
274 sysadm 1.6 CloseHandle(hThreadCurrent);
275 sysadm 1.3 syslog << logfile::log_head << "Create killer thread ... OK" << endl;
276     }
277     else
278     {
279     syslog << logfile::log_head << "Create killer thread ... Failed" << endl;
280 sysadm 1.5 this->uLastErrorCode = E_KILLER_BEGIN_FAILED;
281     return E_KILLER_BEGIN_FAILED;
282 sysadm 1.3 }
283    
284 sysadm 1.5 this->uLastErrorCode = E_NOERROR;
285     return E_NOERROR;
286 sysadm 1.3 }
287    
288     int thread_pool::DisableKillDeadThread(void)
289     {
290 sysadm 1.5 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 sysadm 1.4
300     Sleep(1000);
301    
302 sysadm 1.5 if (!this->bTerminateThreadKiller)
303 sysadm 1.4 {
304     syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
305     }
306 sysadm 1.5 else
307 sysadm 1.3 {
308 sysadm 1.5 if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,this->ulThreadKillerId)) == NULL)
309 sysadm 1.3 {
310 sysadm 1.5 syslog << logfile::log_head << "Get thread handle error in DisableKillDeadThread()" << endl;
311     this->uLastErrorCode = E_INVALID_THREAD;
312     return E_INVALID_THREAD;
313 sysadm 1.3 }
314 sysadm 1.5 if (this->SetLock(true) == 0)
315 sysadm 1.3 {
316 sysadm 1.5 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 sysadm 1.3 }
326 sysadm 1.5 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 sysadm 1.3 }
332 sysadm 1.5
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 sysadm 1.9 syslog << logfile::log_head << "Terminate all thread (" << ulThreadId << ") ... OK" << endl;
363 sysadm 1.5 }
364     else
365     {
366 sysadm 1.9 syslog << logfile::log_head << "Terminate all thread (" << ulThreadId << ") ... Failed" << endl;
367 sysadm 1.5 }
368     CloseHandle(hThread);
369     }
370     }
371     }
372    
373     this->uLastErrorCode = E_NOERROR;
374     return E_NOERROR;
375 sysadm 1.3 }

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