1 karl 1.55 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.2 //
|
3 karl 1.42 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.34 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.42 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.44 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.55 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.2 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.18 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.2 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
|
21 kumpf 1.18 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 kumpf 1.18 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.2 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Mike Day (mdday@us.ibm.com)
33 //
34 // Modified By: Markus Mueller
|
35 kumpf 1.36 // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
|
36 a.arora 1.37 // Amit K Arora, IBM (amita@in.ibm.com) for PEP#101
|
37 david.dillard 1.43 // David Dillard, VERITAS Software Corp.
38 // (david.dillard@veritas.com)
|
39 gs.keenan 1.45 // Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com)
|
40 joyce.j 1.51 // Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#2393
|
41 mike 1.2 //
42 //%/////////////////////////////////////////////////////////////////////////////
43
44 #ifndef Pegasus_Thread_h
45 #define Pegasus_Thread_h
|
46 kumpf 1.26
47 #include <cstring>
|
48 mike 1.2 #include <Pegasus/Common/Config.h>
|
49 mike 1.57.2.1 #include <Pegasus/Common/AtomicInt.h>
|
50 kumpf 1.23 #include <Pegasus/Common/InternalException.h>
|
51 kumpf 1.54 #include <Pegasus/Common/AcceptLanguageList.h>
|
52 kumpf 1.22 #include <Pegasus/Common/Linkage.h>
|
53 a.arora 1.37 #include <Pegasus/Common/AutoPtr.h>
|
54 mike 1.56 #include <Pegasus/Common/List.h>
|
55 mike 1.57.2.1 #include <Pegasus/Common/Mutex.h>
56 #include <Pegasus/Common/Semaphore.h>
57 #include <Pegasus/Common/TSDKey.h>
|
58 mike 1.2
59 PEGASUS_NAMESPACE_BEGIN
60
|
61 mike 1.56 class PEGASUS_COMMON_LINKAGE cleanup_handler : public Linkable
|
62 mike 1.2 {
63
64 public:
65 cleanup_handler( void (*routine)(void *), void *arg ) : _routine(routine), _arg(arg) {}
66 ~cleanup_handler() {; }
|
67 kumpf 1.57
|
68 mike 1.2 private:
|
69 david.dillard 1.50 void execute() { _routine(_arg); }
|
70 mike 1.2 cleanup_handler();
71 void (*_routine)(void *);
72
|
73 kumpf 1.48 void *_arg;
|
74 mike 1.57.2.1 ThreadCleanupType _cleanup_buffer;
|
75 mike 1.2 friend class Thread;
76 };
77
78 ///////////////////////////////////////////////////////////////////////////////
79
80
|
81 mike 1.56 class PEGASUS_COMMON_LINKAGE thread_data : public Linkable
|
82 mike 1.2 {
83
84 public:
85 static void default_delete(void *data);
|
86 kumpf 1.48
|
87 david.dillard 1.43 thread_data( const char *key ) : _delete_func(NULL) , _data(NULL), _size(0)
|
88 mike 1.2 {
|
89 kumpf 1.48 PEGASUS_ASSERT(key != NULL);
90 size_t keysize = strlen(key);
|
91 joyce.j 1.51 _key.reset(new char[keysize + 1]);
92 memcpy(_key.get(), key, keysize);
93 _key.get()[keysize] = 0x00;
|
94 kumpf 1.48
|
95 mike 1.2 }
|
96 kumpf 1.48
|
97 david.dillard 1.43 thread_data(const char *key, size_t size) : _delete_func(default_delete), _size(size)
|
98 mike 1.2 {
|
99 kumpf 1.48 PEGASUS_ASSERT(key != NULL);
100 size_t keysize = strlen(key);
|
101 joyce.j 1.51 _key.reset(new char[keysize + 1]);
102 memcpy(_key.get(), key, keysize);
103 _key.get()[keysize] = 0x00;
|
104 david.dillard 1.50 _data = ::operator new(_size);
|
105 mike 1.2
106 }
107
|
108 david.dillard 1.43 thread_data(const char *key, size_t size, void *data) : _delete_func(default_delete), _size(size)
|
109 mike 1.2 {
|
110 kumpf 1.48 PEGASUS_ASSERT(key != NULL);
111 PEGASUS_ASSERT(data != NULL);
112 size_t keysize = strlen(key);
113
|
114 joyce.j 1.51 _key.reset(new char[keysize + 1]);
115 memcpy(_key.get(), key, keysize);
116 _key.get()[keysize] = 0x00;
|
117 kumpf 1.48 _data = ::operator new(_size);
118 memcpy(_data, data, size);
|
119 mike 1.2 }
120
|
121 kumpf 1.48 ~thread_data()
122 {
123 if( _data != NULL)
124 if(_delete_func != NULL)
|
125 sage 1.9 {
|
126 kumpf 1.48 _delete_func( _data );
|
127 sage 1.9 }
|
128 kumpf 1.48 }
|
129 mike 1.2
|
130 konrad.r 1.40 /**
131 * This function is used to put data in thread space.
132 *
|
133 kumpf 1.48 * Be aware that there is NOTHING in place to stop
134 * other users of the thread to remove this data.
|
135 konrad.r 1.40 * Or change the data.
136 *
|
137 kumpf 1.48 * You, the developer has to make sure that there are
138 * no situations in which this can arise (ie, have a
|
139 konrad.r 1.40 * lock for the function which manipulates the TSD.
|
140 david.dillard 1.50 *
141 * @exception NullPointer
|
142 konrad.r 1.40 */
|
143 david.dillard 1.50 void put_data(void (*del)(void *), size_t size, void *data )
|
144 mike 1.2 {
|
145 kumpf 1.48 if(_data != NULL)
146 if(_delete_func != NULL)
147 _delete_func(_data);
148
149 _delete_func = del;
150 _data = data;
151 _size = size;
|
152 david.dillard 1.50 return;
|
153 mike 1.2 }
154
|
155 david.dillard 1.50 size_t get_size() { return _size; }
|
156 mike 1.2
|
157 konrad.r 1.40 /**
|
158 kumpf 1.48 * This function is used to retrieve data from the
159 * TSD, the thread specific data.
|
160 konrad.r 1.40 *
|
161 kumpf 1.48 * Be aware that there is NOTHING in place to stop
|
162 konrad.r 1.40 * other users of the thread to change the data you
163 * get from this function.
164 *
|
165 kumpf 1.48 * You, the developer has to make sure that there are
166 * no situations in which this can arise (ie, have a
|
167 konrad.r 1.40 * lock for the function which manipulates the TSD.
168 */
|
169 kumpf 1.48 void get_data(void **data, size_t *size)
170 {
171 if(data == NULL || size == NULL)
172 throw NullPointer();
173
174 *data = _data;
175 *size = _size;
176 return;
177
|
178 mike 1.2 }
179
|
180 david.dillard 1.50 // @exception NullPointer
181 void copy_data(void **buf, size_t *size)
|
182 mike 1.2 {
|
183 kumpf 1.48 if((buf == NULL) || (size == NULL))
|
184 david.dillard 1.50 throw NullPointer();
|
185 kumpf 1.48 *buf = ::operator new(_size);
186 *size = _size;
187 memcpy(*buf, _data, _size);
188 return;
189 }
190
191 inline Boolean operator==(const void *key) const
192 {
|
193 joyce.j 1.52 if ( ! strcmp(_key.get(), reinterpret_cast<const char *>(key)))
|
194 kumpf 1.48 return(true);
195 return(false);
196 }
|
197 mday 1.8
|
198 mike 1.2 inline Boolean operator==(const thread_data& b) const
199 {
|
200 joyce.j 1.51 return(operator==(b._key.get()));
|
201 mike 1.2 }
202
|
203 mike 1.56 static bool equal(const thread_data* node, const void* key)
204 {
205 return ((thread_data*)node)->operator==(key);
206 }
207
|
208 mike 1.2 private:
|
209 david.dillard 1.50 void (*_delete_func) (void *data);
|
210 mike 1.2 thread_data();
211 void *_data;
212 size_t _size;
|
213 joyce.j 1.51 AutoArrayPtr<char> _key;
|
214 mike 1.2
215 friend class Thread;
216 };
217
218
|
219 konrad.r 1.53 enum ThreadStatus {
220 PEGASUS_THREAD_OK = 1, /* No problems */
221 PEGASUS_THREAD_INSUFFICIENT_RESOURCES, /* Can't allocate a thread. Not enough
222 memory. Try again later */
223 PEGASUS_THREAD_SETUP_FAILURE, /* Could not allocate into the thread specific
224 data storage. */
225 PEGASUS_THREAD_UNAVAILABLE /* Service is being destroyed and no new threads can
226 be provided. */
227 };
228
|
229 mike 1.2 ///////////////////////////////////////////////////////////////////////////
230
|
231 mike 1.56 class PEGASUS_COMMON_LINKAGE Thread : public Linkable
|
232 mike 1.2 {
|
233 konrad.r 1.53 public:
|
234 mike 1.2
|
235 mike 1.57.2.1 Thread( ThreadReturnType (PEGASUS_THREAD_CDECL *start )(void *),
|
236 kumpf 1.48 void *parameter, Boolean detached );
|
237 mike 1.2
238 ~Thread();
239
|
240 kumpf 1.36 /**
241 Start the thread.
|
242 konrad.r 1.53 @return PEGASUS_THREAD_OK if the thread is started successfully,
243 PEGASUS_THREAD_INSUFFICIENT_RESOURCES if the resources necessary
244 to start the thread are not currently available.
245 PEGASUS_THREAD_SETUP_FAILURE if the thread could not
246 be create properly - check the 'errno' value for specific operating
247 system return code.
|
248 kumpf 1.36 */
|
249 konrad.r 1.53 ThreadStatus run();
|
250 mike 1.2
|
251 kumpf 1.48 // get the user parameter
|
252 david.dillard 1.50 inline void *get_parm() { return _thread_parm; }
|
253 mike 1.2
254 // cancellation must be deferred (not asynchronous)
255 // for user-level threads the thread itself can decide
|
256 kumpf 1.48 // when it should die.
|
257 david.dillard 1.50 void cancel();
|
258 mike 1.2
259 // cancel if there is a pending cancellation request
|
260 david.dillard 1.50 void test_cancel();
|
261 mike 1.2
|
262 david.dillard 1.50 Boolean is_cancelled();
|
263 kumpf 1.48
|
264 mike 1.2 // for user-level threads - put the calling thread
|
265 kumpf 1.48 // to sleep and jump to the thread scheduler.
266 // platforms with preemptive scheduling and native threads
267 // can define this to be a no-op.
268 // platforms without preemptive scheduling like NetWare
269 // or gnu portable threads will have an existing
270 // routine that can be mapped to this method
|
271 mike 1.2
|
272 david.dillard 1.50 void thread_switch();
|
273 mike 1.2
|
274 david.eger 1.27 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
|
275 kumpf 1.48 // suspend this thread
|
276 david.dillard 1.50 void suspend();
|
277 mike 1.2
278 // resume this thread
|
279 david.dillard 1.50 void resume();
|
280 mike 1.2 #endif
281
|
282 david.dillard 1.50 static void sleep(Uint32 msec);
|
283 mike 1.2
284 // block the calling thread until this thread terminates
|
285 david.dillard 1.50 void join();
286 void thread_init();
|
287 mike 1.2
288 // thread routine needs to call this function when
289 // it is ready to exit
|
290 mike 1.57.2.1 void exit_self(ThreadReturnType return_code);
|
291 mike 1.2
292 // stack of functions to be called when thread terminates
293 // will be called last in first out (LIFO)
|
294 david.dillard 1.50 // @exception IPCException
295 void cleanup_push(void (*routine) (void *), void *parm);
296
297 // @exception IPCException
298 void cleanup_pop(Boolean execute = true);
|
299 mike 1.2
300 // create and initialize a tsd
|
301 david.dillard 1.50 // @exception IPCException
302 inline void create_tsd(const char *key, int size, void *buffer)
|
303 mike 1.2 {
|
304 a.arora 1.37 AutoPtr<thread_data> tsd(new thread_data(key, size, buffer));
|
305 mike 1.56 _tsd.insert_front(tsd.get());
|
306 a.arora 1.37 tsd.release();
|
307 mike 1.2 }
308
309 // get the buffer associated with the key
|
310 kumpf 1.48 // NOTE: this call leaves the tsd LOCKED !!!!
|
311 david.dillard 1.50 // @exception IPCException
312 inline void *reference_tsd(const char *key)
|
313 mike 1.2 {
|
314 kumpf 1.48 _tsd.lock();
|
315 mike 1.56 thread_data *tsd = _tsd.find(thread_data::equal, key);
|
316 kumpf 1.48 if(tsd != NULL)
317 return( (void *)(tsd->_data) );
318 else
319 return(NULL);
|
320 mike 1.2 }
321
|
322 david.dillard 1.50 // @exception IPCException
323 inline void *try_reference_tsd(const char *key)
|
324 mike 1.2 {
|
325 kumpf 1.48 _tsd.try_lock();
|
326 mike 1.56 thread_data *tsd = _tsd.find(thread_data::equal, key);
|
327 kumpf 1.48 if(tsd != NULL)
328 return((void *)(tsd->_data) );
329 else
330 return(NULL);
|
331 mike 1.2 }
|
332 kumpf 1.48
|
333 mike 1.2
334 // release the lock held on the tsd
335 // NOTE: assumes a corresponding and prior call to reference_tsd() !!!
|
336 david.dillard 1.50 // @exception IPCException
337 inline void dereference_tsd()
|
338 mike 1.2 {
|
339 kumpf 1.48 _tsd.unlock();
|
340 mike 1.2 }
341
342 // delete the tsd associated with the key
|
343 david.dillard 1.50 // @exception IPCException
344 inline void delete_tsd(const char *key)
|
345 mike 1.2 {
|
346 mike 1.56 AutoPtr<thread_data> tsd(_tsd.remove(thread_data::equal, key));
|
347 mike 1.2 }
|
348 kumpf 1.48
|
349 david.dillard 1.50 // @exception IPCException
350 inline void empty_tsd()
|
351 mike 1.2 {
|
352 mike 1.56 _tsd.clear();
|
353 mike 1.2 }
|
354 kumpf 1.48
|
355 mike 1.2 // create or re-initialize tsd associated with the key
|
356 kumpf 1.14 // if the tsd already exists, delete the existing buffer
|
357 david.dillard 1.50 // @exception IPCException
|
358 kumpf 1.48 void put_tsd(const char *key, void (*delete_func)(void *), Uint32 size, void *value)
|
359 mike 1.2 {
|
360 kumpf 1.48 PEGASUS_ASSERT(key != NULL);
|
361 david.dillard 1.50 AutoPtr<thread_data> tsd;
|
362 mike 1.56 tsd.reset(_tsd.remove(thread_data::equal, key)); // may throw an IPC exception
|
363 kumpf 1.48 tsd.reset();
364 AutoPtr<thread_data> ntsd(new thread_data(key));
365 ntsd->put_data(delete_func, size, value);
|
366 mike 1.56 try { _tsd.insert_front(ntsd.get()); }
|
367 kumpf 1.48 catch(IPCException& e) { e = e; throw; }
|
368 david.dillard 1.50 ntsd.release();
|
369 mike 1.2 }
|
370 mike 1.57.2.1 inline ThreadReturnType get_exit() { return _exit_code; }
371 inline ThreadType self() {return Threads::self(); }
|
372 mike 1.2
|
373 mike 1.57.2.1 ThreadHandle getThreadHandle() {return _handle;}
|
374 mike 1.2
|
375 david.dillard 1.50 void detach();
|
376 kumpf 1.48
|
377 chuck 1.29 //
378 // Gets the Thread object associated with the caller's thread.
|
379 chuck 1.31 // Note: this may return NULL if no Thread object is associated
380 // with the caller's thread.
|
381 chuck 1.29 //
|
382 chuck 1.28 static Thread * getCurrent(); // l10n
|
383 chuck 1.29
384 //
|
385 chuck 1.31 // Sets the Thread object associated with the caller's thread.
386 // Note: the Thread object must be placed on the heap.
|
387 chuck 1.29 //
|
388 kumpf 1.48 static void setCurrent(Thread * thrd); // l10n
|
389 chuck 1.29
390 //
|
391 kumpf 1.54 // Gets the AcceptLanguageList object associated with the caller's
|
392 chuck 1.29 // Thread.
|
393 chuck 1.31 // Note: this may return NULL if no Thread object, or no
|
394 kumpf 1.54 // AcceptLanguageList object, is associated with the caller's thread.
|
395 kumpf 1.48 //
|
396 kumpf 1.54 static AcceptLanguageList * getLanguages(); //l10n
|
397 kumpf 1.48
|
398 chuck 1.29 //
|
399 kumpf 1.54 // Sets the AcceptLanguageList object associated with the caller's
|
400 chuck 1.29 // Thread.
|
401 chuck 1.31 // Note: a Thread object must have been previously associated with
|
402 kumpf 1.48 // the caller's thread.
|
403 kumpf 1.54 // Note: the AcceptLanguageList object must be placed on the heap.
|
404 kumpf 1.48 //
|
405 kumpf 1.54 static void setLanguages(AcceptLanguageList *langs); //l10n
|
406 kumpf 1.48
|
407 chuck 1.29 //
|
408 kumpf 1.54 // Removes the AcceptLanguageList object associated with the caller's
|
409 chuck 1.29 // Thread.
|
410 kumpf 1.48 //
411 static void clearLanguages(); //l10n
412
|
413 mike 1.2 private:
414 Thread();
|
415 chuck 1.29
416 static Sint8 initializeKey(); // l10n
417
|
418 david.dillard 1.50 // @exception IPCException
419 inline void create_tsd(const char *key )
|
420 mike 1.2 {
|
421 kumpf 1.48 AutoPtr<thread_data> tsd(new thread_data(key));
|
422 mike 1.56 _tsd.insert_front(tsd.get());
|
423 kumpf 1.48 tsd.release();
|
424 mike 1.2 }
|
425 mike 1.57.2.1 ThreadHandle _handle;
|
426 mike 1.2 Boolean _is_detached;
427 Boolean _cancel_enabled;
|
428 kumpf 1.48 Boolean _cancelled;
429
|
430 mike 1.2 // always pass this * as the void * parameter to the thread
|
431 kumpf 1.48 // store the user parameter in _thread_parm
|
432 mike 1.2
|
433 mike 1.57.2.1 ThreadReturnType ( PEGASUS_THREAD_CDECL *_start)(void *);
434 List<cleanup_handler, Mutex> _cleanup;
435 List<thread_data, Mutex> _tsd;
|
436 mike 1.2
437 void *_thread_parm;
|
438 mike 1.57.2.1 ThreadReturnType _exit_code;
|
439 mike 1.2 static Boolean _signals_blocked;
|
440 mike 1.57.2.1 static TSDKeyType _platform_thread_key; //l10n
|
441 kumpf 1.48 static Boolean _key_initialized; // l10n
442 static Boolean _key_error; // l10n
443 };
|
444 mike 1.2
445
446 class PEGASUS_COMMON_LINKAGE ThreadPool
447 {
|
448 kumpf 1.48 public:
|
449 mike 1.2
|
450 kumpf 1.48 /**
451 Constructs a new ThreadPool object.
452 @param initialSize The number of threads that are initially added to
453 the thread pool.
454 @param key A name for this thread pool that can be used to determine
455 equality of two thread pool objects. Only the first 16 characters
456 of this value are used.
457 @param minThreads The minimum number of threads that should be
458 contained in this thread pool at any given time.
459 @param maxThreads The maximum number of threads that should be
460 contained in this thread pool at any given time.
461 @param deallocateWait The minimum time that a thread should be idle
462 before it is removed from the pool and cleaned up.
463 */
464 ThreadPool(
465 Sint16 initialSize,
466 const char* key,
467 Sint16 minThreads,
468 Sint16 maxThreads,
469 struct timeval& deallocateWait);
470
471 kumpf 1.48 /**
472 Destructs the ThreadPool object.
473 */
474 ~ThreadPool();
475
476 /**
477 Allocate and start a thread to do a unit of work.
478 @param parm A generic parameter to pass to the thread
479 @param work A pointer to the function that is to be executed by
480 the thread
481 @param blocking A pointer to an optional semaphore which, if
482 specified, is signaled after the thread finishes
483 executing the work function
|
484 konrad.r 1.53 @return PEGASUS_THREAD_OK if the thread is started successfully,
485 PEGASUS_THREAD_INSUFFICIENT_RESOURCES if the
|
486 kumpf 1.48 resources necessary to start the thread are not currently
|
487 konrad.r 1.53 available. PEGASUS_THREAD_SETUP_FAILURE if the thread
488 could not be setup properly. PEGASUS_THREAD_UNAVAILABLE
489 if this service is shutting down and no more threads can
490 be allocated.
|
491 kumpf 1.48 @exception IPCException
492 */
|
493 konrad.r 1.53 ThreadStatus allocate_and_awaken(
|
494 kumpf 1.48 void* parm,
|
495 mike 1.57.2.1 ThreadReturnType (PEGASUS_THREAD_CDECL* work)(void *),
|
496 kumpf 1.48 Semaphore* blocking = 0);
497
498 /**
499 Cleans up idle threads if they have been running longer than the
500 deallocate_wait configuration and more than the configured
501 minimum number of threads is running.
502 @return The number of threads that were cleaned up.
503 @exception IPCException
504 */
505 Uint32 cleanupIdleThreads();
506
507 void get_key(Sint8* buf, int bufsize);
508
509 inline void setMinThreads(Sint16 min)
510 {
511 _minThreads = min;
512 }
513
514 inline Sint16 getMinThreads() const
515 {
516 return _minThreads;
517 kumpf 1.48 }
518
519 inline void setMaxThreads(Sint16 max)
520 {
521 _maxThreads = max;
522 }
523
524 inline Sint16 getMaxThreads() const
525 {
526 return _maxThreads;
527 }
528
529 inline Uint32 runningCount()
530 {
|
531 mike 1.56 return _runningThreads.size();
|
532 kumpf 1.48 }
533
534 inline Uint32 idleCount()
535 {
|
536 mike 1.56 return _idleThreads.size();
|
537 kumpf 1.48 }
538
539 private:
540
541 ThreadPool(); // Unimplemented
542 ThreadPool(const ThreadPool&); // Unimplemented
543 ThreadPool& operator=(const ThreadPool&); // Unimplemented
544
|
545 mike 1.57.2.1 static ThreadReturnType PEGASUS_THREAD_CDECL _loop(void *);
|
546 kumpf 1.48
547 static Boolean _timeIntervalExpired(
548 struct timeval* start,
549 struct timeval* interval);
550
551 static void _deleteSemaphore(void* p);
552
553 void _cleanupThread(Thread* thread);
554 Thread* _initializeThread();
555 void _addToIdleThreadsQueue(Thread* th);
556
557 Sint16 _maxThreads;
558 Sint16 _minThreads;
559 AtomicInt _currentThreads;
560 struct timeval _deallocateWait;
561 char _key[17];
|
562 mike 1.57.2.1 List<Thread, Mutex> _idleThreads;
563 List<Thread, Mutex> _runningThreads;
|
564 kumpf 1.48 AtomicInt _dying;
565 };
|
566 mike 1.2
567
568 #if defined(PEGASUS_OS_TYPE_WINDOWS)
569 # include "ThreadWindows_inline.h"
|
570 sage 1.6 #elif defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
571 # include "ThreadzOS_inline.h"
|
572 mike 1.2 #elif defined(PEGASUS_OS_TYPE_UNIX)
573 # include "ThreadUnix_inline.h"
|
574 gs.keenan 1.45 #elif defined(PEGASUS_OS_VMS)
575 # include "ThreadVms_inline.h"
|
576 mike 1.2 #endif
577
578 PEGASUS_NAMESPACE_END
579
580 #endif // Pegasus_Thread_h
|