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

Diff of /innwebd/thread_pool.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.1 by sysadm, Sat Jul 3 08:38:54 2004 UTC Revision 1.10 by sysadm, Fri Apr 11 17:14:49 2008 UTC
# Line 1  Line 1 
1  /*******************************************************/  /*******************************************************/
2  /*                                                     */  /*                                                     */
3  /*  LeafOK Innd                                        */  /*  LeafOK Innbbsd                                     */
 /*  Copyright (C) LeafOK.com, 2003-2004                */  
4  /*                                                     */  /*                                                     */
5  /*  Programmed by Leaf                                 */  /*  Copyright (C) LeafOK.com, 2003-2008                */
 /*  E-mail:leaf@leafok.com  QQ:6049044                 */  
6  /*                                                     */  /*                                                     */
7  /*  http://bbs.leafok.com                              */  /*  http://www.leafok.com                              */
 /*  http://bbs.leafok.net                              */  
 /*  http://bbs.fenglin.info                            */  
8  /*                                                     */  /*                                                     */
9  /*******************************************************/  /*******************************************************/
10    
11  #include "StdAfx.h"  #include "StdAfx.h"
12  #include ".\thread_pool.h"  #include ".\thread_pool.h"
13    
14  thread_pool::thread_pool(UINT uThreadMax, double thread_timeout)  thread_pool::thread_pool(UINT uThreadMax)
15  {  {
16          UINT i;          UINT i;
17    
18          this->uLastErrorCode = E_NOERROR;          this->uLastErrorCode = E_NOERROR;
19          this->uThreadCount = 0;          this->uThreadCount = 0;
20          this->uThreadMax = uThreadMax;          this->uThreadMax = uThreadMax;
21          this->thread_timeout = thread_timeout;          this->ulThreadKillerId = 0;
22    
23            if (this->uThreadMax > TS_MAX_THREAD)
24            {
25                    this->uThreadMax = 0;
26                    this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
27            }
28    
29          for (i=0; i < this->uThreadMax; i++)          for (i=0; i < this->uThreadMax; i++)
30          {          {
31                  this->hThreadList[i] = NULL;                  this->ulThreadIdList[i] = 0;
32                  this->uThreadStatusList[i] = S_UNUSED;                  this->uThreadStatusList[i] = S_UNUSED;
33                  this->time_status_keep[i] = 0;                  this->time_status_set[i] = clock();
34          }          }
35    
36          this->SetLock(false);          this->SetLock(false);
37    
38            this->EnableKillDeadThread();
39  }  }
40    
41  thread_pool::~thread_pool(void)  thread_pool::~thread_pool(void)
42  {  {
43            this->DisableKillDeadThread();
44            this->KillAllThread();
45  }  }
46    
47  int thread_pool::AddThread(HANDLE hThread)  int thread_pool::AddThread(ULONG ulThreadId, clock_t thread_timeout)
48  {  {
49          UINT i;          UINT i;
50    
         if (this->SetLock(true) == 0)  
         {  
                 return this->uLastErrorCode;  
         }  
   
51          if (this->uThreadCount >= this->uThreadMax)          if (this->uThreadCount >= this->uThreadMax)
52          {          {
                 this->SetLock(false);  
53                  this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;                  this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
54                  return E_MAX_THREAD_EXCEEDED;                  return E_MAX_THREAD_EXCEEDED;
55          }          }
56    
57          for (i=0; i < this->uThreadMax; i++)          if (thread_timeout < 0)
58          {          {
59                  if (this->uThreadStatusList[i] == S_UNUSED)                  this->uLastErrorCode = E_INVALID_TIMEOUT;
60                    return E_INVALID_TIMEOUT;
61            }
62    
63            if (this->SetLock(true) == 0)
64            {
65                    for (i=0; i < this->uThreadMax; i++)
66                  {                  {
67                          this->hThreadList[i] = hThread;                          if (this->uThreadStatusList[i] == S_UNUSED)
68                          this->uThreadCount++;                          {
69                          this->SetLock(false);                                  this->ulThreadIdList[i] = ulThreadId;
70                          this->uLastErrorCode = E_NOERROR;                                  this->uThreadStatusList[i] = S_WAITING;
71                          return E_NOERROR;                                  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                  }                  }
79                    this->SetLock(false);
80                    this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
81                    return E_MAX_THREAD_EXCEEDED;
82          }          }
83    
84          this->SetLock(false);          return E_LOCK_TIMEOUT;
         this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;  
         return E_MAX_THREAD_EXCEEDED;  
85  }  }
86    
87  int thread_pool::SetLock(bool bLock, time_t tTimeout)  int thread_pool::SetLock(bool bLock, clock_t tTimeout)
88  {  {
89          time_t wait = 0;          clock_t wait = 0;
90            
91          if (!bLock) // Free lock          if (!bLock) // Free lock
92          {          {
# Line 99  int thread_pool::SetLock(bool bLock, tim Line 111  int thread_pool::SetLock(bool bLock, tim
111          return E_NOERROR;          return E_NOERROR;
112  }  }
113    
114  UINT thread_pool::GetLastError(void)  int thread_pool::GetLastError(void) const
115  {  {
116          return this->uLastErrorCode;          return this->uLastErrorCode;
117  }  }
118    
119  int thread_pool::RemoveThread(HANDLE hThread)  int thread_pool::RemoveThread(ULONG ulThreadId)
120  {  {
121          UINT i;          UINT i;
122    
         if (this->SetLock(true) == 0)  
         {  
                 return this->uLastErrorCode;  
         }  
   
123          if (this->uThreadCount <= 0)          if (this->uThreadCount <= 0)
124          {          {
                 this->SetLock(false);  
125                  this->uLastErrorCode = E_THREAD_NOT_FOUND;                  this->uLastErrorCode = E_THREAD_NOT_FOUND;
126                  return E_THREAD_NOT_FOUND;                  return E_THREAD_NOT_FOUND;
127          }          }
128    
129          for (i=0; i < this->uThreadMax; i++)          if (this->SetLock(true) == 0)
130          {          {
131                  if (this->hThreadList[i] == hThread)                  for (i=0; i < this->uThreadMax; i++)
132                  {                  {
133                          this->hThreadList[i] = NULL;                          if (this->ulThreadIdList[i] == ulThreadId)
134                          this->uThreadCount--;                          {
135                          this->SetLock(false);                                  this->ulThreadIdList[i] = 0;
136                          this->uLastErrorCode = E_NOERROR;                                  this->uThreadStatusList[i] = S_UNUSED;
137                          return this->uLastErrorCode;                                  this->uThreadCount--;
138                                    this->SetLock(false);
139                                    this->uLastErrorCode = E_NOERROR;
140                                    return E_NOERROR;
141                            }
142                  }                  }
143                    this->SetLock(false);
144                    this->uLastErrorCode = E_THREAD_NOT_FOUND;
145                    return E_THREAD_NOT_FOUND;
146          }          }
147    
148          this->SetLock(false);          return E_LOCK_TIMEOUT;
         this->uLastErrorCode = E_THREAD_NOT_FOUND;  
         return E_THREAD_NOT_FOUND;  
149  }  }
150    
151    
152  int thread_pool::SetThreadStatus(HANDLE hThread, UINT uStatus)  int thread_pool::SetThreadStatus(ULONG ulThreadId, int uStatus)
153  {  {
154          UINTT i;          UINT i;
   
         if (this->SetLock(true) == 0)  
         {  
                 return this->uLastErrorCode;  
         }  
155    
156          if (this->uThreadCount <= 0)          if (this->uThreadCount <= 0)
157          {          {
                 this->SetLock(false);  
158                  this->uLastErrorCode = E_THREAD_NOT_FOUND;                  this->uLastErrorCode = E_THREAD_NOT_FOUND;
159                  return E_THREAD_NOT_FOUND;                  return E_THREAD_NOT_FOUND;
160          }          }
161    
162          for (i=0; i < this->uThreadMax; i++)          for (i=0; i < this->uThreadMax; i++)
163          {          {
164                  if (this->hThreadList[i] == hThread)                  if (this->ulThreadIdList[i] == ulThreadId)
165                  {                  {
166                          this->uThreadStatusList[i] = (thread_status)uStatus;                          this->uThreadStatusList[i] = (thread_status)uStatus;
167                          this->SetLock(false);                          this->time_status_set[i] = clock();
168                          this->uLastErrorCode = E_NOERROR;                          this->uLastErrorCode = E_NOERROR;
169                          return this->uLastErrorCode;                          return this->uLastErrorCode;
170                  }                  }
171          }          }
172    
         this->SetLock(false);  
173          this->uLastErrorCode = E_THREAD_NOT_FOUND;          this->uLastErrorCode = E_THREAD_NOT_FOUND;
174          return E_THREAD_NOT_FOUND;          return E_THREAD_NOT_FOUND;
175  }  }
176    
177  UINT thread_pool::GetThreadStatus(HANDLE hThread)  int thread_pool::GetThreadStatus(ULONG ulThreadId)
178  {  {
179          UINT i;          UINT i;
180    
# Line 182  UINT thread_pool::GetThreadStatus(HANDLE Line 186  UINT thread_pool::GetThreadStatus(HANDLE
186    
187          for (i=0; i < this->uThreadMax; i++)          for (i=0; i < this->uThreadMax; i++)
188          {          {
189                  if (this->hThreadList[i] == hThread)                  if (this->ulThreadIdList[i] == ulThreadId)
190                  {                  {
191                          this->uLastErrorCode = E_NOERROR;                          this->uLastErrorCode = E_NOERROR;
192                          return this->uThreadStatusList[i];                          return this->uThreadStatusList[i];
# Line 192  UINT thread_pool::GetThreadStatus(HANDLE Line 196  UINT thread_pool::GetThreadStatus(HANDLE
196          this->uLastErrorCode = E_THREAD_NOT_FOUND;          this->uLastErrorCode = E_THREAD_NOT_FOUND;
197          return S_UNKNOWN;          return S_UNKNOWN;
198  }  }
199    
200    DWORD thread_pool::KillDeadThread(LPVOID pParam)
201    {
202            thread_pool *p;
203        UINT i;
204            HANDLE hThread;
205            ULONG ulThreadId;
206            int t_count = 0;
207    
208            p = (thread_pool*)pParam;
209    
210            p->ulThreadKillerId = GetCurrentThreadId();
211    
212            while(!p->bTerminateThreadKiller)
213            {
214                    if (t_count>=100)
215                    {
216                            t_count=0;
217    
218                            for (i=0; i < p->uThreadMax; i++)
219                            {
220                                    if ((p->ulThreadIdList[i] != 0) &&
221                                            (p->uThreadStatusList[i] == S_WORKING) &&
222                                            (clock() - p->time_status_set[i] > p->thread_timeout[i]))
223                                    {
224                                            ulThreadId = p->ulThreadIdList[i];
225                                            // Remove dead thread from thread pool
226                                            if (p->RemoveThread(ulThreadId) != 0)
227                                            {
228                                                    syslog << logfile::log_head << "Unregister thread (" << ulThreadId << ") ... Failed" << endl;
229                                            }
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                                            {
237                                                    if (TerminateThread(hThread,-1))
238                                                    {
239                                                            syslog << logfile::log_head << "Terminate dead thread (" << ulThreadId << ") ... OK" << endl;
240                                                    }
241                                                    else
242                                                    {
243                                                            syslog << logfile::log_head << "Terminate dead thread (" << ulThreadId << ") ... Failed" << endl;
244                                                    }
245                                                    CloseHandle(hThread);
246                                            }
247                                    }
248                            }
249                    }
250    
251                    Sleep(100);
252                    t_count++;
253            }
254    
255            p->bTerminateThreadKiller = false;
256            p->ulThreadKillerId = 0;
257    
258            return (E_NOERROR);
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    
271            this->bTerminateThreadKiller = false;
272            if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_pool::KillDeadThread,(LPVOID)this,0,&ulThreadId))
273            {
274                    CloseHandle(hThreadCurrent);
275                    syslog << logfile::log_head << "Create killer thread ... OK" << endl;
276            }
277            else
278            {
279                    syslog << logfile::log_head << "Create killer thread ... Failed" << endl;
280                    this->uLastErrorCode = E_KILLER_BEGIN_FAILED;
281                    return E_KILLER_BEGIN_FAILED;
282            }
283    
284            this->uLastErrorCode = E_NOERROR;
285            return E_NOERROR;
286    }
287    
288    int thread_pool::DisableKillDeadThread(void)
289    {
290            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    
300            Sleep(1000);
301    
302            if (!this->bTerminateThreadKiller)
303            {
304                    syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
305            }
306            else
307            {
308                    if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,this->ulThreadKillerId)) == NULL)
309                    {
310                            syslog << logfile::log_head << "Get thread handle error in DisableKillDeadThread()" << endl;
311                            this->uLastErrorCode = E_INVALID_THREAD;
312                            return E_INVALID_THREAD;
313                    }
314                    if (this->SetLock(true) == 0)
315                    {
316                            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                    }
326                    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            }
332    
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                                            syslog << logfile::log_head << "Terminate all thread (" << ulThreadId << ") ... OK" << endl;
363                                    }
364                                    else
365                                    {
366                                            syslog << logfile::log_head << "Terminate all thread (" << ulThreadId << ") ... Failed" << endl;
367                                    }
368                                    CloseHandle(hThread);
369                            }
370                    }
371            }
372    
373            this->uLastErrorCode = E_NOERROR;
374            return E_NOERROR;
375    }


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

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