version 1.69, 2004/07/29 07:29:47
|
version 1.70, 2004/08/06 19:24:45
|
|
|
// is needed. | // is needed. |
sleep_sem->signal(); | sleep_sem->signal(); |
th->dereference_tsd(); | th->dereference_tsd(); |
th->cancel(); |
|
th->join(); | th->join(); |
delete th; | delete th; |
} | } |
|
|
sleep_sem->signal(); | sleep_sem->signal(); |
sleep_sem->signal(); | sleep_sem->signal(); |
th->dereference_tsd(); | th->dereference_tsd(); |
th->cancel(); |
|
th->join(); | th->join(); |
delete th; | delete th; |
} | } |
|
|
sleep_sem->signal(); | sleep_sem->signal(); |
sleep_sem->signal(); | sleep_sem->signal(); |
th->dereference_tsd(); | th->dereference_tsd(); |
th->cancel(); |
//th->cancel(); |
pegasus_yield(); | pegasus_yield(); |
| |
th->join(); | th->join(); |
|
|
return 0; | return 0; |
} | } |
| |
DQueue<Thread> * map[2] = |
|
{ |
|
&_pool, &_running |
|
}; |
|
|
|
|
|
DQueue<Thread> *q = 0; |
|
int i = 0; |
|
Thread *th = 0; | Thread *th = 0; |
internal_dq idq; | internal_dq idq; |
| |
#ifdef PEGASUS_KILL_LONG_RUNNING_THREADS |
if(_pool.count() > 0 ) |
// Defining PEGASUS_KILL_LONG_RUNNING_THREADS causes the thread pool |
|
// to kill threads that are on the _running queue longer than the |
|
// _deadlock_detect time interval specified for the thread pool. |
|
// Cancelling long-running threads has proven to be problematic and |
|
// may cause a crash depending on the state of the thread when it is |
|
// killed. Use this option with care. |
|
for( ; i < 2; i++) |
|
#else |
|
for( ; i < 1; i++) |
|
#endif |
|
{ |
|
q = map[i]; |
|
if(q->count() > 0 ) |
|
{ | { |
try | try |
{ | { |
q->try_lock(); |
_pool.try_lock(); |
} | } |
catch(...) | catch(...) |
{ | { |
|
|
struct timeval dt = { 0, 0 }; | struct timeval dt = { 0, 0 }; |
struct timeval *dtp; | struct timeval *dtp; |
| |
th = q->next(th); |
th = _pool.next(th); |
while (th != 0 ) | while (th != 0 ) |
{ | { |
try | try |
|
|
} | } |
catch(...) | catch(...) |
{ | { |
q->unlock(); |
_pool.unlock(); |
return bodies; | return bodies; |
} | } |
| |
|
|
th->dereference_tsd(); | th->dereference_tsd(); |
struct timeval deadlock_timeout; | struct timeval deadlock_timeout; |
Boolean too_long; | Boolean too_long; |
if( i == 0) |
|
{ |
|
too_long = check_time(&dt, get_deallocate_wait(&deadlock_timeout)); | too_long = check_time(&dt, get_deallocate_wait(&deadlock_timeout)); |
} |
|
else |
|
{ |
|
too_long = check_time(&dt, get_deadlock_detect(&deadlock_timeout)); |
|
} |
|
| |
if( true == too_long) | if( true == too_long) |
{ | { |
// if we are deallocating from the pool, escape if we are |
// escape if we are down to the minimum thread count |
// down to the minimum thread count |
|
_current_threads--; | _current_threads--; |
if( _current_threads.value() < (Uint32)_min_threads ) | if( _current_threads.value() < (Uint32)_min_threads ) |
{ | { |
if( i == 0) |
|
{ |
|
_current_threads++; | _current_threads++; |
th = q->next(th); |
th = _pool.next(th); |
continue; | continue; |
} | } |
else |
|
{ |
|
// we are killing a hung thread and we will drop below the |
|
// minimum. create another thread to make up for the one |
|
// we are about to kill |
|
needed++; |
|
} |
|
} |
|
| |
th = q->remove_no_lock((void *)th); |
th = _pool.remove_no_lock((void *)th); |
idq.insert_first((void*)th); | idq.insert_first((void*)th); |
} | } |
th = q->next(th); |
th = _pool.next(th); |
} | } |
q->unlock(); |
_pool.unlock(); |
} | } |
| |
th = (Thread*)idq.remove_last(); | th = (Thread*)idq.remove_last(); |
while(th != 0) | while(th != 0) |
{ | { |
if( i == 0 ) |
|
{ |
|
th->delete_tsd("work func"); | th->delete_tsd("work func"); |
th->put_tsd("work func", NULL, | th->put_tsd("work func", NULL, |
sizeof( PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *)(void *)), | sizeof( PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *)(void *)), |
|
|
| |
bodies++; | bodies++; |
th->dereference_tsd(); | th->dereference_tsd(); |
// Putting thread on _dead queue delays availability to others |
|
//_dead.insert_first(th); |
|
sleep_sem->signal(); | sleep_sem->signal(); |
th->join(); // Note: Clean up the thread here rather than | th->join(); // Note: Clean up the thread here rather than |
delete th; // leave it sitting unused on the _dead queue | delete th; // leave it sitting unused on the _dead queue |
th = 0; |
|
} |
|
else |
|
{ |
|
// deadlocked threads |
|
Tracer::trace(TRC_THREAD, Tracer::LEVEL2, |
|
"A thread has run longer than %u seconds and " |
|
"will be cancelled.", |
|
Uint32(_deadlock_detect.tv_sec)); |
|
Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, |
|
Logger::SEVERE, |
|
"Common.Thread.CANCEL_LONG_RUNNING_THREAD", |
|
"A thread has run longer than {0} seconds and " |
|
"will be cancelled.", |
|
Uint32(_deadlock_detect.tv_sec)); |
|
th->cancel(); |
|
delete th; |
|
} |
|
th = (Thread*)idq.remove_last(); | th = (Thread*)idq.remove_last(); |
} | } |
} |
|
| |
Tracer::trace(TRC_THREAD, Tracer::LEVEL2, | Tracer::trace(TRC_THREAD, Tracer::LEVEL2, |
"We need %u new threads", needed.value()); | "We need %u new threads", needed.value()); |