version 1.16.2.1, 2008/08/20 23:05:50
|
version 1.22, 2008/12/01 17:49:57
|
|
|
//%2006//////////////////////////////////////////////////////////////////////// |
//%LICENSE//////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
// Licensed to The Open Group (TOG) under one or more contributor license |
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
// agreements. Refer to the OpenPegasusNOTICE.txt file distributed with |
// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; |
// this work for additional information regarding copyright ownership. |
// IBM Corp.; EMC Corporation, The Open Group. |
// Each contributor licenses this file to you under the OpenPegasus Open |
// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; |
// Source License; you may not use this file except in compliance with the |
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
// License. |
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
|
// 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 |
// of this software and associated documentation files (the "Software"), to |
// copy of this software and associated documentation files (the "Software"), |
// deal in the Software without restriction, including without limitation the |
// to deal in the Software without restriction, including without limitation |
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
// the rights to use, copy, modify, merge, publish, distribute, sublicense, |
// sell copies of the Software, and to permit persons to whom the Software is |
// and/or sell copies of the Software, and to permit persons to whom the |
// furnished to do so, subject to the following conditions: |
// Software is furnished to do so, subject to the following conditions: |
// | // |
// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN |
// The above copyright notice and this permission notice shall be included |
// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED |
// in all copies or substantial portions of the Software. |
// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT |
|
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
// | // |
//============================================================================== |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
|
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
|
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
// |
|
////////////////////////////////////////////////////////////////////////// |
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
|
|
| |
try | try |
{ | { |
sleep_sem = (Semaphore *) myself->reference_tsd("sleep sem"); |
sleep_sem = (Semaphore *) myself->reference_tsd(TSD_SLEEP_SEM); |
myself->dereference_tsd(); | myself->dereference_tsd(); |
PEGASUS_ASSERT(sleep_sem != 0); | PEGASUS_ASSERT(sleep_sem != 0); |
| |
lastActivityTime = | lastActivityTime = |
(struct timeval *) myself-> | (struct timeval *) myself-> |
reference_tsd("last activity time"); |
reference_tsd(TSD_LAST_ACTIVITY_TIME); |
myself->dereference_tsd(); | myself->dereference_tsd(); |
PEGASUS_ASSERT(lastActivityTime != 0); | PEGASUS_ASSERT(lastActivityTime != 0); |
} | } |
|
|
try | try |
{ | { |
work = (ThreadReturnType(PEGASUS_THREAD_CDECL *) (void *)) | work = (ThreadReturnType(PEGASUS_THREAD_CDECL *) (void *)) |
myself->reference_tsd("work func"); |
myself->reference_tsd(TSD_WORK_FUNC); |
myself->dereference_tsd(); | myself->dereference_tsd(); |
workParm = myself->reference_tsd("work parm"); |
workParm = myself->reference_tsd(TSD_WORK_PARM); |
myself->dereference_tsd(); | myself->dereference_tsd(); |
blocking_sem = | blocking_sem = |
(Semaphore *) myself->reference_tsd("blocking sem"); |
(Semaphore *) myself->reference_tsd(TSD_BLOCKING_SEM); |
myself->dereference_tsd(); | myself->dereference_tsd(); |
} | } |
catch (...) | catch (...) |
|
|
} | } |
catch (Exception& e) | catch (Exception& e) |
{ | { |
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1, |
String("Exception from work in ThreadPool::_loop: ") + |
"Exception from work in ThreadPool::_loop: %s", |
e.getMessage()); |
(const char*)e.getMessage().getCString())); |
} | } |
catch (const exception& e) | catch (const exception& e) |
{ | { |
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1, |
String("Exception from work in ThreadPool::_loop: ") + |
"Exception from work in ThreadPool::_loop: %s",e.what())); |
e.what()); |
|
} | } |
catch (...) | catch (...) |
{ | { |
|
|
} | } |
catch (const Exception & e) | catch (const Exception & e) |
{ | { |
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1, |
"Caught exception: \"" + e.getMessage() + "\". Exiting _loop."); |
"Caught exception: \"%s\". Exiting _loop.", |
|
(const char*)e.getMessage().getCString())); |
} | } |
catch (...) | catch (...) |
{ | { |
|
|
Threads::id(th->getThreadHandle().thid).buffer, | Threads::id(th->getThreadHandle().thid).buffer, |
parm)); | parm)); |
| |
th->delete_tsd("work func"); |
th->delete_tsd(TSD_WORK_FUNC); |
th->put_tsd("work func", NULL, |
th->put_tsd(TSD_WORK_FUNC, NULL, |
sizeof (ThreadReturnType(PEGASUS_THREAD_CDECL *) | sizeof (ThreadReturnType(PEGASUS_THREAD_CDECL *) |
(void *)), (void *) work); | (void *)), (void *) work); |
th->delete_tsd("work parm"); |
th->delete_tsd(TSD_WORK_PARM); |
th->put_tsd("work parm", NULL, sizeof (void *), parm); |
th->put_tsd(TSD_WORK_PARM, NULL, sizeof (void *), parm); |
th->delete_tsd("blocking sem"); |
th->delete_tsd(TSD_BLOCKING_SEM); |
if (blocking != 0) | if (blocking != 0) |
th->put_tsd("blocking sem", NULL, sizeof (Semaphore *), blocking); |
th->put_tsd(TSD_BLOCKING_SEM, NULL, sizeof (Semaphore *), blocking); |
| |
// put the thread on the running list | // put the thread on the running list |
_runningThreads.insert_front(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(TSD_SLEEP_SEM); |
PEGASUS_ASSERT(sleep_sem != 0); | PEGASUS_ASSERT(sleep_sem != 0); |
| |
PEG_TRACE_CSTRING(TRC_THREAD, Tracer::LEVEL4, | PEG_TRACE_CSTRING(TRC_THREAD, Tracer::LEVEL4, |
|
|
break; | break; |
} | } |
| |
struct timeval *lastActivityTime; |
void* tsd = thread->reference_tsd(TSD_LAST_ACTIVITY_TIME); |
if (!thread->try_reference_tsd( |
struct timeval *lastActivityTime = |
"last activity time", (void**)&lastActivityTime)) |
reinterpret_cast<struct timeval*>(tsd); |
{ |
|
PEGASUS_ASSERT(false); |
|
_idleThreads.insert_back(thread); |
|
break; |
|
} |
|
PEGASUS_ASSERT(lastActivityTime != 0); | PEGASUS_ASSERT(lastActivityTime != 0); |
| |
Boolean cleanupThisThread = | Boolean cleanupThisThread = |
|
|
{ | { |
PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::cleanupThread"); | PEG_METHOD_ENTER(TRC_THREAD, "ThreadPool::cleanupThread"); |
| |
// Set the "work func" and "work parm" to 0 so _loop() knows to exit. |
// Set the TSD_WORK_FUNC and TSD_WORK_PARM to 0 so _loop() knows to exit. |
thread->delete_tsd("work func"); |
thread->delete_tsd(TSD_WORK_FUNC); |
thread->put_tsd("work func", 0, |
thread->put_tsd(TSD_WORK_FUNC, 0, |
sizeof (ThreadReturnType(PEGASUS_THREAD_CDECL *) | sizeof (ThreadReturnType(PEGASUS_THREAD_CDECL *) |
(void *)), (void *) 0); | (void *)), (void *) 0); |
thread->delete_tsd("work parm"); |
thread->delete_tsd(TSD_WORK_PARM); |
thread->put_tsd("work parm", 0, sizeof (void *), 0); |
thread->put_tsd(TSD_WORK_PARM, 0, sizeof (void *), 0); |
| |
// signal the thread's sleep semaphore to awaken it | // signal the thread's sleep semaphore to awaken it |
Semaphore *sleep_sem = (Semaphore *) thread->reference_tsd("sleep sem"); |
Semaphore *sleep_sem = (Semaphore *) thread->reference_tsd(TSD_SLEEP_SEM); |
PEGASUS_ASSERT(sleep_sem != 0); | PEGASUS_ASSERT(sleep_sem != 0); |
sleep_sem->signal(); | sleep_sem->signal(); |
thread->dereference_tsd(); | thread->dereference_tsd(); |
|
|
Uint32 usec; | Uint32 usec; |
Time::gettimeofday(&now); | Time::gettimeofday(&now); |
| |
#if defined(PEGASUS_OS_SOLARIS) |
|
memset(&remaining, 0, sizeof(remaining)); | memset(&remaining, 0, sizeof(remaining)); |
#else |
|
Time::gettimeofday(&remaining); // Avoid valgrind error |
|
#endif |
|
| |
finish.tv_sec = start->tv_sec + interval->tv_sec; | finish.tv_sec = start->tv_sec + interval->tv_sec; |
usec = start->tv_usec + interval->tv_usec; | usec = start->tv_usec + interval->tv_usec; |
|
|
// we signal the semaphore | // we signal the semaphore |
Semaphore *sleep_sem = (Semaphore *) new Semaphore(0); | Semaphore *sleep_sem = (Semaphore *) new Semaphore(0); |
th->put_tsd( | th->put_tsd( |
"sleep sem", &_deleteSemaphore, sizeof(Semaphore), (void*) sleep_sem); |
TSD_SLEEP_SEM, &_deleteSemaphore, sizeof(Semaphore), (void*) sleep_sem); |
| |
struct timeval* lastActivityTime = | struct timeval* lastActivityTime = |
(struct timeval *)::operator new(sizeof (struct timeval)); | (struct timeval *)::operator new(sizeof (struct timeval)); |
Time::gettimeofday(lastActivityTime); | Time::gettimeofday(lastActivityTime); |
| |
th->put_tsd( | th->put_tsd( |
"last activity time", |
TSD_LAST_ACTIVITY_TIME, |
thread_data::default_delete, | thread_data::default_delete, |
sizeof(struct timeval), | sizeof(struct timeval), |
(void*) lastActivityTime); | (void*) lastActivityTime); |