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

Contents of /innwebd/thread_pool.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations)
Sat Jul 3 15:10:23 2004 UTC (21 years, 8 months ago) by sysadm
Branch: MAIN
Changes since 1.3: +44 -32 lines
Content type: text/x-c++src
no message

1 /*******************************************************/
2 /* */
3 /* LeafOK Innd */
4 /* Copyright (C) LeafOK.com, 2003-2004 */
5 /* */
6 /* Programmed by Leaf */
7 /* E-mail:leaf@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->hThreadKiller = NULL;
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->hThreadList[i] = NULL;
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 }
49
50 int thread_pool::AddThread(HANDLE hThread, clock_t thread_timeout)
51 {
52 UINT i;
53
54 if (this->SetLock(true) != 0)
55 {
56 return this->uLastErrorCode;
57 }
58
59 if (this->uThreadCount >= this->uThreadMax)
60 {
61 this->SetLock(false);
62 this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
63 return E_MAX_THREAD_EXCEEDED;
64 }
65
66 if (thread_timeout < 0)
67 {
68 this->uLastErrorCode = E_INVALID_TIMEOUT;
69 return E_INVALID_TIMEOUT;
70 }
71
72 for (i=0; i < this->uThreadMax; i++)
73 {
74 if (this->uThreadStatusList[i] == S_UNUSED)
75 {
76 this->hThreadList[i] = hThread;
77 this->uThreadStatusList[i] = S_WAITING;
78 this->thread_timeout[i] = thread_timeout;
79 this->time_status_set[i] = clock();
80 this->uThreadCount++;
81 this->SetLock(false);
82 this->uLastErrorCode = E_NOERROR;
83 return E_NOERROR;
84 }
85 }
86
87 this->SetLock(false);
88 this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
89 return E_MAX_THREAD_EXCEEDED;
90 }
91
92 int thread_pool::SetLock(bool bLock, clock_t tTimeout)
93 {
94 clock_t wait = 0;
95
96 if (!bLock) // Free lock
97 {
98 this->bProcessLock = false;
99 this->uLastErrorCode = E_NOERROR;
100 return E_NOERROR;
101 }
102
103 while (this->bProcessLock) // Locked by others
104 {
105 Sleep(10);
106 wait += 10;
107 if (wait > tTimeout) // Timeout
108 {
109 this->uLastErrorCode = E_LOCK_TIMEOUT;
110 return E_LOCK_TIMEOUT;
111 }
112 }
113 this->bProcessLock = true;
114 this->uLastErrorCode = E_NOERROR;
115
116 return E_NOERROR;
117 }
118
119 int thread_pool::GetLastError(void) const
120 {
121 return this->uLastErrorCode;
122 }
123
124 int thread_pool::RemoveThread(HANDLE hThread)
125 {
126 UINT i;
127
128 if (this->SetLock(true) != 0)
129 {
130 return this->uLastErrorCode;
131 }
132
133 if (this->uThreadCount <= 0)
134 {
135 this->SetLock(false);
136 this->uLastErrorCode = E_THREAD_NOT_FOUND;
137 return E_THREAD_NOT_FOUND;
138 }
139
140 for (i=0; i < this->uThreadMax; i++)
141 {
142 if (this->hThreadList[i] == hThread)
143 {
144 this->hThreadList[i] = NULL;
145 this->uThreadCount--;
146 this->SetLock(false);
147 this->uLastErrorCode = E_NOERROR;
148 return this->uLastErrorCode;
149 }
150 }
151
152 this->SetLock(false);
153 this->uLastErrorCode = E_THREAD_NOT_FOUND;
154 return E_THREAD_NOT_FOUND;
155 }
156
157
158 int thread_pool::SetThreadStatus(HANDLE hThread, int uStatus)
159 {
160 UINTT i;
161
162 if (this->SetLock(true) != 0)
163 {
164 return this->uLastErrorCode;
165 }
166
167 if (this->uThreadCount <= 0)
168 {
169 this->SetLock(false);
170 this->uLastErrorCode = E_THREAD_NOT_FOUND;
171 return E_THREAD_NOT_FOUND;
172 }
173
174 for (i=0; i < this->uThreadMax; i++)
175 {
176 if (this->hThreadList[i] == hThread)
177 {
178 this->uThreadStatusList[i] = (thread_status)uStatus;
179 this->time_status_set[i] = clock();
180 this->SetLock(false);
181 this->uLastErrorCode = E_NOERROR;
182 return this->uLastErrorCode;
183 }
184 }
185
186 this->SetLock(false);
187 this->uLastErrorCode = E_THREAD_NOT_FOUND;
188 return E_THREAD_NOT_FOUND;
189 }
190
191 int thread_pool::GetThreadStatus(HANDLE hThread)
192 {
193 UINT i;
194
195 if (this->uThreadCount <= 0)
196 {
197 this->uLastErrorCode = E_THREAD_NOT_FOUND;
198 return S_UNKNOWN;
199 }
200
201 for (i=0; i < this->uThreadMax; i++)
202 {
203 if (this->hThreadList[i] == hThread)
204 {
205 this->uLastErrorCode = E_NOERROR;
206 return this->uThreadStatusList[i];
207 }
208 }
209
210 this->uLastErrorCode = E_THREAD_NOT_FOUND;
211 return S_UNKNOWN;
212 }
213
214 DWORD thread_pool::KillDeadThread(LPVOID pParam)
215 {
216 thread_pool *p;
217 UINT i;
218 int t_count = 0;
219
220 p = (thread_pool*)pParam;
221
222 while(!p->bTerminateThreadKiller)
223 {
224 if (t_count>=100)
225 {
226 t_count=0;
227
228 if (p->SetLock(true) == 0)
229 {
230 for (i=0; i < p->uThreadMax; i++)
231 {
232 if ((p->hThreadList[i] != NULL) &&
233 (p->uThreadStatusList[i] == S_WORKING) &&
234 (clock() - p->time_status_set[i] > p->thread_timeout[i]))
235 {
236 if (TerminateThread(p->hThreadList[i],-1))
237 {
238 syslog << logfile::log_head << "Terminate dead thread ... OK" << endl;
239 }
240 else
241 {
242 syslog << logfile::log_head << "Terminate dead thread ... Failed" << endl;
243 }
244 p->hThreadList[i] = NULL;
245 p->uThreadStatusList[i] = S_UNUSED;
246 p->time_status_set[i] = clock();
247 p->uThreadCount--;
248 }
249 }
250 }
251
252 p->SetLock(false);
253 }
254
255 Sleep(100);
256 t_count++;
257 }
258
259 return (E_NOERROR);
260 }
261
262 int thread_pool::GetThreadCount(void) const
263 {
264 return this->uThreadCount;
265 }
266
267 int thread_pool::EnableKillDeadThread(void)
268 {
269 HANDLE hThreadCurrent;
270 ULONG ulThreadId;
271
272 this->bTerminateThreadKiller = false;
273 if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_pool::KillDeadThread,(LPVOID)this,0,&ulThreadId))
274 {
275 this->hThreadKiller = hThreadCurrent;
276 syslog << logfile::log_head << "Create killer thread ... OK" << endl;
277 }
278 else
279 {
280 syslog << logfile::log_head << "Create killer thread ... Failed" << endl;
281 return -1;
282 }
283
284 return 0;
285 }
286
287 int thread_pool::DisableKillDeadThread(void)
288 {
289 bTerminateThreadKiller = true;
290
291 Sleep(1000);
292
293 if (!bTerminateThreadKiller)
294 {
295 syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
296 }
297
298 if (bTerminateThreadKiller && this->hThreadKiller)
299 {
300 if (TerminateThread(this->hThreadKiller,0))
301 {
302 this->hThreadKiller = NULL;
303 syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
304 }
305 else
306 {
307 syslog << logfile::log_head << "Terminate killer thread ... Failed" << endl;
308 return -1;
309 }
310 }
311 return 0;
312 }

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