--- innwebd/thread_pool.cpp 2004/07/03 13:55:42 1.3 +++ innwebd/thread_pool.cpp 2008/04/11 17:14:49 1.10 @@ -1,14 +1,10 @@ /*******************************************************/ /* */ -/* LeafOK Innd */ -/* Copyright (C) LeafOK.com, 2003-2004 */ +/* LeafOK Innbbsd */ /* */ -/* Programmed by Leaf */ -/* E-mail:leaf@leafok.com QQ:6049044 */ +/* Copyright (C) LeafOK.com, 2003-2008 */ /* */ -/* http://bbs.leafok.com */ -/* http://bbs.leafok.net */ -/* http://bbs.fenglin.info */ +/* http://www.leafok.com */ /* */ /*******************************************************/ @@ -22,7 +18,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 +28,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 +41,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 +60,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 +116,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 ulThreadId, int uStatus) { - UINTT i; - - if (this->SetLock(true) != 0) - { - return this->uLastErrorCode; - } + UINT i; 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 +186,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,47 +201,61 @@ DWORD thread_pool::KillDeadThread(LPVOID { thread_pool *p; UINT i; - bool bKillStatus = true; + HANDLE hThread; + ULONG ulThreadId; + int t_count = 0; 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; - } + p->ulThreadKillerId = GetCurrentThreadId(); - for (i=0; i < p->uThreadMax; i++) + while(!p->bTerminateThreadKiller) { - if ((p->uThreadStatusList[i] == S_WORKING) && - (clock() - p->time_status_set[i] > p->thread_timeout[i])) + if (t_count>=100) { - if (TerminateThread(p->hThreadList[i],-1)) - { - bKillStatus &= true; - syslog << logfile::log_head << "Terminate dead thread ... OK" << endl; - } - else + t_count=0; + + for (i=0; i < p->uThreadMax; i++) { - bKillStatus &= false; - syslog << logfile::log_head << "Terminate dead thread ... Failed" << endl; + if ((p->ulThreadIdList[i] != 0) && + (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 (" << ulThreadId << ") ... 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(hThread,-1)) + { + syslog << logfile::log_head << "Terminate dead thread (" << ulThreadId << ") ... OK" << endl; + } + else + { + syslog << logfile::log_head << "Terminate dead thread (" << ulThreadId << ") ... Failed" << endl; + } + CloseHandle(hThread); + } + } } - p->hThreadList[i] = NULL; - p->uThreadStatusList[i] = S_UNUSED; - p->time_status_set[i] = clock(); - p->uThreadCount--; } + + Sleep(100); + t_count++; } - p->SetLock(false); - p->uLastErrorCode = (bKillStatus?E_NOERROR:E_KILL_THREAD_FAILED); - return (bKillStatus?E_NOERROR:E_KILL_THREAD_FAILED); + p->bTerminateThreadKiller = false; + p->ulThreadKillerId = 0; + + return (E_NOERROR); } int thread_pool::GetThreadCount(void) const @@ -267,34 +267,109 @@ int thread_pool::EnableKillDeadThread(vo { HANDLE hThreadCurrent; ULONG ulThreadId; + + this->bTerminateThreadKiller = false; if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_pool::KillDeadThread,(LPVOID)this,0,&ulThreadId)) { - this->hThreadKiller = hThreadCurrent; + CloseHandle(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) { - if (this->hThreadKiller) + HANDLE hThread; + + if (this->ulThreadKillerId == 0) + { + this->uLastErrorCode = E_KILLER_END_FAILED; + return E_KILLER_END_FAILED; + } + + this->bTerminateThreadKiller = true; + + Sleep(1000); + + if (!this->bTerminateThreadKiller) + { + syslog << logfile::log_head << "Terminate killer thread ... OK" << endl; + } + 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 (" << ulThreadId << ") ... OK" << endl; + } + else + { + syslog << logfile::log_head << "Terminate all thread (" << ulThreadId << ") ... Failed" << endl; + } + CloseHandle(hThread); + } + } + } + + this->uLastErrorCode = E_NOERROR; + return E_NOERROR; }