version 1.86.8.2, 2005/10/21 17:34:38
|
version 1.90, 2006/07/11 18:39:28
|
|
|
//%2005//////////////////////////////////////////////////////////////////////// |
//%2006//////////////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development | // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. | // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
|
|
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. | // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; | // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
// EMC Corporation; VERITAS Software Corporation; The Open Group. | // EMC Corporation; VERITAS Software Corporation; The Open Group. |
|
// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
|
// EMC Corporation; Symantec Corporation; The Open Group. |
// | // |
// Permission is hereby granted, free of charge, to any person obtaining a copy | // Permission is hereby granted, free of charge, to any person obtaining a copy |
// of this software and associated documentation files (the "Software"), to | // of this software and associated documentation files (the "Software"), to |
|
|
{ | { |
if( data != NULL) | if( data != NULL) |
{ | { |
AutoPtr<AcceptLanguages> al(static_cast<AcceptLanguages *>(data)); |
AutoPtr<AcceptLanguageList> al(static_cast<AcceptLanguageList *>(data)); |
} | } |
} | } |
// l10n end | // l10n end |
|
|
void Thread::cleanup_push( void (*routine)(void *), void *parm) | void Thread::cleanup_push( void (*routine)(void *), void *parm) |
{ | { |
AutoPtr<cleanup_handler> cu(new cleanup_handler(routine, parm)); | AutoPtr<cleanup_handler> cu(new cleanup_handler(routine, parm)); |
_cleanup.insert_first(cu.get()); |
_cleanup.insert_front(cu.get()); |
cu.release(); | cu.release(); |
return; | return; |
} | } |
|
|
AutoPtr<cleanup_handler> cu; | AutoPtr<cleanup_handler> cu; |
try | try |
{ | { |
cu.reset(_cleanup.remove_first()); |
cu.reset(_cleanup.remove_front()); |
} | } |
catch(IPCException&) | catch(IPCException&) |
{ | { |
|
|
void Thread::exit_self(PEGASUS_THREAD_RETURN exit_code) | void Thread::exit_self(PEGASUS_THREAD_RETURN exit_code) |
{ | { |
// execute the cleanup stack and then return | // execute the cleanup stack and then return |
while( _cleanup.count() ) |
while( _cleanup.size() ) |
{ | { |
try | try |
{ | { |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
| |
AcceptLanguages * Thread::getLanguages() |
AcceptLanguageList * Thread::getLanguages() |
{ | { |
PEG_METHOD_ENTER(TRC_THREAD, "Thread::getLanguages"); | PEG_METHOD_ENTER(TRC_THREAD, "Thread::getLanguages"); |
| |
Thread * curThrd = Thread::getCurrent(); | Thread * curThrd = Thread::getCurrent(); |
if (curThrd == NULL) | if (curThrd == NULL) |
return NULL; | return NULL; |
AcceptLanguages * acceptLangs = |
AcceptLanguageList * acceptLangs = |
(AcceptLanguages *)curThrd->reference_tsd("acceptLanguages"); |
(AcceptLanguageList *)curThrd->reference_tsd("acceptLanguages"); |
curThrd->dereference_tsd(); | curThrd->dereference_tsd(); |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return acceptLangs; | return acceptLangs; |
} | } |
| |
void Thread::setLanguages(AcceptLanguages *langs) //l10n |
void Thread::setLanguages(AcceptLanguageList *langs) //l10n |
{ | { |
PEG_METHOD_ENTER(TRC_THREAD, "Thread::setLanguages"); | PEG_METHOD_ENTER(TRC_THREAD, "Thread::setLanguages"); |
| |
|
|
// deletes the old tsd and creates a new one | // deletes the old tsd and creates a new one |
currentThrd->put_tsd("acceptLanguages", | currentThrd->put_tsd("acceptLanguages", |
language_delete, | language_delete, |
sizeof(AcceptLanguages *), |
sizeof(AcceptLanguageList *), |
langs); | langs); |
} | } |
| |
|
|
: _maxThreads(maxThreads), | : _maxThreads(maxThreads), |
_minThreads(minThreads), | _minThreads(minThreads), |
_currentThreads(0), | _currentThreads(0), |
_idleThreads(true), |
_idleThreads(), |
_runningThreads(true), |
_runningThreads(), |
_dying(0) | _dying(0) |
{ | { |
_deallocateWait.tv_sec = deallocateWait.tv_sec; | _deallocateWait.tv_sec = deallocateWait.tv_sec; |
|
|
"Cleaning up %d idle threads. ", _currentThreads.get()); | "Cleaning up %d idle threads. ", _currentThreads.get()); |
while (_currentThreads.get() > 0) | while (_currentThreads.get() > 0) |
{ | { |
Thread* thread = _idleThreads.remove_first(); |
Thread* thread = _idleThreads.remove_front(); |
if (thread != 0) | if (thread != 0) |
{ | { |
_cleanupThread(thread); | _cleanupThread(thread); |
|
|
blocking_sem->signal(); | blocking_sem->signal(); |
} | } |
| |
Boolean removed = pool->_runningThreads.remove((void *)myself); |
pool->_runningThreads.remove(myself); |
PEGASUS_ASSERT(removed); |
pool->_idleThreads.insert_front(myself); |
|
|
pool->_idleThreads.insert_first(myself); |
|
} | } |
catch (...) | catch (...) |
{ | { |
|
|
gettimeofday(&start, NULL); | gettimeofday(&start, NULL); |
Thread* th = 0; | Thread* th = 0; |
| |
th = _idleThreads.remove_first(); |
th = _idleThreads.remove_front(); |
| |
if (th == 0) | if (th == 0) |
{ | { |
|
|
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, | Tracer::trace(TRC_DISCARDED_DATA, 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.count(), _idleThreads.count()); |
_key, _runningThreads.size(), _idleThreads.size()); |
return PEGASUS_THREAD_INSUFFICIENT_RESOURCES; | return PEGASUS_THREAD_INSUFFICIENT_RESOURCES; |
} | } |
| |
|
|
th->put_tsd("blocking sem", NULL, sizeof(Semaphore *), blocking); | th->put_tsd("blocking sem", NULL, sizeof(Semaphore *), blocking); |
| |
// put the thread on the running list | // put the thread on the running list |
_runningThreads.insert_first(th); |
_runningThreads.insert_front(th); |
| |
// signal the thread's sleep semaphore to awaken it | // signal the thread's sleep semaphore to awaken it |
Semaphore* sleep_sem = (Semaphore *)th->reference_tsd("sleep sem"); | Semaphore* sleep_sem = (Semaphore *)th->reference_tsd("sleep sem"); |
|
|
| |
Uint32 numThreadsCleanedUp = 0; | Uint32 numThreadsCleanedUp = 0; |
| |
Uint32 numIdleThreads = _idleThreads.count(); |
Uint32 numIdleThreads = _idleThreads.size(); |
for (Uint32 i = 0; i < numIdleThreads; i++) | for (Uint32 i = 0; i < numIdleThreads; i++) |
{ | { |
// Do not dip below the minimum thread count | // Do not dip below the minimum thread count |
|
|
break; | break; |
} | } |
| |
Thread* thread = _idleThreads.remove_last(); |
Thread* thread = _idleThreads.remove_back(); |
| |
// If there are no more threads in the _idleThreads queue, we're done. | // If there are no more threads in the _idleThreads queue, we're done. |
if (thread == 0) | if (thread == 0) |
|
|
catch (...) | catch (...) |
{ | { |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
_idleThreads.insert_last(thread); |
_idleThreads.insert_back(thread); |
break; | break; |
} | } |
| |
|
|
} | } |
else | else |
{ | { |
_idleThreads.insert_first(thread); |
_idleThreads.insert_front(thread); |
} | } |
} | } |
| |
|
|
| |
try | try |
{ | { |
_idleThreads.insert_first(th); |
_idleThreads.insert_front(th); |
} | } |
catch (...) | catch (...) |
{ | { |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, | Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"ThreadPool::_addToIdleThreadsQueue: _idleThreads.insert_first " |
"ThreadPool::_addToIdleThreadsQueue: _idleThreads.insert_front " |
"failed."); | "failed."); |
} | } |
} | } |