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

Annotation of /innwebd/thread_pool.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (hide annotations)
Sat Feb 26 16:10:26 2005 UTC (21 years ago) by sysadm
Branch: MAIN
Changes since 1.7: +1 -1 lines
Content type: text/x-c++src
Copyright update

1 sysadm 1.1 /*******************************************************/
2     /* */
3 sysadm 1.5 /* LeafOK Innbbsd */
4 sysadm 1.8 /* Copyright (C) LeafOK.com, 2003-2005 */
5 sysadm 1.1 /* */
6     /* Programmed by Leaf */
7 sysadm 1.5 /* E-mail:leaflet@leafok.com QQ:6049044 */
8 sysadm 1.1 /* */
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 sysadm 1.3 thread_pool::thread_pool(UINT uThreadMax)
19 sysadm 1.1 {
20     UINT i;
21    
22     this->uLastErrorCode = E_NOERROR;
23     this->uThreadCount = 0;
24     this->uThreadMax = uThreadMax;
25 sysadm 1.5 this->ulThreadKillerId = 0;
26 sysadm 1.1
27 sysadm 1.3 if (this->uThreadMax > TS_MAX_THREAD)
28 sysadm 1.2 {
29 sysadm 1.3 this->uThreadMax = 0;
30 sysadm 1.2 this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
31     }
32    
33 sysadm 1.1 for (i=0; i < this->uThreadMax; i++)
34     {
35 sysadm 1.5 this->ulThreadIdList[i] = 0;
36 sysadm 1.1 this->uThreadStatusList[i] = S_UNUSED;
37 sysadm 1.2 this->time_status_set[i] = clock();
38 sysadm 1.1 }
39    
40     this->SetLock(false);
41 sysadm 1.3
42     this->EnableKillDeadThread();
43 sysadm 1.1 }
44    
45     thread_pool::~thread_pool(void)
46     {
47 sysadm 1.3 this->DisableKillDeadThread();
48 sysadm 1.5 this->KillAllThread();
49 sysadm 1.1 }
50    
51 sysadm 1.5 int thread_pool::AddThread(ULONG ulThreadId, clock_t thread_timeout)
52 sysadm 1.1 {
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 sysadm 1.3 if (thread_timeout < 0)
62     {
63     this->uLastErrorCode = E_INVALID_TIMEOUT;
64     return E_INVALID_TIMEOUT;
65     }
66    
67 sysadm 1.5 if (this->SetLock(true) == 0)
68 sysadm 1.1 {
69 sysadm 1.5 for (i=0; i < this->uThreadMax; i++)
70 sysadm 1.1 {
71 sysadm 1.5 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 sysadm 1.1 }
83 sysadm 1.5 this->SetLock(false);
84     this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
85     return E_MAX_THREAD_EXCEEDED;
86 sysadm 1.1 }
87    
88 sysadm 1.5 return E_LOCK_TIMEOUT;
89 sysadm 1.1 }
90    
91 sysadm 1.2 int thread_pool::SetLock(bool bLock, clock_t tTimeout)
92 sysadm 1.1 {
93 sysadm 1.2 clock_t wait = 0;
94 sysadm 1.1
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 sysadm 1.3 int thread_pool::GetLastError(void) const
119 sysadm 1.1 {
120     return this->uLastErrorCode;
121     }
122    
123 sysadm 1.5 int thread_pool::RemoveThread(ULONG ulThreadId)
124 sysadm 1.1 {
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 sysadm 1.5 if (this->SetLock(true) == 0)
134 sysadm 1.1 {
135 sysadm 1.5 for (i=0; i < this->uThreadMax; i++)
136 sysadm 1.1 {
137 sysadm 1.5 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 sysadm 1.1 }
147 sysadm 1.5 this->SetLock(false);
148     this->uLastErrorCode = E_THREAD_NOT_FOUND;
149     return E_THREAD_NOT_FOUND;
150 sysadm 1.1 }
151    
152 sysadm 1.5 return E_LOCK_TIMEOUT;
153 sysadm 1.1 }
154    
155    
156 sysadm 1.7 int thread_pool::SetThreadStatus(ULONG ulThreadId, int uStatus)
157 sysadm 1.1 {
158 sysadm 1.7 UINT i;
159 sysadm 1.1
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 sysadm 1.5 if (this->ulThreadIdList[i] == ulThreadId)
169 sysadm 1.1 {
170     this->uThreadStatusList[i] = (thread_status)uStatus;
171 sysadm 1.2 this->time_status_set[i] = clock();
172 sysadm 1.1 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 sysadm 1.5 int thread_pool::GetThreadStatus(ULONG ulThreadId)
182 sysadm 1.1 {
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 sysadm 1.5 if (this->ulThreadIdList[i] == ulThreadId)
194 sysadm 1.1 {
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 sysadm 1.2
204 sysadm 1.3 DWORD thread_pool::KillDeadThread(LPVOID pParam)
205 sysadm 1.2 {
206 sysadm 1.3 thread_pool *p;
207     UINT i;
208 sysadm 1.5 HANDLE hThread;
209     ULONG ulThreadId;
210 sysadm 1.4 int t_count = 0;
211 sysadm 1.3
212     p = (thread_pool*)pParam;
213 sysadm 1.2
214 sysadm 1.5 p->ulThreadKillerId = GetCurrentThreadId();
215    
216 sysadm 1.4 while(!p->bTerminateThreadKiller)
217 sysadm 1.2 {
218 sysadm 1.4 if (t_count>=100)
219     {
220     t_count=0;
221 sysadm 1.2
222 sysadm 1.5 for (i=0; i < p->uThreadMax; i++)
223 sysadm 1.2 {
224 sysadm 1.5 if ((p->ulThreadIdList[i] != 0) &&
225     (p->uThreadStatusList[i] == S_WORKING) &&
226     (clock() - p->time_status_set[i] > p->thread_timeout[i]))
227 sysadm 1.4 {
228 sysadm 1.5 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 sysadm 1.4 {
241 sysadm 1.5 if (TerminateThread(hThread,-1))
242 sysadm 1.4 {
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 sysadm 1.5 CloseHandle(hThread);
250 sysadm 1.4 }
251     }
252 sysadm 1.2 }
253     }
254 sysadm 1.4
255     Sleep(100);
256     t_count++;
257 sysadm 1.2 }
258    
259 sysadm 1.5 p->bTerminateThreadKiller = false;
260     p->ulThreadKillerId = 0;
261    
262 sysadm 1.4 return (E_NOERROR);
263 sysadm 1.2 }
264 sysadm 1.3
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 sysadm 1.4
275     this->bTerminateThreadKiller = false;
276 sysadm 1.3 if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_pool::KillDeadThread,(LPVOID)this,0,&ulThreadId))
277     {
278 sysadm 1.6 CloseHandle(hThreadCurrent);
279 sysadm 1.3 syslog << logfile::log_head << "Create killer thread ... OK" << endl;
280     }
281     else
282     {
283     syslog << logfile::log_head << "Create killer thread ... Failed" << endl;
284 sysadm 1.5 this->uLastErrorCode = E_KILLER_BEGIN_FAILED;
285     return E_KILLER_BEGIN_FAILED;
286 sysadm 1.3 }
287    
288 sysadm 1.5 this->uLastErrorCode = E_NOERROR;
289     return E_NOERROR;
290 sysadm 1.3 }
291    
292     int thread_pool::DisableKillDeadThread(void)
293     {
294 sysadm 1.5 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 sysadm 1.4
304     Sleep(1000);
305    
306 sysadm 1.5 if (!this->bTerminateThreadKiller)
307 sysadm 1.4 {
308     syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
309     }
310 sysadm 1.5 else
311 sysadm 1.3 {
312 sysadm 1.5 if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,this->ulThreadKillerId)) == NULL)
313 sysadm 1.3 {
314 sysadm 1.5 syslog << logfile::log_head << "Get thread handle error in DisableKillDeadThread()" << endl;
315     this->uLastErrorCode = E_INVALID_THREAD;
316     return E_INVALID_THREAD;
317 sysadm 1.3 }
318 sysadm 1.5 if (this->SetLock(true) == 0)
319 sysadm 1.3 {
320 sysadm 1.5 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 sysadm 1.3 }
330 sysadm 1.5 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 sysadm 1.3 }
336 sysadm 1.5
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 sysadm 1.3 }

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