--- innwebd/thread_pool.cpp 2004/07/03 15:10:23 1.4 +++ innwebd/thread_pool.cpp 2004/07/04 06:45:23 1.5 @@ -1,10 +1,10 @@ /*******************************************************/ /* */ -/* LeafOK Innd */ +/* LeafOK Innbbsd */ /* Copyright (C) LeafOK.com, 2003-2004 */ /* */ /* Programmed by Leaf */ -/* E-mail:leaf@leafok.com QQ:6049044 */ +/* E-mail:leaflet@leafok.com QQ:6049044 */ /* */ /* http://bbs.leafok.com */ /* http://bbs.leafok.net */ @@ -22,7 +22,7 @@ thread_pool::thread_pool(UINT uThreadMax this->uLastErrorCode = E_NOERROR; this->uThreadCount = 0; this->uThreadMax = uThreadMax; - this->hThreadKiller = NULL; + this->ulThreadKillerId = 0; if (this->uThreadMax > TS_MAX_THREAD) { @@ -32,7 +32,7 @@ thread_pool::thread_pool(UINT uThreadMax for (i=0; i < this->uThreadMax; i++) { - this->hThreadList[i] = NULL; + this->ulThreadIdList[i] = 0; this->uThreadStatusList[i] = S_UNUSED; this->time_status_set[i] = clock(); } @@ -45,20 +45,15 @@ thread_pool::thread_pool(UINT uThreadMax thread_pool::~thread_pool(void) { this->DisableKillDeadThread(); + this->KillAllThread(); } -int thread_pool::AddThread(HANDLE hThread, clock_t thread_timeout) +int thread_pool::AddThread(ULONG ulThreadId, clock_t thread_timeout) { UINT i; - if (this->SetLock(true) != 0) - { - return this->uLastErrorCode; - } - if (this->uThreadCount >= this->uThreadMax) { - this->SetLock(false); this->uLastErrorCode = E_MAX_THREAD_EXCEEDED; return E_MAX_THREAD_EXCEEDED; } @@ -69,24 +64,28 @@ int thread_pool::AddThread(HANDLE hThrea return E_INVALID_TIMEOUT; } - for (i=0; i < this->uThreadMax; i++) + if (this->SetLock(true) == 0) { - if (this->uThreadStatusList[i] == S_UNUSED) + for (i=0; i < this->uThreadMax; i++) { - 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; - return E_NOERROR; + if (this->uThreadStatusList[i] == S_UNUSED) + { + this->ulThreadIdList[i] = ulThreadId; + 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; + return E_NOERROR; + } } + this->SetLock(false); + this->uLastErrorCode = E_MAX_THREAD_EXCEEDED; + return E_MAX_THREAD_EXCEEDED; } - this->SetLock(false); - this->uLastErrorCode = E_MAX_THREAD_EXCEEDED; - return E_MAX_THREAD_EXCEEDED; + return E_LOCK_TIMEOUT; } int thread_pool::SetLock(bool bLock, clock_t tTimeout) @@ -121,74 +120,65 @@ int thread_pool::GetLastError(void) cons return this->uLastErrorCode; } -int thread_pool::RemoveThread(HANDLE hThread) +int thread_pool::RemoveThread(ULONG ulThreadId) { UINT i; - if (this->SetLock(true) != 0) - { - return this->uLastErrorCode; - } - if (this->uThreadCount <= 0) { - this->SetLock(false); this->uLastErrorCode = E_THREAD_NOT_FOUND; return E_THREAD_NOT_FOUND; } - for (i=0; i < this->uThreadMax; i++) + if (this->SetLock(true) == 0) { - if (this->hThreadList[i] == hThread) + for (i=0; i < this->uThreadMax; i++) { - this->hThreadList[i] = NULL; - this->uThreadCount--; - this->SetLock(false); - this->uLastErrorCode = E_NOERROR; - return this->uLastErrorCode; + if (this->ulThreadIdList[i] == ulThreadId) + { + this->ulThreadIdList[i] = 0; + this->uThreadStatusList[i] = S_UNUSED; + this->uThreadCount--; + this->SetLock(false); + this->uLastErrorCode = E_NOERROR; + return E_NOERROR; + } } + this->SetLock(false); + this->uLastErrorCode = E_THREAD_NOT_FOUND; + return E_THREAD_NOT_FOUND; } - this->SetLock(false); - this->uLastErrorCode = E_THREAD_NOT_FOUND; - return E_THREAD_NOT_FOUND; + return E_LOCK_TIMEOUT; } -int thread_pool::SetThreadStatus(HANDLE hThread, int uStatus) +int thread_pool::SetThreadStatus(ULONG ulThreadd, int uStatus) { UINTT i; - if (this->SetLock(true) != 0) - { - return this->uLastErrorCode; - } - if (this->uThreadCount <= 0) { - this->SetLock(false); this->uLastErrorCode = E_THREAD_NOT_FOUND; return E_THREAD_NOT_FOUND; } for (i=0; i < this->uThreadMax; i++) { - if (this->hThreadList[i] == hThread) + if (this->ulThreadIdList[i] == ulThreadId) { this->uThreadStatusList[i] = (thread_status)uStatus; this->time_status_set[i] = clock(); - this->SetLock(false); this->uLastErrorCode = E_NOERROR; return this->uLastErrorCode; } } - this->SetLock(false); this->uLastErrorCode = E_THREAD_NOT_FOUND; return E_THREAD_NOT_FOUND; } -int thread_pool::GetThreadStatus(HANDLE hThread) +int thread_pool::GetThreadStatus(ULONG ulThreadId) { UINT i; @@ -200,7 +190,7 @@ int thread_pool::GetThreadStatus(HANDLE for (i=0; i < this->uThreadMax; i++) { - if (this->hThreadList[i] == hThread) + if (this->ulThreadIdList[i] == ulThreadId) { this->uLastErrorCode = E_NOERROR; return this->uThreadStatusList[i]; @@ -215,25 +205,40 @@ DWORD thread_pool::KillDeadThread(LPVOID { thread_pool *p; UINT i; + HANDLE hThread; + ULONG ulThreadId; int t_count = 0; p = (thread_pool*)pParam; + p->ulThreadKillerId = GetCurrentThreadId(); + while(!p->bTerminateThreadKiller) { if (t_count>=100) { t_count=0; - if (p->SetLock(true) == 0) + for (i=0; i < p->uThreadMax; i++) { - for (i=0; i < p->uThreadMax; i++) + if ((p->ulThreadIdList[i] != 0) && + (p->uThreadStatusList[i] == S_WORKING) && + (clock() - p->time_status_set[i] > p->thread_timeout[i])) { - if ((p->hThreadList[i] != NULL) && - (p->uThreadStatusList[i] == S_WORKING) && - (clock() - p->time_status_set[i] > p->thread_timeout[i])) + ulThreadId = p->ulThreadIdList[i]; + // Remove dead thread from thread pool + if (p->RemoveThread(ulThreadId) != 0) + { + syslog << logfile::log_head << "Unregister thread ... Failed" << endl; + } + // Kill dead thread + if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,ulThreadId)) == NULL) + { + syslog << logfile::log_head << "Get thread handle error in KillDeadThread()" << endl; + } + else { - if (TerminateThread(p->hThreadList[i],-1)) + if (TerminateThread(hThread,-1)) { syslog << logfile::log_head << "Terminate dead thread ... OK" << endl; } @@ -241,21 +246,19 @@ DWORD thread_pool::KillDeadThread(LPVOID { 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--; + CloseHandle(hThread); } } } - - p->SetLock(false); } Sleep(100); t_count++; } + p->bTerminateThreadKiller = false; + p->ulThreadKillerId = 0; + return (E_NOERROR); } @@ -272,41 +275,104 @@ int thread_pool::EnableKillDeadThread(vo this->bTerminateThreadKiller = false; 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; + this->uLastErrorCode = E_KILLER_BEGIN_FAILED; + return E_KILLER_BEGIN_FAILED; } - return 0; + this->uLastErrorCode = E_NOERROR; + return E_NOERROR; } int thread_pool::DisableKillDeadThread(void) { - bTerminateThreadKiller = true; + HANDLE hThread; + + if (this->ulThreadKillerId == 0) + { + this->uLastErrorCode = E_KILLER_END_FAILED; + return E_KILLER_END_FAILED; + } + + this->bTerminateThreadKiller = true; Sleep(1000); - if (!bTerminateThreadKiller) + if (!this->bTerminateThreadKiller) { syslog << logfile::log_head << "Terminate killer thread ... OK" << endl; } - - if (bTerminateThreadKiller && this->hThreadKiller) + else { - if (TerminateThread(this->hThreadKiller,0)) + if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,this->ulThreadKillerId)) == NULL) { - this->hThreadKiller = NULL; - syslog << logfile::log_head << "Terminate killer thread ... OK" << endl; + syslog << logfile::log_head << "Get thread handle error in DisableKillDeadThread()" << endl; + this->uLastErrorCode = E_INVALID_THREAD; + return E_INVALID_THREAD; } - else + if (this->SetLock(true) == 0) { - syslog << logfile::log_head << "Terminate killer thread ... Failed" << endl; - return -1; + if (TerminateThread(hThread,0)) + { + CloseHandle(hThread); + this->ulThreadKillerId = 0; + this->SetLock(false); + syslog << logfile::log_head << "Terminate killer thread ... OK" << endl; + this->uLastErrorCode = E_NOERROR; + return E_NOERROR; + } } + CloseHandle(hThread); + this->SetLock(false); + syslog << logfile::log_head << "Terminate killer thread ... Failed" << endl; + this->uLastErrorCode = E_KILLER_END_FAILED; + return E_KILLER_END_FAILED; } - return 0; + + this->uLastErrorCode = E_NOERROR; + return E_NOERROR; +} + +int thread_pool::KillAllThread(void) +{ + UINT i; + ULONG ulThreadId; + HANDLE hThread; + + for (i=0; i < this->uThreadMax; i++) + { + if ((this->ulThreadIdList[i] != 0)) + { + ulThreadId = this->ulThreadIdList[i]; + // Remove dead thread from thread pool + if (this->RemoveThread(ulThreadId) != 0) + { + syslog << logfile::log_head << "Unregister thread ... Failed" << endl; + } + // Kill dead thread + if ((hThread = OpenThread(THREAD_TERMINATE,FALSE,ulThreadId)) == NULL) + { + syslog << logfile::log_head << "Get thread handle error in KillAllThread()" << endl; + } + else + { + if (TerminateThread(hThread,-1)) + { + syslog << logfile::log_head << "Terminate all thread ... OK" << endl; + } + else + { + syslog << logfile::log_head << "Terminate all thread ... Failed" << endl; + } + CloseHandle(hThread); + } + } + } + + this->uLastErrorCode = E_NOERROR; + return E_NOERROR; }