/[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.7 by sysadm, Sun Jul 4 23:35:00 2004 UTC
# Line 1  Line 1 
1  /*******************************************************/  /*******************************************************/
2  /*                                                     */  /*                                                     */
3  /*  LeafOK Innd                                        */  /*  LeafOK Innbbsd                                     */
4  /*  Copyright (C) LeafOK.com, 2003-2004                */  /*  Copyright (C) LeafOK.com, 2003-2004                */
5  /*                                                     */  /*                                                     */
6  /*  Programmed by Leaf                                 */  /*  Programmed by Leaf                                 */
7  /*  E-mail:leaf@leafok.com  QQ:6049044                 */  /*  E-mail:leaflet@leafok.com  QQ:6049044              */
8  /*                                                     */  /*                                                     */
9  /*  http://bbs.leafok.com                              */  /*  http://bbs.leafok.com                              */
10  /*  http://bbs.leafok.net                              */  /*  http://bbs.leafok.net                              */
# Line 15  Line 15 
15  #include "StdAfx.h"  #include "StdAfx.h"
16  #include ".\thread_pool.h"  #include ".\thread_pool.h"
17    
18  thread_pool::thread_pool(UINT uThreadMax, double thread_timeout)  thread_pool::thread_pool(UINT uThreadMax)
19  {  {
20          UINT i;          UINT i;
21    
22          this->uLastErrorCode = E_NOERROR;          this->uLastErrorCode = E_NOERROR;
23          this->uThreadCount = 0;          this->uThreadCount = 0;
24          this->uThreadMax = uThreadMax;          this->uThreadMax = uThreadMax;
25          this->thread_timeout = thread_timeout;          this->ulThreadKillerId = 0;
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++)          for (i=0; i < this->uThreadMax; i++)
34          {          {
35                  this->hThreadList[i] = NULL;                  this->ulThreadIdList[i] = 0;
36                  this->uThreadStatusList[i] = S_UNUSED;                  this->uThreadStatusList[i] = S_UNUSED;
37                  this->time_status_keep[i] = 0;                  this->time_status_set[i] = clock();
38          }          }
39    
40          this->SetLock(false);          this->SetLock(false);
41    
42            this->EnableKillDeadThread();
43  }  }
44    
45  thread_pool::~thread_pool(void)  thread_pool::~thread_pool(void)
46  {  {
47            this->DisableKillDeadThread();
48            this->KillAllThread();
49  }  }
50    
51  int thread_pool::AddThread(HANDLE hThread)  int thread_pool::AddThread(ULONG ulThreadId, clock_t thread_timeout)
52  {  {
53          UINT i;          UINT i;
54    
         if (this->SetLock(true) == 0)  
         {  
                 return this->uLastErrorCode;  
         }  
   
55          if (this->uThreadCount >= this->uThreadMax)          if (this->uThreadCount >= this->uThreadMax)
56          {          {
                 this->SetLock(false);  
57                  this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;                  this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
58                  return E_MAX_THREAD_EXCEEDED;                  return E_MAX_THREAD_EXCEEDED;
59          }          }
60    
61          for (i=0; i < this->uThreadMax; i++)          if (thread_timeout < 0)
62          {          {
63                  if (this->uThreadStatusList[i] == S_UNUSED)                  this->uLastErrorCode = E_INVALID_TIMEOUT;
64                    return E_INVALID_TIMEOUT;
65            }
66    
67            if (this->SetLock(true) == 0)
68            {
69                    for (i=0; i < this->uThreadMax; i++)
70                  {                  {
71                          this->hThreadList[i] = hThread;                          if (this->uThreadStatusList[i] == S_UNUSED)
72                          this->uThreadCount++;                          {
73                          this->SetLock(false);                                  this->ulThreadIdList[i] = ulThreadId;
74                          this->uLastErrorCode = E_NOERROR;                                  this->uThreadStatusList[i] = S_WAITING;
75                          return E_NOERROR;                                  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                  }                  }
83                    this->SetLock(false);
84                    this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;
85                    return E_MAX_THREAD_EXCEEDED;
86          }          }
87    
88          this->SetLock(false);          return E_LOCK_TIMEOUT;
         this->uLastErrorCode = E_MAX_THREAD_EXCEEDED;  
         return E_MAX_THREAD_EXCEEDED;  
89  }  }
90    
91  int thread_pool::SetLock(bool bLock, time_t tTimeout)  int thread_pool::SetLock(bool bLock, clock_t tTimeout)
92  {  {
93          time_t wait = 0;          clock_t wait = 0;
94            
95          if (!bLock) // Free lock          if (!bLock) // Free lock
96          {          {
# Line 99  int thread_pool::SetLock(bool bLock, tim Line 115  int thread_pool::SetLock(bool bLock, tim
115          return E_NOERROR;          return E_NOERROR;
116  }  }
117    
118  UINT thread_pool::GetLastError(void)  int thread_pool::GetLastError(void) const
119  {  {
120          return this->uLastErrorCode;          return this->uLastErrorCode;
121  }  }
122    
123  int thread_pool::RemoveThread(HANDLE hThread)  int thread_pool::RemoveThread(ULONG ulThreadId)
124  {  {
125          UINT i;          UINT i;
126    
         if (this->SetLock(true) == 0)  
         {  
                 return this->uLastErrorCode;  
         }  
   
127          if (this->uThreadCount <= 0)          if (this->uThreadCount <= 0)
128          {          {
                 this->SetLock(false);  
129                  this->uLastErrorCode = E_THREAD_NOT_FOUND;                  this->uLastErrorCode = E_THREAD_NOT_FOUND;
130                  return E_THREAD_NOT_FOUND;                  return E_THREAD_NOT_FOUND;
131          }          }
132    
133          for (i=0; i < this->uThreadMax; i++)          if (this->SetLock(true) == 0)
134          {          {
135                  if (this->hThreadList[i] == hThread)                  for (i=0; i < this->uThreadMax; i++)
136                  {                  {
137                          this->hThreadList[i] = NULL;                          if (this->ulThreadIdList[i] == ulThreadId)
138                          this->uThreadCount--;                          {
139                          this->SetLock(false);                                  this->ulThreadIdList[i] = 0;
140                          this->uLastErrorCode = E_NOERROR;                                  this->uThreadStatusList[i] = S_UNUSED;
141                          return this->uLastErrorCode;                                  this->uThreadCount--;
142                                    this->SetLock(false);
143                                    this->uLastErrorCode = E_NOERROR;
144                                    return E_NOERROR;
145                            }
146                  }                  }
147                    this->SetLock(false);
148                    this->uLastErrorCode = E_THREAD_NOT_FOUND;
149                    return E_THREAD_NOT_FOUND;
150          }          }
151    
152          this->SetLock(false);          return E_LOCK_TIMEOUT;
         this->uLastErrorCode = E_THREAD_NOT_FOUND;  
         return E_THREAD_NOT_FOUND;  
153  }  }
154    
155    
156  int thread_pool::SetThreadStatus(HANDLE hThread, UINT uStatus)  int thread_pool::SetThreadStatus(ULONG ulThreadId, int uStatus)
157  {  {
158          UINTT i;          UINT i;
   
         if (this->SetLock(true) == 0)  
         {  
                 return this->uLastErrorCode;  
         }  
159    
160          if (this->uThreadCount <= 0)          if (this->uThreadCount <= 0)
161          {          {
                 this->SetLock(false);  
162                  this->uLastErrorCode = E_THREAD_NOT_FOUND;                  this->uLastErrorCode = E_THREAD_NOT_FOUND;
163                  return E_THREAD_NOT_FOUND;                  return E_THREAD_NOT_FOUND;
164          }          }
165    
166          for (i=0; i < this->uThreadMax; i++)          for (i=0; i < this->uThreadMax; i++)
167          {          {
168                  if (this->hThreadList[i] == hThread)                  if (this->ulThreadIdList[i] == ulThreadId)
169                  {                  {
170                          this->uThreadStatusList[i] = (thread_status)uStatus;                          this->uThreadStatusList[i] = (thread_status)uStatus;
171                          this->SetLock(false);                          this->time_status_set[i] = clock();
172                          this->uLastErrorCode = E_NOERROR;                          this->uLastErrorCode = E_NOERROR;
173                          return this->uLastErrorCode;                          return this->uLastErrorCode;
174                  }                  }
175          }          }
176    
         this->SetLock(false);  
177          this->uLastErrorCode = E_THREAD_NOT_FOUND;          this->uLastErrorCode = E_THREAD_NOT_FOUND;
178          return E_THREAD_NOT_FOUND;          return E_THREAD_NOT_FOUND;
179  }  }
180    
181  UINT thread_pool::GetThreadStatus(HANDLE hThread)  int thread_pool::GetThreadStatus(ULONG ulThreadId)
182  {  {
183          UINT i;          UINT i;
184    
# Line 182  UINT thread_pool::GetThreadStatus(HANDLE Line 190  UINT thread_pool::GetThreadStatus(HANDLE
190    
191          for (i=0; i < this->uThreadMax; i++)          for (i=0; i < this->uThreadMax; i++)
192          {          {
193                  if (this->hThreadList[i] == hThread)                  if (this->ulThreadIdList[i] == ulThreadId)
194                  {                  {
195                          this->uLastErrorCode = E_NOERROR;                          this->uLastErrorCode = E_NOERROR;
196                          return this->uThreadStatusList[i];                          return this->uThreadStatusList[i];
# Line 192  UINT thread_pool::GetThreadStatus(HANDLE Line 200  UINT thread_pool::GetThreadStatus(HANDLE
200          this->uLastErrorCode = E_THREAD_NOT_FOUND;          this->uLastErrorCode = E_THREAD_NOT_FOUND;
201          return S_UNKNOWN;          return S_UNKNOWN;
202  }  }
203    
204    DWORD thread_pool::KillDeadThread(LPVOID pParam)
205    {
206            thread_pool *p;
207        UINT i;
208            HANDLE hThread;
209            ULONG ulThreadId;
210            int t_count = 0;
211    
212            p = (thread_pool*)pParam;
213    
214            p->ulThreadKillerId = GetCurrentThreadId();
215    
216            while(!p->bTerminateThreadKiller)
217            {
218                    if (t_count>=100)
219                    {
220                            t_count=0;
221    
222                            for (i=0; i < p->uThreadMax; i++)
223                            {
224                                    if ((p->ulThreadIdList[i] != 0) &&
225                                            (p->uThreadStatusList[i] == S_WORKING) &&
226                                            (clock() - p->time_status_set[i] > p->thread_timeout[i]))
227                                    {
228                                            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                                            {
241                                                    if (TerminateThread(hThread,-1))
242                                                    {
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                                                    CloseHandle(hThread);
250                                            }
251                                    }
252                            }
253                    }
254    
255                    Sleep(100);
256                    t_count++;
257            }
258    
259            p->bTerminateThreadKiller = false;
260            p->ulThreadKillerId = 0;
261    
262            return (E_NOERROR);
263    }
264    
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    
275            this->bTerminateThreadKiller = false;
276            if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_pool::KillDeadThread,(LPVOID)this,0,&ulThreadId))
277            {
278                    CloseHandle(hThreadCurrent);
279                    syslog << logfile::log_head << "Create killer thread ... OK" << endl;
280            }
281            else
282            {
283                    syslog << logfile::log_head << "Create killer thread ... Failed" << endl;
284                    this->uLastErrorCode = E_KILLER_BEGIN_FAILED;
285                    return E_KILLER_BEGIN_FAILED;
286            }
287    
288            this->uLastErrorCode = E_NOERROR;
289            return E_NOERROR;
290    }
291    
292    int thread_pool::DisableKillDeadThread(void)
293    {
294            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    
304            Sleep(1000);
305    
306            if (!this->bTerminateThreadKiller)
307            {
308                    syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;
309            }
310            else
311            {
312                    if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,this->ulThreadKillerId)) == NULL)
313                    {
314                            syslog << logfile::log_head << "Get thread handle error in DisableKillDeadThread()" << endl;
315                            this->uLastErrorCode = E_INVALID_THREAD;
316                            return E_INVALID_THREAD;
317                    }
318                    if (this->SetLock(true) == 0)
319                    {
320                            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                    }
330                    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            }
336    
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    }


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

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