(file) Return to Thread.h CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2