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

Annotation of /innwebd/thread_pool.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (hide 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 sysadm 1.1 /*******************************************************/
2     /* */
3 sysadm 1.5 /* LeafOK Innbbsd */
4 sysadm 1.1 /* Copyright (C) LeafOK.com, 2003-2004 */
5     /* */
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.5 int thread_pool::SetThreadStatus(ULONG ulThreadd, int uStatus)
157 sysadm 1.1 {
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 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     syslog << logfile::log_head << "Create killer thread ... OK" << endl;
279     }
280     else
281     {
282     syslog << logfile::log_head << "Create killer thread ... Failed" << endl;
283 sysadm 1.5 this->uLastErrorCode = E_KILLER_BEGIN_FAILED;
284     return E_KILLER_BEGIN_FAILED;
285 sysadm 1.3 }
286    
287 sysadm 1.5 this->uLastErrorCode = E_NOERROR;
288     return E_NOERROR;
289 sysadm 1.3 }
290    
291     int thread_pool::DisableKillDeadThread(void)
292     {
293 sysadm 1.5 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 sysadm 1.4
303     Sleep(1000);
304    
305 sysadm 1.5 if (!this->bTerminateThreadKiller)
306 sysadm 1.4 {
307     syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
308     }
309 sysadm 1.5 else
310 sysadm 1.3 {
311 sysadm 1.5 if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,this->ulThreadKillerId)) == NULL)
312 sysadm 1.3 {
313 sysadm 1.5 syslog << logfile::log_head << "Get thread handle error in DisableKillDeadThread()" << endl;
314     this->uLastErrorCode = E_INVALID_THREAD;
315     return E_INVALID_THREAD;
316 sysadm 1.3 }
317 sysadm 1.5 if (this->SetLock(true) == 0)
318 sysadm 1.3 {
319 sysadm 1.5 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 sysadm 1.3 }
329 sysadm 1.5 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 sysadm 1.3 }
335 sysadm 1.5
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 sysadm 1.3 }

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