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

Contents of /innwebd/thread_pool.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations)
Sat Jul 3 13:55:42 2004 UTC (21 years, 8 months ago) by sysadm
Branch: MAIN
Changes since 1.2: +81 -33 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 bool bKillStatus = true;
219
220 p = (thread_pool*)pParam;
221
222 if (p->SetLock(true) != 0)
223 {
224 return p->uLastErrorCode;
225 }
226
227 if (p->uThreadCount <= 0)
228 {
229 p->SetLock(false);
230 p->uLastErrorCode = E_THREAD_NOT_FOUND;
231 return E_THREAD_NOT_FOUND;
232 }
233
234 for (i=0; i < p->uThreadMax; i++)
235 {
236 if ((p->uThreadStatusList[i] == S_WORKING) &&
237 (clock() - p->time_status_set[i] > p->thread_timeout[i]))
238 {
239 if (TerminateThread(p->hThreadList[i],-1))
240 {
241 bKillStatus &= true;
242 syslog << logfile::log_head << "Terminate dead thread ... OK" << endl;
243 }
244 else
245 {
246 bKillStatus &= false;
247 syslog << logfile::log_head << "Terminate dead thread ... Failed" << endl;
248 }
249 p->hThreadList[i] = NULL;
250 p->uThreadStatusList[i] = S_UNUSED;
251 p->time_status_set[i] = clock();
252 p->uThreadCount--;
253 }
254 }
255
256 p->SetLock(false);
257 p->uLastErrorCode = (bKillStatus?E_NOERROR:E_KILL_THREAD_FAILED);
258 return (bKillStatus?E_NOERROR:E_KILL_THREAD_FAILED);
259 }
260
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 if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_pool::KillDeadThread,(LPVOID)this,0,&ulThreadId))
271 {
272 this->hThreadKiller = hThreadCurrent;
273 syslog << logfile::log_head << "Create killer thread ... OK" << endl;
274 }
275 else
276 {
277 syslog << logfile::log_head << "Create killer thread ... Failed" << endl;
278 return -1;
279 }
280
281 return 0;
282 }
283
284 int thread_pool::DisableKillDeadThread(void)
285 {
286 if (this->hThreadKiller)
287 {
288 if (TerminateThread(this->hThreadKiller,0))
289 {
290 this->hThreadKiller = NULL;
291 syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
292 }
293 else
294 {
295 syslog << logfile::log_head << "Terminate killer thread ... Failed" << endl;
296 return -1;
297 }
298 }
299 return 0;
300 }

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