version 1.4.4.3, 2007/06/11 08:16:12
|
version 1.5, 2007/01/11 16:21:54
|
|
|
// Set the dying flag so all thread know the destructor has been | // Set the dying flag so all thread know the destructor has been |
// entered | // entered |
_dying++; | _dying++; |
PEG_TRACE((TRC_THREAD, Tracer::LEVEL2, |
Tracer::trace(TRC_THREAD, Tracer::LEVEL2, |
"Cleaning up %d idle threads.", _currentThreads.get())); |
"Cleaning up %d idle threads.", _currentThreads.get()); |
| |
while (_currentThreads.get() > 0) | while (_currentThreads.get() > 0) |
{ | { |
|
|
} | } |
catch (...) | catch (...) |
{ | { |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"ThreadPool::_loop: Failure getting sleep_sem or " | "ThreadPool::_loop: Failure getting sleep_sem or " |
"lastActivityTime."); | "lastActivityTime."); |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
|
|
} | } |
catch (...) | catch (...) |
{ | { |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"ThreadPool::_loop: failure on sleep_sem->wait()."); | "ThreadPool::_loop: failure on sleep_sem->wait()."); |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
pool->_idleThreads.remove(myself); | pool->_idleThreads.remove(myself); |
|
|
} | } |
catch (...) | catch (...) |
{ | { |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"ThreadPool::_loop: Failure accessing work func, work " | "ThreadPool::_loop: Failure accessing work func, work " |
"parm, or blocking sem."); | "parm, or blocking sem."); |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
|
|
| |
if (work == 0) | if (work == 0) |
{ | { |
PEG_TRACE_CSTRING(TRC_THREAD, Tracer::LEVEL4, |
Tracer::trace(TRC_THREAD, Tracer::LEVEL4, |
"ThreadPool::_loop: work func is 0, meaning we should " | "ThreadPool::_loop: work func is 0, meaning we should " |
"exit."); | "exit."); |
break; | break; |
|
|
| |
try | try |
{ | { |
PEG_TRACE_CSTRING(TRC_THREAD, Tracer::LEVEL4, |
PEG_TRACE_STRING(TRC_THREAD, Tracer::LEVEL4, |
"Work starting."); | "Work starting."); |
work(parm); | work(parm); |
PEG_TRACE_CSTRING(TRC_THREAD, Tracer::LEVEL4, |
PEG_TRACE_STRING(TRC_THREAD, Tracer::LEVEL4, |
"Work finished."); | "Work finished."); |
} | } |
catch (Exception& e) | catch (Exception& e) |
|
|
#endif | #endif |
catch (...) | catch (...) |
{ | { |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"Unknown exception from work in ThreadPool::_loop."); | "Unknown exception from work in ThreadPool::_loop."); |
} | } |
| |
|
|
} | } |
catch (...) | catch (...) |
{ | { |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"ThreadPool::_loop: Adding thread to idle pool failed."); | "ThreadPool::_loop: Adding thread to idle pool failed."); |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
pool->_currentThreads--; | pool->_currentThreads--; |
|
|
} | } |
catch (...) | catch (...) |
{ | { |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"Caught unrecognized exception. Exiting _loop."); | "Caught unrecognized exception. Exiting _loop."); |
} | } |
| |
|
|
{ | { |
if (_dying.get()) | if (_dying.get()) |
{ | { |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"ThreadPool::allocate_and_awaken: ThreadPool is dying(1)."); | "ThreadPool::allocate_and_awaken: ThreadPool is dying(1)."); |
return PEGASUS_THREAD_UNAVAILABLE; | return PEGASUS_THREAD_UNAVAILABLE; |
} | } |
|
|
| |
if (th == 0) | if (th == 0) |
{ | { |
PEG_TRACE((TRC_THREAD, Tracer::LEVEL2, |
Tracer::trace(TRC_THREAD, Tracer::LEVEL2, |
"ThreadPool::allocate_and_awaken: Insufficient resources: " | "ThreadPool::allocate_and_awaken: Insufficient resources: " |
" pool = %s, running threads = %d, idle threads = %d", | " pool = %s, running threads = %d, idle threads = %d", |
_key, _runningThreads.size(), _idleThreads.size())); |
_key, _runningThreads.size(), _idleThreads.size()); |
return PEGASUS_THREAD_INSUFFICIENT_RESOURCES; | return PEGASUS_THREAD_INSUFFICIENT_RESOURCES; |
} | } |
| |
// initialize the thread data with the work function and parameters | // initialize the thread data with the work function and parameters |
PEG_TRACE((TRC_THREAD, Tracer::LEVEL4, |
Tracer::trace(TRC_THREAD, Tracer::LEVEL4, |
"Initializing thread(%s)" |
"Initializing thread with work function and parameters: parm = %p", |
" with work function and parameters: parm = %p", |
parm); |
Threads::id(th->getThreadHandle().thid).buffer, |
|
parm)); |
|
| |
th->delete_tsd("work func"); | th->delete_tsd("work func"); |
th->put_tsd("work func", NULL, | th->put_tsd("work func", NULL, |
|
|
Semaphore *sleep_sem = (Semaphore *) th->reference_tsd("sleep sem"); | Semaphore *sleep_sem = (Semaphore *) th->reference_tsd("sleep sem"); |
PEGASUS_ASSERT(sleep_sem != 0); | PEGASUS_ASSERT(sleep_sem != 0); |
| |
PEG_TRACE_CSTRING(TRC_THREAD, Tracer::LEVEL4, "Signal thread to awaken"); |
Tracer::trace(TRC_THREAD, Tracer::LEVEL4, "Signal thread to awaken"); |
sleep_sem->signal(); | sleep_sem->signal(); |
th->dereference_tsd(); | th->dereference_tsd(); |
} | } |
catch (...) | catch (...) |
{ | { |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"ThreadPool::allocate_and_awaken: Operation Failed."); | "ThreadPool::allocate_and_awaken: Operation Failed."); |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
// ATTN: Error result has not yet been defined | // ATTN: Error result has not yet been defined |
|
|
| |
Uint32 numThreadsCleanedUp = 0; | Uint32 numThreadsCleanedUp = 0; |
| |
Uint32 numIdleThreads = _idleThreads.size(); |
size_t numIdleThreads = _idleThreads.size(); |
for (Uint32 i = 0; i < numIdleThreads; i++) |
for (size_t i = 0; i < numIdleThreads; i++) |
{ | { |
// Do not dip below the minimum thread count | // Do not dip below the minimum thread count |
if (_currentThreads.get() <= (Uint32) _minThreads) | if (_currentThreads.get() <= (Uint32) _minThreads) |
|
|
| |
if (th->run() != PEGASUS_THREAD_OK) | if (th->run() != PEGASUS_THREAD_OK) |
{ | { |
PEG_TRACE((TRC_THREAD, Tracer::LEVEL2, |
Tracer::trace(TRC_THREAD, Tracer::LEVEL2, |
"Could not create thread. Error code is %d.", errno)); |
"Could not create thread. Error code is %d.", errno); |
delete th; | delete th; |
return 0; | return 0; |
} | } |
_currentThreads++; | _currentThreads++; |
|
Threads::yield(); |
| |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return th; | return th; |
|
|
{ | { |
if (th == 0) | if (th == 0) |
{ | { |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"ThreadPool::_addToIdleThreadsQueue: Thread pointer is null."); | "ThreadPool::_addToIdleThreadsQueue: Thread pointer is null."); |
throw NullPointer(); | throw NullPointer(); |
} | } |
|
|
} | } |
catch (...) | catch (...) |
{ | { |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"ThreadPool::_addToIdleThreadsQueue: _idleThreads.insert_front " | "ThreadPool::_addToIdleThreadsQueue: _idleThreads.insert_front " |
"failed."); | "failed."); |
} | } |