version 1.47, 2005/03/10 02:06:42
|
version 1.48, 2005/04/01 17:26:52
|
|
|
| |
/////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////// |
| |
class PEGASUS_COMMON_LINKAGE ThreadPool; |
|
|
|
class PEGASUS_COMMON_LINKAGE Thread | class PEGASUS_COMMON_LINKAGE Thread |
{ | { |
| |
|
|
// get the user parameter | // get the user parameter |
inline void *get_parm(void) { return _thread_parm; } | inline void *get_parm(void) { return _thread_parm; } |
| |
// send the thread a signal -- may not be appropriate due to Windows |
|
// void kill(int signum); |
|
|
|
// cancellation must be deferred (not asynchronous) | // cancellation must be deferred (not asynchronous) |
// for user-level threads the thread itself can decide | // for user-level threads the thread itself can decide |
// when it should die. | // when it should die. |
|
|
| |
inline void empty_tsd(void) throw(IPCException) | inline void empty_tsd(void) throw(IPCException) |
{ | { |
|
|
try | try |
{ | { |
|
|
_tsd.try_lock(); | _tsd.try_lock(); |
} | } |
catch(IPCException&) | catch(IPCException&) |
|
|
static PEGASUS_THREAD_KEY_TYPE _platform_thread_key; //l10n | static PEGASUS_THREAD_KEY_TYPE _platform_thread_key; //l10n |
static Boolean _key_initialized; // l10n | static Boolean _key_initialized; // l10n |
static Boolean _key_error; // l10n | static Boolean _key_error; // l10n |
friend class ThreadPool; |
|
} ; | } ; |
| |
| |
|
|
{ | { |
public: | public: |
| |
ThreadPool(Sint16 initial_size, |
/** |
|
Constructs a new ThreadPool object. |
|
@param initialSize The number of threads that are initially added to |
|
the thread pool. |
|
@param key A name for this thread pool that can be used to determine |
|
equality of two thread pool objects. Only the first 16 characters |
|
of this value are used. |
|
@param minThreads The minimum number of threads that should be |
|
contained in this thread pool at any given time. |
|
@param maxThreads The maximum number of threads that should be |
|
contained in this thread pool at any given time. |
|
@param deallocateWait The minimum time that a thread should be idle |
|
before it is removed from the pool and cleaned up. |
|
*/ |
|
ThreadPool( |
|
Sint16 initialSize, |
const char *key, | const char *key, |
Sint16 min, |
Sint16 minThreads, |
Sint16 max, |
Sint16 maxThreads, |
struct timeval & alloc_wait, |
struct timeval& deallocateWait); |
struct timeval & dealloc_wait); |
|
| |
~ThreadPool(void); |
/** |
|
Destructs the ThreadPool object. |
|
*/ |
|
~ThreadPool(); |
| |
/** | /** |
Allocate and start a thread to do a unit of work. | Allocate and start a thread to do a unit of work. |
|
|
resources necessary to start the thread are not currently | resources necessary to start the thread are not currently |
available. ATTN: The result is undefined for any other | available. ATTN: The result is undefined for any other |
type of thread creation failure. | type of thread creation failure. |
|
@exception IPCException |
*/ | */ |
Boolean allocate_and_awaken(void *parm, |
Boolean allocate_and_awaken( |
|
void* parm, |
PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *work)(void *), | PEGASUS_THREAD_RETURN (PEGASUS_THREAD_CDECL *work)(void *), |
Semaphore *blocking = 0) |
Semaphore* blocking = 0); |
throw(IPCException); |
|
|
|
| |
Uint32 kill_dead_threads( void ) |
/** |
throw(IPCException); |
Cleans up idle threads if they have been running longer than the |
|
deallocate_wait configuration and more than the configured |
|
minimum number of threads is running. |
|
@return The number of threads that were cleaned up. |
|
@exception IPCException |
|
*/ |
|
Uint32 cleanupIdleThreads(); |
| |
void get_key(Sint8 *buf, int bufsize); | void get_key(Sint8 *buf, int bufsize); |
| |
inline Boolean operator==(const char *key) const | inline Boolean operator==(const char *key) const |
{ | { |
if ( ! strncmp(key, _key, 16)) |
return (!strncmp(key, _key, 16)); |
return(true); |
|
return(false); |
|
} |
|
inline Boolean operator==(const ThreadPool & b) const |
|
{ |
|
return(operator==(b._key)); |
|
} |
|
|
|
inline void set_min_threads(Sint16 min) |
|
{ |
|
_min_threads = min; |
|
} |
|
|
|
inline Sint16 get_min_threads(void) const |
|
{ |
|
return _min_threads; |
|
} | } |
| |
inline void set_max_threads(Sint16 max) |
Boolean operator==(const void* p) |
{ | { |
_max_threads = max; |
return ((void *)this == p); |
} | } |
| |
inline Sint16 get_max_threads(void) const |
inline Boolean operator==(const ThreadPool & b) const |
{ | { |
return _max_threads; |
return (operator==(b._key)); |
} | } |
| |
inline void set_allocate_wait(const struct timeval & alloc_wait) |
Boolean operator==(const ThreadPool & p) |
{ | { |
_allocate_wait.tv_sec = alloc_wait.tv_sec; |
return operator==((const void *)&p); |
_allocate_wait.tv_usec = alloc_wait.tv_usec; |
|
} | } |
| |
inline struct timeval *get_allocate_wait(struct timeval *buffer) const |
inline void setMinThreads(Sint16 min) |
{ | { |
if(buffer == 0) |
_minThreads = min; |
throw NullPointer(); |
|
buffer->tv_sec = _allocate_wait.tv_sec; |
|
buffer->tv_usec = _allocate_wait.tv_usec; |
|
return buffer; |
|
} | } |
| |
inline void set_deallocate_wait(const struct timeval & dealloc_wait) |
inline Sint16 getMinThreads() const |
{ | { |
_deallocate_wait.tv_sec = dealloc_wait.tv_sec; |
return _minThreads; |
_deallocate_wait.tv_usec = dealloc_wait.tv_usec; |
|
} | } |
| |
inline struct timeval *get_deallocate_wait(struct timeval *buffer) const |
inline void setMaxThreads(Sint16 max) |
{ | { |
if(buffer == 0) |
_maxThreads = max; |
throw NullPointer(); |
|
buffer->tv_sec = _deallocate_wait.tv_sec; |
|
buffer->tv_usec = _deallocate_wait.tv_usec; |
|
return buffer; |
|
} | } |
| |
inline Uint32 running_count(void) |
inline Sint16 getMaxThreads() const |
{ | { |
return _running.count(); |
return _maxThreads; |
} | } |
| |
inline Uint32 pool_count(void) |
inline Uint32 runningCount() |
{ | { |
return _pool.count(); |
return _runningThreads.count(); |
} | } |
| |
static Boolean check_time(struct timeval *start, struct timeval *interval); |
inline Uint32 idleCount() |
|
|
Boolean operator ==(const ThreadPool & p) |
|
{ | { |
return operator==((const void *)&p); |
return _idleThreads.count(); |
} | } |
| |
Boolean operator ==(const void *p) |
private: |
{ |
|
if((void *)this == p) |
|
return true; |
|
return false; |
|
} |
|
| |
static void kill_idle_threads(void); |
ThreadPool(); // Unimplemented |
|
ThreadPool(const ThreadPool&); // Unimplemented |
|
ThreadPool& operator=(const ThreadPool&); // Unimplemented |
| |
private: |
|
ThreadPool(void); |
|
Sint16 _max_threads; |
|
Sint16 _min_threads; |
|
AtomicInt _current_threads; |
|
struct timeval _allocate_wait; |
|
struct timeval _deallocate_wait; |
|
static PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL _loop(void *); | static PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL _loop(void *); |
|
|
|
static Boolean _timeIntervalExpired( |
|
struct timeval* start, |
|
struct timeval* interval); |
|
|
|
static void _deleteSemaphore(void* p); |
|
|
|
void _cleanupThread(Thread* thread); |
|
Thread* _initializeThread(); |
|
void _addToIdleThreadsQueue(Thread* th); |
|
|
|
Sint16 _maxThreads; |
|
Sint16 _minThreads; |
|
AtomicInt _currentThreads; |
|
struct timeval _deallocateWait; |
char _key[17]; | char _key[17]; |
DQueue<Thread> _pool; |
DQueue<Thread> _idleThreads; |
DQueue<Thread> _running; |
DQueue<Thread> _runningThreads; |
AtomicInt _dying; | AtomicInt _dying; |
|
|
static void _sleep_sem_del(void *p); |
|
|
|
Boolean _check_dealloc(struct timeval *start); |
|
Thread *_init_thread(void) throw(IPCException); |
|
void _link_pool(Thread *th) throw(IPCException); |
|
static PEGASUS_THREAD_RETURN _undertaker(void *); |
|
static PEGASUS_THREAD_RETURN _graveyard(Thread *); |
|
static DQueue<ThreadPool> _pools; |
|
}; | }; |
| |
| |
|
|
|
|
#if defined(PEGASUS_OS_TYPE_WINDOWS) | #if defined(PEGASUS_OS_TYPE_WINDOWS) |
# include "ThreadWindows_inline.h" | # include "ThreadWindows_inline.h" |
#elif defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) | #elif defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) |