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