(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 a.dunfey      1.53.12.1 #include <Pegasus/Common/AcceptLanguageList.h>
 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 a.dunfey      1.53.12.1       //  Gets the AcceptLanguageList 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 a.dunfey      1.53.12.1       //  AcceptLanguageList object, is associated with the caller's thread.
429 kumpf         1.48            //
430 a.dunfey      1.53.12.1       static AcceptLanguageList * getLanguages(); //l10n
431 kumpf         1.48      
432 chuck         1.29            //
433 a.dunfey      1.53.12.1       //  Sets the AcceptLanguageList 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 a.dunfey      1.53.12.1       //  Note: the AcceptLanguageList object must be placed on the heap.
438 kumpf         1.48            //
439 a.dunfey      1.53.12.1       static void setLanguages(AcceptLanguageList *langs); //l10n
440 kumpf         1.48      
441 chuck         1.29            //
442 a.dunfey      1.53.12.1       //  Removes the AcceptLanguageList 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