--- innwebd/thread_pool.cpp 2004/07/03 08:38:54 1.1 +++ innwebd/thread_pool.cpp 2004/07/03 13:55:42 1.3 @@ -15,35 +15,43 @@ #include "StdAfx.h" #include ".\thread_pool.h" -thread_pool::thread_pool(UINT uThreadMax, double thread_timeout) +thread_pool::thread_pool(UINT uThreadMax) { UINT i; this->uLastErrorCode = E_NOERROR; this->uThreadCount = 0; this->uThreadMax = uThreadMax; - this->thread_timeout = thread_timeout; + this->hThreadKiller = NULL; + + if (this->uThreadMax > TS_MAX_THREAD) + { + this->uThreadMax = 0; + this->uLastErrorCode = E_MAX_THREAD_EXCEEDED; + } for (i=0; i < this->uThreadMax; i++) { this->hThreadList[i] = NULL; this->uThreadStatusList[i] = S_UNUSED; - this->time_status_keep[i] = 0; + this->time_status_set[i] = clock(); } this->SetLock(false); + + this->EnableKillDeadThread(); } thread_pool::~thread_pool(void) { - + this->DisableKillDeadThread(); } -int thread_pool::AddThread(HANDLE hThread) +int thread_pool::AddThread(HANDLE hThread, clock_t thread_timeout) { UINT i; - if (this->SetLock(true) == 0) + if (this->SetLock(true) != 0) { return this->uLastErrorCode; } @@ -55,11 +63,20 @@ int thread_pool::AddThread(HANDLE hThrea return E_MAX_THREAD_EXCEEDED; } + if (thread_timeout < 0) + { + this->uLastErrorCode = E_INVALID_TIMEOUT; + return E_INVALID_TIMEOUT; + } + for (i=0; i < this->uThreadMax; i++) { if (this->uThreadStatusList[i] == S_UNUSED) { this->hThreadList[i] = hThread; + this->uThreadStatusList[i] = S_WAITING; + this->thread_timeout[i] = thread_timeout; + this->time_status_set[i] = clock(); this->uThreadCount++; this->SetLock(false); this->uLastErrorCode = E_NOERROR; @@ -72,9 +89,9 @@ int thread_pool::AddThread(HANDLE hThrea return E_MAX_THREAD_EXCEEDED; } -int thread_pool::SetLock(bool bLock, time_t tTimeout) +int thread_pool::SetLock(bool bLock, clock_t tTimeout) { - time_t wait = 0; + clock_t wait = 0; if (!bLock) // Free lock { @@ -99,7 +116,7 @@ int thread_pool::SetLock(bool bLock, tim return E_NOERROR; } -UINT thread_pool::GetLastError(void) +int thread_pool::GetLastError(void) const { return this->uLastErrorCode; } @@ -108,7 +125,7 @@ int thread_pool::RemoveThread(HANDLE hTh { UINT i; - if (this->SetLock(true) == 0) + if (this->SetLock(true) != 0) { return this->uLastErrorCode; } @@ -138,11 +155,11 @@ int thread_pool::RemoveThread(HANDLE hTh } -int thread_pool::SetThreadStatus(HANDLE hThread, UINT uStatus) +int thread_pool::SetThreadStatus(HANDLE hThread, int uStatus) { UINTT i; - if (this->SetLock(true) == 0) + if (this->SetLock(true) != 0) { return this->uLastErrorCode; } @@ -159,6 +176,7 @@ int thread_pool::SetThreadStatus(HANDLE if (this->hThreadList[i] == hThread) { this->uThreadStatusList[i] = (thread_status)uStatus; + this->time_status_set[i] = clock(); this->SetLock(false); this->uLastErrorCode = E_NOERROR; return this->uLastErrorCode; @@ -170,7 +188,7 @@ int thread_pool::SetThreadStatus(HANDLE return E_THREAD_NOT_FOUND; } -UINT thread_pool::GetThreadStatus(HANDLE hThread) +int thread_pool::GetThreadStatus(HANDLE hThread) { UINT i; @@ -192,3 +210,91 @@ UINT thread_pool::GetThreadStatus(HANDLE this->uLastErrorCode = E_THREAD_NOT_FOUND; return S_UNKNOWN; } + +DWORD thread_pool::KillDeadThread(LPVOID pParam) +{ + thread_pool *p; + UINT i; + bool bKillStatus = true; + + p = (thread_pool*)pParam; + + if (p->SetLock(true) != 0) + { + return p->uLastErrorCode; + } + + if (p->uThreadCount <= 0) + { + p->SetLock(false); + p->uLastErrorCode = E_THREAD_NOT_FOUND; + return E_THREAD_NOT_FOUND; + } + + for (i=0; i < p->uThreadMax; i++) + { + if ((p->uThreadStatusList[i] == S_WORKING) && + (clock() - p->time_status_set[i] > p->thread_timeout[i])) + { + if (TerminateThread(p->hThreadList[i],-1)) + { + bKillStatus &= true; + syslog << logfile::log_head << "Terminate dead thread ... OK" << endl; + } + else + { + bKillStatus &= false; + syslog << logfile::log_head << "Terminate dead thread ... Failed" << endl; + } + p->hThreadList[i] = NULL; + p->uThreadStatusList[i] = S_UNUSED; + p->time_status_set[i] = clock(); + p->uThreadCount--; + } + } + + p->SetLock(false); + p->uLastErrorCode = (bKillStatus?E_NOERROR:E_KILL_THREAD_FAILED); + return (bKillStatus?E_NOERROR:E_KILL_THREAD_FAILED); +} + +int thread_pool::GetThreadCount(void) const +{ + return this->uThreadCount; +} + +int thread_pool::EnableKillDeadThread(void) +{ + HANDLE hThreadCurrent; + ULONG ulThreadId; + if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_pool::KillDeadThread,(LPVOID)this,0,&ulThreadId)) + { + this->hThreadKiller = hThreadCurrent; + syslog << logfile::log_head << "Create killer thread ... OK" << endl; + } + else + { + syslog << logfile::log_head << "Create killer thread ... Failed" << endl; + return -1; + } + + return 0; +} + +int thread_pool::DisableKillDeadThread(void) +{ + if (this->hThreadKiller) + { + if (TerminateThread(this->hThreadKiller,0)) + { + this->hThreadKiller = NULL; + syslog << logfile::log_head << "Terminate killer thread ... OK" << endl; + } + else + { + syslog << logfile::log_head << "Terminate killer thread ... Failed" << endl; + return -1; + } + } + return 0; +}