/[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.3 by sysadm, Sat Jul 3 13:55:42 2004 UTC Revision 1.6 by sysadm, Sun Jul 4 22:49:03 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 22  thread_pool::thread_pool(UINT uThreadMax Line 22  thread_pool::thread_pool(UINT uThreadMax
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->hThreadKiller = NULL;          this->ulThreadKillerId = 0;
26    
27          if (this->uThreadMax > TS_MAX_THREAD)          if (this->uThreadMax > TS_MAX_THREAD)
28          {          {
# Line 32  thread_pool::thread_pool(UINT uThreadMax Line 32  thread_pool::thread_pool(UINT uThreadMax
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_set[i] = clock();                  this->time_status_set[i] = clock();
38          }          }
# Line 45  thread_pool::thread_pool(UINT uThreadMax Line 45  thread_pool::thread_pool(UINT uThreadMax
45  thread_pool::~thread_pool(void)  thread_pool::~thread_pool(void)
46  {  {
47          this->DisableKillDeadThread();          this->DisableKillDeadThread();
48            this->KillAllThread();
49  }  }
50    
51  int thread_pool::AddThread(HANDLE hThread, clock_t thread_timeout)  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          }          }
# Line 69  int thread_pool::AddThread(HANDLE hThrea Line 64  int thread_pool::AddThread(HANDLE hThrea
64                  return E_INVALID_TIMEOUT;                  return E_INVALID_TIMEOUT;
65          }          }
66    
67          for (i=0; i < this->uThreadMax; i++)          if (this->SetLock(true) == 0)
68          {          {
69                  if (this->uThreadStatusList[i] == S_UNUSED)                  for (i=0; i < this->uThreadMax; i++)
70                  {                  {
71                          this->hThreadList[i] = hThread;                          if (this->uThreadStatusList[i] == S_UNUSED)
72                          this->uThreadStatusList[i] = S_WAITING;                          {
73                          this->thread_timeout[i] = thread_timeout;                                  this->ulThreadIdList[i] = ulThreadId;
74                          this->time_status_set[i] = clock();                                  this->uThreadStatusList[i] = S_WAITING;
75                          this->uThreadCount++;                                  this->thread_timeout[i] = thread_timeout;
76                          this->SetLock(false);                                  this->time_status_set[i] = clock();
77                          this->uLastErrorCode = E_NOERROR;                                  this->uThreadCount++;
78                          return E_NOERROR;                                  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, clock_t tTimeout)  int thread_pool::SetLock(bool bLock, clock_t tTimeout)
# Line 121  int thread_pool::GetLastError(void) cons Line 120  int thread_pool::GetLastError(void) cons
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, int uStatus)  int thread_pool::SetThreadStatus(ULONG ulThreadd, int uStatus)
157  {  {
158          UINTT i;          UINTT i;
159    
         if (this->SetLock(true) != 0)  
         {  
                 return this->uLastErrorCode;  
         }  
   
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->time_status_set[i] = clock();                          this->time_status_set[i] = clock();
                         this->SetLock(false);  
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  int thread_pool::GetThreadStatus(HANDLE hThread)  int thread_pool::GetThreadStatus(ULONG ulThreadId)
182  {  {
183          UINT i;          UINT i;
184    
# Line 200  int thread_pool::GetThreadStatus(HANDLE Line 190  int 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 215  DWORD thread_pool::KillDeadThread(LPVOID Line 205  DWORD thread_pool::KillDeadThread(LPVOID
205  {  {
206          thread_pool *p;          thread_pool *p;
207      UINT i;      UINT i;
208      bool bKillStatus = true;          HANDLE hThread;
209            ULONG ulThreadId;
210            int t_count = 0;
211    
212          p = (thread_pool*)pParam;          p = (thread_pool*)pParam;
213    
214          if (p->SetLock(true) != 0)          p->ulThreadKillerId = GetCurrentThreadId();
         {  
                 return p->uLastErrorCode;  
         }  
   
         if (p->uThreadCount <= 0)  
         {  
                 p->SetLock(false);  
                 p->uLastErrorCode = E_THREAD_NOT_FOUND;  
                 return E_THREAD_NOT_FOUND;  
         }  
215    
216          for (i=0; i < p->uThreadMax; i++)          while(!p->bTerminateThreadKiller)
217          {          {
218                  if ((p->uThreadStatusList[i] == S_WORKING) &&                  if (t_count>=100)
                         (clock() - p->time_status_set[i] > p->thread_timeout[i]))  
219                  {                  {
220                          if (TerminateThread(p->hThreadList[i],-1))                          t_count=0;
221                          {  
222                                  bKillStatus &= true;                          for (i=0; i < p->uThreadMax; i++)
                                 syslog << logfile::log_head << "Terminate dead thread ... OK" << endl;  
                         }  
                         else  
223                          {                          {
224                                  bKillStatus &= false;                                  if ((p->ulThreadIdList[i] != 0) &&
225                                  syslog << logfile::log_head << "Terminate dead thread ... Failed" << endl;                                          (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                          }                          }
                         p->hThreadList[i] = NULL;  
                         p->uThreadStatusList[i] = S_UNUSED;  
                         p->time_status_set[i] = clock();  
                         p->uThreadCount--;  
253                  }                  }
254    
255                    Sleep(100);
256                    t_count++;
257          }          }
258    
259          p->SetLock(false);          p->bTerminateThreadKiller = false;
260          p->uLastErrorCode = (bKillStatus?E_NOERROR:E_KILL_THREAD_FAILED);          p->ulThreadKillerId = 0;
261          return (bKillStatus?E_NOERROR:E_KILL_THREAD_FAILED);  
262            return (E_NOERROR);
263  }  }
264    
265  int thread_pool::GetThreadCount(void) const  int thread_pool::GetThreadCount(void) const
# Line 267  int thread_pool::EnableKillDeadThread(vo Line 271  int thread_pool::EnableKillDeadThread(vo
271  {  {
272          HANDLE hThreadCurrent;          HANDLE hThreadCurrent;
273          ULONG ulThreadId;          ULONG ulThreadId;
274    
275            this->bTerminateThreadKiller = false;
276          if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_pool::KillDeadThread,(LPVOID)this,0,&ulThreadId))          if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_pool::KillDeadThread,(LPVOID)this,0,&ulThreadId))
277          {          {
278                  this->hThreadKiller = hThreadCurrent;                  CloseHandle(hThreadCurrent);
279                  syslog << logfile::log_head << "Create killer thread ... OK" << endl;                  syslog << logfile::log_head << "Create killer thread ... OK" << endl;
280          }          }
281          else          else
282          {          {
283                  syslog << logfile::log_head << "Create killer thread ... Failed" << endl;                  syslog << logfile::log_head << "Create killer thread ... Failed" << endl;
284                  return -1;                  this->uLastErrorCode = E_KILLER_BEGIN_FAILED;
285                    return E_KILLER_BEGIN_FAILED;
286          }          }
287    
288          return 0;          this->uLastErrorCode = E_NOERROR;
289            return E_NOERROR;
290  }  }
291    
292  int thread_pool::DisableKillDeadThread(void)  int thread_pool::DisableKillDeadThread(void)
293  {  {
294          if (this->hThreadKiller)          HANDLE hThread;
295    
296            if (this->ulThreadKillerId == 0)
297          {          {
298                  if (TerminateThread(this->hThreadKiller,0))                  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                          this->hThreadKiller = NULL;                          if (TerminateThread(hThread,0))
321                          syslog << logfile::log_head << "Terminate killer thread ... OK" << endl;                          {
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                  else                  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                          syslog << logfile::log_head << "Terminate killer thread ... Failed" << endl;                          ulThreadId = this->ulThreadIdList[i];
352                          return -1;                          // 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          return 0;  
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