00001 
00002 
00003 #include "ace/TSS_T.h"
00004 #include "ace/Thread_Manager.h"
00005 #include "ace/Dynamic.h"
00006 #include "ace/Object_Manager.h"
00007 #include "ace/Singleton.h"
00008 #include "ace/Auto_Ptr.h"
00009 #include "ace/Guard_T.h"
00010 
00011 #include "ace/Time_Value.h"
00012 #include "ace/OS_NS_sys_time.h"
00013 
00014 #if !defined (__ACE_INLINE__)
00015 #include "ace/Thread_Manager.inl"
00016 #endif 
00017 
00018 
00019 ACE_RCSID (ace,
00020            Thread_Manager,
00021            "Thread_Manager.cpp,v 4.239 2006/06/12 01:33:26 schmidt Exp")
00022 
00023 
00024 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00025 
00026 #if !defined(ACE_USE_ONE_SHOT_AT_THREAD_EXIT)
00027 
00028 ACE_At_Thread_Exit::~ACE_At_Thread_Exit (void)
00029 {
00030   this->do_apply ();
00031 }
00032 
00033 ACE_At_Thread_Exit_Func::~ACE_At_Thread_Exit_Func (void)
00034 {
00035   this->do_apply ();
00036 }
00037 
00038 void
00039 ACE_At_Thread_Exit_Func::apply (void)
00040 {
00041   this->func_ (this->object_, this->param_);
00042 }
00043 
00044 #endif  
00045 
00046 
00047 ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Control)
00048 ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Manager)
00049 
00050 #if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
00051 
00052 ACE_Thread_Manager *ACE_Thread_Manager::thr_mgr_ = 0;
00053 
00054 
00055 
00056 int ACE_Thread_Manager::delete_thr_mgr_ = 0;
00057 #endif 
00058 
00059 ACE_TSS_TYPE (ACE_Thread_Exit) *ACE_Thread_Manager::thr_exit_ = 0;
00060 
00061 int
00062 ACE_Thread_Manager::set_thr_exit (ACE_TSS_TYPE (ACE_Thread_Exit) *ptr)
00063 {
00064   if (ACE_Thread_Manager::thr_exit_ == 0)
00065     ACE_Thread_Manager::thr_exit_ = ptr;
00066   else
00067     return -1;
00068   return 0;
00069 }
00070 
00071 void
00072 ACE_Thread_Manager::dump (void)
00073 {
00074 #if defined (ACE_HAS_DUMP)
00075   ACE_TRACE ("ACE_Thread_Manager::dump");
00076   
00077   ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon,
00078                      ((ACE_Thread_Manager *) this)->lock_));
00079 
00080   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00081 
00082   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ngrp_id_ = %d"), this->grp_id_));
00083   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ncurrent_count_ = %d"), this->thr_list_.size ()));
00084 
00085   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
00086        !iter.done ();
00087        iter.advance ())
00088     iter.next ()->dump ();
00089 
00090   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00091 #endif 
00092 }
00093 
00094 ACE_Thread_Descriptor::~ACE_Thread_Descriptor (void)
00095 {
00096   delete this->sync_;
00097 }
00098 
00099 #if !defined(ACE_USE_ONE_SHOT_AT_THREAD_EXIT)
00100 void ACE_Thread_Descriptor::at_pop (int apply)
00101 
00102 {
00103   ACE_TRACE ("ACE_Thread_Descriptor::at_pop");
00104   
00105   ACE_At_Thread_Exit* at = this->at_exit_list_;
00106   
00107   this->at_exit_list_ = at->next_;
00108   
00109   if (apply)
00110    {
00111      at->apply ();
00112      
00113      at->was_applied (1);
00114      
00115      
00116    }
00117   
00118   if (!at->is_owner ())
00119    delete at;
00120 }
00121 
00122 void
00123 ACE_Thread_Descriptor::at_push (ACE_At_Thread_Exit* cleanup, int is_owner)
00124 
00125 {
00126   ACE_TRACE ("ACE_Thread_Descriptor::at_push");
00127   cleanup->is_owner (is_owner);
00128   cleanup->td_ = this;
00129   cleanup->next_ = at_exit_list_;
00130   at_exit_list_ = cleanup;
00131 }
00132 
00133 int
00134 ACE_Thread_Descriptor::at_exit (ACE_At_Thread_Exit& cleanup)
00135 
00136 {
00137   ACE_TRACE ("ACE_Thread_Descriptor::at_exit");
00138   at_push (&cleanup, 1);
00139   return 0;
00140 }
00141 
00142 int
00143 ACE_Thread_Descriptor::at_exit (ACE_At_Thread_Exit* cleanup)
00144 
00145 {
00146   ACE_TRACE ("ACE_Thread_Descriptor::at_exit");
00147   if (cleanup==0)
00148    return -1;
00149   else
00150    {
00151      this->at_push (cleanup);
00152      return 0;
00153    }
00154 }
00155 
00156 void
00157 ACE_Thread_Descriptor::do_at_exit ()
00158 
00159 {
00160   ACE_TRACE ("ACE_Thread_Descriptor::do_at_exit");
00161   while (at_exit_list_!=0)
00162     this->at_pop ();
00163 }
00164 
00165 void
00166 ACE_Thread_Descriptor::terminate ()
00167 
00168 {
00169   ACE_TRACE ("ACE_Thread_Descriptor::terminate");
00170 
00171   if (!terminated_)
00172    {
00173      ACE_Log_Msg* log_msg = this->log_msg_;
00174      terminated_ = true;
00175      
00176      this->do_at_exit ();
00177      
00178      if (this->tm_ != 0)
00179       {
00180          int close_handle = 0;
00181 
00182 #if !defined (ACE_VXWORKS)
00183          
00184          
00185 
00186          if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_JOINING))
00187            {
00188              if (ACE_BIT_DISABLED (this->flags_, THR_DETACHED | THR_DAEMON)
00189                  || ACE_BIT_ENABLED (this->flags_, THR_JOINABLE))
00190                {
00191                  
00192                  ACE_SET_BITS (this->thr_state_, ACE_Thread_Manager::ACE_THR_TERMINATED);
00193                  tm_->register_as_terminated (this);
00194                  
00195                  
00196                }
00197 #if defined (ACE_WIN32)
00198              else
00199                {
00200                  close_handle = 1;
00201                }
00202 #endif 
00203            }
00204 #endif 
00205 
00206          
00207          if (this->tm_ != 0)
00208            tm_->remove_thr (this, close_handle);
00209       }
00210 
00211      
00212      
00213      if (log_msg == 0)
00214       {
00215         
00216         
00217         ACE_LOG_MSG->thr_desc (0);
00218       }
00219      else
00220       {
00221         
00222         
00223         this->log_msg_ = 0;
00224         delete log_msg;
00225       }
00226    }
00227 }
00228 
00229 #endif 
00230 
00231 int
00232 ACE_Thread_Descriptor::at_exit (void *object,
00233                                 ACE_CLEANUP_FUNC cleanup_hook,
00234                                 void *param)
00235 {
00236   ACE_TRACE ("ACE_Thread_Descriptor::at_exit");
00237 #if defined(ACE_USE_ONE_SHOT_AT_THREAD_EXIT)
00238   this->cleanup_info_.cleanup_hook_ = cleanup_hook;
00239   this->cleanup_info_.object_ = object;
00240   this->cleanup_info_.param_ = param;
00241 #else
00242   
00243   
00244   if (cleanup_hook == 0)
00245    {
00246      if (this->at_exit_list_!= 0)
00247       this->at_pop(0);
00248    }
00249   else
00250    {
00251      ACE_At_Thread_Exit* cleanup = 0;
00252      ACE_NEW_RETURN (cleanup,
00253                      ACE_At_Thread_Exit_Func (object,
00254                                               cleanup_hook,
00255                                               param),
00256                      -1);
00257      this->at_push (cleanup);
00258    }
00259 #endif 
00260   return 0;
00261 }
00262 
00263 void
00264 ACE_Thread_Descriptor::dump (void) const
00265 {
00266 #if defined (ACE_HAS_DUMP)
00267   ACE_TRACE ("ACE_Thread_Descriptor::dump");
00268   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00269 
00270   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nthr_id_ = %d"), this->thr_id_));
00271   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nthr_handle_ = %d"), this->thr_handle_));
00272   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ngrp_id_ = %d"), this->grp_id_));
00273   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nthr_state_ = %d"), this->thr_state_));
00274   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ncleanup_info_.cleanup_hook_ = %x"), this->cleanup_info_.cleanup_hook_));
00275   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nflags_ = %x\n"), this->flags_));
00276 
00277   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00278 #endif 
00279 }
00280 
00281 ACE_Thread_Descriptor::ACE_Thread_Descriptor (void)
00282 #if !defined (ACE_USE_ONE_SHOT_AT_THREAD_EXIT)
00283   : log_msg_ (0),
00284     at_exit_list_ (0),
00285     terminated_ (false)
00286 #endif 
00287 {
00288   ACE_TRACE ("ACE_Thread_Descriptor::ACE_Thread_Descriptor");
00289   ACE_NEW (this->sync_,
00290            ACE_DEFAULT_THREAD_MANAGER_LOCK);
00291 }
00292 
00293 void
00294 ACE_Thread_Descriptor::acquire_release (void)
00295 {
00296   
00297 #if defined (ACE_THREAD_MANAGER_USES_SAFE_SPAWN)
00298   if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED))
00299 #endif 
00300     {
00301       this->sync_->acquire ();
00302       
00303       
00304       
00305 
00306       
00307       ACE_ASSERT (ACE_BIT_ENABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED));
00308 
00309       this->sync_->release ();
00310       
00311     }
00312 }
00313 
00314 void
00315 ACE_Thread_Descriptor::acquire (void)
00316 {
00317   
00318 #if defined (ACE_THREAD_MANAGER_USES_SAFE_SPAWN)
00319   if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED))
00320 #endif 
00321     {
00322       this->sync_->acquire ();
00323     }
00324 }
00325 
00326 void
00327 ACE_Thread_Descriptor::release (void)
00328 {
00329   
00330 #if defined (ACE_THREAD_MANAGER_USES_SAFE_SPAWN)
00331   if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED))
00332 #endif 
00333     {
00334       this->sync_->release ();
00335       
00336     }
00337 }
00338 
00339 
00340 #define ACE_FIND(OP,INDEX) \
00341   ACE_Thread_Descriptor *INDEX = OP; \
00342 
00343 ACE_Thread_Descriptor *
00344 ACE_Thread_Manager::thread_descriptor (ACE_thread_t thr_id)
00345 {
00346   ACE_TRACE ("ACE_Thread_Manager::thread_descriptor");
00347   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00348 
00349   ACE_FIND (this->find_thread (thr_id), ptr);
00350   return ptr;
00351 }
00352 
00353 ACE_Thread_Descriptor *
00354 ACE_Thread_Manager::hthread_descriptor (ACE_hthread_t thr_handle)
00355 {
00356   ACE_TRACE ("ACE_Thread_Manager::hthread_descriptor");
00357   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00358 
00359   ACE_FIND (this->find_hthread (thr_handle), ptr);
00360   return ptr;
00361 }
00362 
00363 
00364 
00365 int
00366 ACE_Thread_Manager::thr_self (ACE_hthread_t &self)
00367 {
00368   ACE_TRACE ("ACE_Thread_Manager::thr_self");
00369 
00370   ACE_Thread_Descriptor *desc =
00371     this->thread_desc_self ();
00372 
00373   if (desc == 0)
00374     return -1;
00375   else
00376     desc->self (self);
00377 
00378   return 0;
00379 }
00380 
00381 
00382 
00383 ACE_Thread_Manager::ACE_Thread_Manager (size_t prealloc,
00384                                         size_t lwm,
00385                                         size_t inc,
00386                                         size_t hwm)
00387   : grp_id_ (1),
00388     automatic_wait_ (1)
00389 #if defined (ACE_HAS_THREADS)
00390     , zero_cond_ (lock_)
00391 #endif 
00392     , thread_desc_freelist_ (ACE_FREE_LIST_WITH_POOL,
00393                              prealloc, lwm, hwm, inc)
00394 {
00395   ACE_TRACE ("ACE_Thread_Manager::ACE_Thread_Manager");
00396 }
00397 
00398 #if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
00399 ACE_Thread_Manager *
00400 ACE_Thread_Manager::instance (void)
00401 {
00402   ACE_TRACE ("ACE_Thread_Manager::instance");
00403 
00404   if (ACE_Thread_Manager::thr_mgr_ == 0)
00405     {
00406       
00407       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00408                                 *ACE_Static_Object_Lock::instance (), 0));
00409 
00410       if (ACE_Thread_Manager::thr_mgr_ == 0)
00411         {
00412           ACE_NEW_RETURN (ACE_Thread_Manager::thr_mgr_,
00413                           ACE_Thread_Manager,
00414                           0);
00415           ACE_Thread_Manager::delete_thr_mgr_ = 1;
00416         }
00417     }
00418 
00419   return ACE_Thread_Manager::thr_mgr_;
00420 }
00421 
00422 ACE_Thread_Manager *
00423 ACE_Thread_Manager::instance (ACE_Thread_Manager *tm)
00424 {
00425   ACE_TRACE ("ACE_Thread_Manager::instance");
00426   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00427                             *ACE_Static_Object_Lock::instance (), 0));
00428 
00429   ACE_Thread_Manager *t = ACE_Thread_Manager::thr_mgr_;
00430   
00431   ACE_Thread_Manager::delete_thr_mgr_ = 0;
00432 
00433   ACE_Thread_Manager::thr_mgr_ = tm;
00434   return t;
00435 }
00436 
00437 void
00438 ACE_Thread_Manager::close_singleton (void)
00439 {
00440   ACE_TRACE ("ACE_Thread_Manager::close_singleton");
00441 
00442   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00443                      *ACE_Static_Object_Lock::instance ()));
00444 
00445   if (ACE_Thread_Manager::delete_thr_mgr_)
00446     {
00447       
00448       ACE_Thread_Manager::thr_mgr_->close ();
00449       delete ACE_Thread_Manager::thr_mgr_;
00450       ACE_Thread_Manager::thr_mgr_ = 0;
00451       ACE_Thread_Manager::delete_thr_mgr_ = 0;
00452     }
00453 
00454   ACE_Thread_Exit::cleanup (ACE_Thread_Manager::thr_exit_);
00455 }
00456 #endif 
00457 
00458 
00459 
00460 int
00461 ACE_Thread_Manager::close ()
00462 {
00463   ACE_TRACE ("ACE_Thread_Manager::close");
00464 
00465   
00466   if (this->automatic_wait_)
00467     this->wait (0, 1);
00468   else
00469     {
00470       ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00471 
00472       this->remove_thr_all ();
00473     }
00474 
00475   return 0;
00476 }
00477 
00478 ACE_Thread_Manager::~ACE_Thread_Manager (void)
00479 {
00480   ACE_TRACE ("ACE_Thread_Manager::~ACE_Thread_Manager");
00481   this->close ();
00482 }
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506 
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 #if defined(ACE_USE_THREAD_MANAGER_ADAPTER)
00516 extern "C" void *
00517 ace_thread_manager_adapter (void *args)
00518 {
00519 #if defined (ACE_HAS_TSS_EMULATION)
00520   
00521   
00522   
00523   void *ts_storage[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX];
00524   ACE_TSS_Emulation::tss_open (ts_storage);
00525 #endif 
00526 
00527   ACE_Thread_Adapter *thread_args = (ACE_Thread_Adapter *) args;
00528 
00529   
00530   
00531   
00532   
00533 #if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)
00534   
00535   
00536   
00537   
00538   ACE_Thread_Exit &exit_hook = *ACE_Thread_Exit::instance ();
00539 #else
00540   
00541   
00542   
00543   
00544   
00545   
00546   ACE_Thread_Exit exit_hook;
00547 #endif 
00548 
00549   
00550   
00551   exit_hook.thr_mgr (thread_args->thr_mgr ());
00552 
00553   
00554   void *status = thread_args->invoke ();
00555 
00556   return status;
00557 }
00558 #endif
00559 
00560 
00561 
00562 
00563 int
00564 ACE_Thread_Manager::spawn_i (ACE_THR_FUNC func,
00565                              void *args,
00566                              long flags,
00567                              ACE_thread_t *t_id,
00568                              ACE_hthread_t *t_handle,
00569                              long priority,
00570                              int grp_id,
00571                              void *stack,
00572                              size_t stack_size,
00573                              ACE_Task_Base *task)
00574 {
00575   
00576   
00577   
00578   
00579   ACE_ASSERT (ACE_BIT_DISABLED (flags, THR_DAEMON));
00580 
00581   
00582   
00583   
00584   auto_ptr<ACE_Thread_Descriptor> new_thr_desc (this->thread_desc_freelist_.remove ());
00585 
00586   
00587   new_thr_desc->reset (this);
00588 
00589   ACE_Thread_Adapter *thread_args = 0;
00590 # if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
00591   ACE_NEW_RETURN (thread_args,
00592                   ACE_Thread_Adapter (func,
00593                                       args,
00594                                       (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME,
00595                                       this,
00596                                       new_thr_desc.get (),
00597                                       ACE_OS_Object_Manager::seh_except_selector(),
00598                                       ACE_OS_Object_Manager::seh_except_handler()),
00599                   -1);
00600 # else
00601   ACE_NEW_RETURN (thread_args,
00602                   ACE_Thread_Adapter (func,
00603                                       args,
00604                                       (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME,
00605                                       this,
00606                                       new_thr_desc.get ()),
00607                   -1);
00608 # endif 
00609 
00610   ACE_TRACE ("ACE_Thread_Manager::spawn_i");
00611   ACE_hthread_t thr_handle;
00612 
00613 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
00614   
00615   
00616   
00617   
00618   
00619   
00620   if (t_id == 0)
00621     {
00622        ACE_NEW_RETURN (t_id,
00623                        char*,
00624                        -1);
00625        ACE_NEW_RETURN (*t_id,
00626                        char[16],
00627                        -1);
00628        
00629        
00630        (*t_id)[0] = ACE_THR_ID_ALLOCATED;
00631        (*t_id)[1] = '\0';
00632     }
00633 #else  
00634   ACE_thread_t thr_id;
00635   if (t_id == 0)
00636     t_id = &thr_id;
00637 #endif 
00638 
00639   new_thr_desc->sync_->acquire ();
00640   
00641   
00642   
00643 
00644   int const result = ACE_Thread::spawn (func,
00645                                         args,
00646                                         flags,
00647                                         t_id,
00648                                         &thr_handle,
00649                                         priority,
00650                                         stack,
00651                                         stack_size,
00652                                         thread_args);
00653 
00654   if (result != 0)
00655     {
00656       
00657       
00658       
00659       ACE_Errno_Guard guard (errno);     
00660       new_thr_desc->sync_->release ();
00661       return -1;
00662     }
00663 
00664 #if defined (ACE_HAS_WTHREADS)
00665   
00666   
00667   
00668   if (t_handle != 0)
00669 # if defined (ACE_HAS_WINCE)
00670     *t_handle = thr_handle;
00671 # else  
00672   (void) ::DuplicateHandle (::GetCurrentProcess (),
00673                             thr_handle,
00674                             ::GetCurrentProcess (),
00675                             t_handle,
00676                             0,
00677                             TRUE,
00678                             DUPLICATE_SAME_ACCESS);
00679 # endif 
00680 #else  
00681   if (t_handle != 0)
00682     *t_handle = thr_handle;
00683 #endif 
00684 
00685   
00686   
00687   
00688   return this->append_thr (*t_id,
00689                            thr_handle,
00690                            ACE_THR_SPAWNED,
00691                            grp_id,
00692                            task,
00693                            flags,
00694                            new_thr_desc.release ());
00695 }
00696 
00697 int
00698 ACE_Thread_Manager::spawn (ACE_THR_FUNC func,
00699                            void *args,
00700                            long flags,
00701                            ACE_thread_t *t_id,
00702                            ACE_hthread_t *t_handle,
00703                            long priority,
00704                            int grp_id,
00705                            void *stack,
00706                            size_t stack_size)
00707 {
00708   ACE_TRACE ("ACE_Thread_Manager::spawn");
00709 
00710   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00711 
00712   if (grp_id == -1)
00713     grp_id = this->grp_id_++; 
00714 
00715   if (priority != ACE_DEFAULT_THREAD_PRIORITY)
00716     ACE_CLR_BITS (flags, THR_INHERIT_SCHED);
00717 
00718   if (this->spawn_i (func,
00719                      args,
00720                      flags,
00721                      t_id,
00722                      t_handle,
00723                      priority,
00724                      grp_id,
00725                      stack,
00726                      stack_size,
00727                      0) == -1)
00728     return -1;
00729 
00730   return grp_id;
00731 }
00732 
00733 
00734 
00735 int
00736 ACE_Thread_Manager::spawn_n (size_t n,
00737                              ACE_THR_FUNC func,
00738                              void *args,
00739                              long flags,
00740                              long priority,
00741                              int grp_id,
00742                              ACE_Task_Base *task,
00743                              ACE_hthread_t thread_handles[],
00744                              void *stack[],
00745                              size_t stack_size[])
00746 {
00747   ACE_TRACE ("ACE_Thread_Manager::spawn_n");
00748   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00749 
00750   if (grp_id == -1)
00751     grp_id = this->grp_id_++; 
00752 
00753   for (size_t i = 0; i < n; i++)
00754     {
00755       
00756       
00757       if (this->spawn_i (func,
00758                          args,
00759                          flags,
00760                          0,
00761                          thread_handles == 0 ? 0 : &thread_handles[i],
00762                          priority,
00763                          grp_id,
00764                          stack == 0 ? 0 : stack[i],
00765                          stack_size == 0 ? 0 : stack_size[i],
00766                          task) == -1)
00767         return -1;
00768     }
00769 
00770   return grp_id;
00771 }
00772 
00773 
00774 
00775 int
00776 ACE_Thread_Manager::spawn_n (ACE_thread_t thread_ids[],
00777                              size_t n,
00778                              ACE_THR_FUNC func,
00779                              void *args,
00780                              long flags,
00781                              long priority,
00782                              int grp_id,
00783                              void *stack[],
00784                              size_t stack_size[],
00785                              ACE_hthread_t thread_handles[],
00786                              ACE_Task_Base *task)
00787 {
00788   ACE_TRACE ("ACE_Thread_Manager::spawn_n");
00789   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00790 
00791   if (grp_id == -1)
00792     grp_id = this->grp_id_++; 
00793 
00794   for (size_t i = 0; i < n; i++)
00795     {
00796       
00797       
00798       if (this->spawn_i (func,
00799                          args,
00800                          flags,
00801                          thread_ids == 0 ? 0 : &thread_ids[i],
00802                          thread_handles == 0 ? 0 : &thread_handles[i],
00803                          priority,
00804                          grp_id,
00805                          stack == 0 ? 0 : stack[i],
00806                          stack_size == 0 ? 0 : stack_size[i],
00807                          task) == -1)
00808         return -1;
00809     }
00810 
00811   return grp_id;
00812 }
00813 
00814 
00815 
00816 
00817 int
00818 ACE_Thread_Manager::append_thr (ACE_thread_t t_id,
00819                                 ACE_hthread_t t_handle,
00820                                 ACE_UINT32 thr_state,
00821                                 int grp_id,
00822                                 ACE_Task_Base *task,
00823                                 long flags,
00824                                 ACE_Thread_Descriptor *td)
00825 {
00826   ACE_TRACE ("ACE_Thread_Manager::append_thr");
00827   ACE_Thread_Descriptor *thr_desc = 0;
00828 
00829   if (td == 0)
00830     {
00831     ACE_NEW_RETURN (thr_desc,
00832                     ACE_Thread_Descriptor,
00833                     -1);
00834 #if !defined(ACE_USE_ONE_SHOT_AT_THREAD_EXIT)
00835     thr_desc->tm_ = this;
00836     
00837 #endif 
00838   }
00839   else
00840     thr_desc = td;
00841 
00842   thr_desc->thr_id_ = t_id;
00843   thr_desc->thr_handle_ = t_handle;
00844   thr_desc->grp_id_ = grp_id;
00845   thr_desc->task_ = task;
00846   thr_desc->flags_ = flags;
00847 
00848   this->thr_list_.insert_head (thr_desc);
00849   ACE_SET_BITS (thr_desc->thr_state_, thr_state);
00850   thr_desc->sync_->release ();
00851 
00852   return 0;
00853 }
00854 
00855 
00856 
00857 ACE_Thread_Descriptor *
00858 ACE_Thread_Manager::find_hthread (ACE_hthread_t h_id)
00859 {
00860   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
00861        !iter.done ();
00862        iter.advance ())
00863     if (ACE_OS::thr_cmp (iter.next ()->thr_handle_, h_id))
00864       return iter.next ();
00865 
00866   return 0;
00867 }
00868 
00869 
00870 
00871 
00872 ACE_Thread_Descriptor *
00873 ACE_Thread_Manager::find_thread (ACE_thread_t t_id)
00874 {
00875   ACE_TRACE ("ACE_Thread_Manager::find_thread");
00876 
00877   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
00878        !iter.done ();
00879        iter.advance ())
00880     if (ACE_OS::thr_equal (iter.next ()->thr_id_, t_id))
00881       return iter.next ();
00882   return 0;
00883 }
00884 
00885 
00886 
00887 
00888 int
00889 ACE_Thread_Manager::insert_thr (ACE_thread_t t_id,
00890                                 ACE_hthread_t t_handle,
00891                                 int grp_id,
00892                                 long flags)
00893 {
00894   ACE_TRACE ("ACE_Thread_Manager::insert_thr");
00895   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00896 
00897   
00898 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
00899   if (this->find_hthread (t_handle) != 0 )
00900     return -1;
00901 #else  
00902   if (this->find_thread (t_id) != 0 )
00903     return -1;
00904 #endif 
00905 
00906   if (grp_id == -1)
00907     grp_id = this->grp_id_++;
00908 
00909   if (this->append_thr (t_id,
00910                         t_handle,
00911                         ACE_THR_SPAWNED,
00912                         grp_id,
00913                         0,
00914                         flags) == -1)
00915     return -1;
00916 
00917   return grp_id;
00918 }
00919 
00920 
00921 
00922 void
00923 ACE_Thread_Manager::run_thread_exit_hooks (int i)
00924 {
00925 #if 0 // currently unused!
00926   ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks");
00927 
00928   
00929   
00930 
00931   ACE_Thread_Descriptor *td = this->thread_desc_self ();
00932   if (td != 0 && td->cleanup_info.cleanup_hook_ != 0)
00933     {
00934       (*td->cleanup_info_.cleanup_hook_)
00935         (td->cleanup_info_.object_,
00936          td->cleanup_info_.param_);
00937 
00938       td->cleanup_info_.cleanup_hook_ = 0;
00939     }
00940   ACE_UNUSED_ARG (i);
00941 #else
00942   ACE_UNUSED_ARG (i);
00943 #endif 
00944 }
00945 
00946 
00947 
00948 void
00949 ACE_Thread_Manager::remove_thr (ACE_Thread_Descriptor *td,
00950                                 int close_handler)
00951 {
00952   ACE_TRACE ("ACE_Thread_Manager::remove_thr");
00953 
00954 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
00955   ACE_thread_t tid = td->self ();
00956 #endif 
00957 
00958 #if !defined(ACE_USE_ONE_SHOT_AT_THREAD_EXIT)
00959   td->tm_ = 0;
00960 #endif 
00961   this->thr_list_.remove (td);
00962 
00963 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
00964   
00965   if (tid  &&  tid[0] == ACE_THR_ID_ALLOCATED)
00966     {
00967       delete [] tid;
00968     }
00969 #endif 
00970 
00971 #if defined (ACE_WIN32)
00972   if (close_handler != 0)
00973     ::CloseHandle (td->thr_handle_);
00974 #else
00975   ACE_UNUSED_ARG (close_handler);
00976 #endif 
00977 
00978   this->thread_desc_freelist_.add (td);
00979 
00980 #if defined (ACE_HAS_THREADS)
00981   
00982   if (this->thr_list_.size () == 0)
00983     this->zero_cond_.broadcast ();
00984 #endif 
00985 }
00986 
00987 
00988 
00989 void
00990 ACE_Thread_Manager::remove_thr_all (void)
00991 {
00992   ACE_Thread_Descriptor *td = 0;
00993 
00994   while ((td = this->thr_list_.delete_head ()) != 0)
00995     {
00996       this->remove_thr (td, 1);
00997     }
00998 }
00999 
01000 
01001 
01002 #define ACE_THR_OP(OP,STATE) \
01003   int result = OP (td->thr_handle_); \
01004   if (result == -1) { \
01005     if (errno != ENOTSUP) \
01006       this->thr_to_be_removed_.enqueue_tail (td); \
01007     return -1; \
01008   } \
01009   else { \
01010     ACE_SET_BITS (td->thr_state_, STATE); \
01011     return 0; \
01012   }
01013 
01014 int
01015 ACE_Thread_Manager::join_thr (ACE_Thread_Descriptor *td, int)
01016 {
01017   ACE_TRACE ("ACE_Thread_Manager::join_thr");
01018   int result = ACE_Thread::join (td->thr_handle_);
01019   if (result != 0)
01020     {
01021       
01022       
01023 
01024       
01025       errno = result;
01026       return -1;
01027     }
01028 
01029   return 0;
01030 }
01031 
01032 int
01033 ACE_Thread_Manager::suspend_thr (ACE_Thread_Descriptor *td, int)
01034 {
01035   ACE_TRACE ("ACE_Thread_Manager::suspend_thr");
01036 
01037   int const result = ACE_Thread::suspend (td->thr_handle_);
01038   if (result == -1) {
01039     if (errno != ENOTSUP)
01040       this->thr_to_be_removed_.enqueue_tail (td);
01041     return -1;
01042   }
01043   else {
01044     ACE_SET_BITS (td->thr_state_, ACE_THR_SUSPENDED);
01045     return 0;
01046   }
01047 }
01048 
01049 int
01050 ACE_Thread_Manager::resume_thr (ACE_Thread_Descriptor *td, int)
01051 {
01052   ACE_TRACE ("ACE_Thread_Manager::resume_thr");
01053 
01054   int const result = ACE_Thread::resume (td->thr_handle_);
01055   if (result == -1) {
01056     if (errno != ENOTSUP)
01057       this->thr_to_be_removed_.enqueue_tail (td);
01058     return -1;
01059   }
01060   else {
01061     ACE_CLR_BITS (td->thr_state_, ACE_THR_SUSPENDED);
01062     return 0;
01063   }
01064 }
01065 
01066 int
01067 ACE_Thread_Manager::cancel_thr (ACE_Thread_Descriptor *td, int async_cancel)
01068 {
01069   ACE_TRACE ("ACE_Thread_Manager::cancel_thr");
01070   
01071   ACE_SET_BITS (td->thr_state_, ACE_THR_CANCELLED);
01072 
01073   if (async_cancel != 0)
01074     
01075     
01076     
01077     return ACE_Thread::cancel (td->thr_id_);
01078 
01079   return 0;
01080 }
01081 
01082 int
01083 ACE_Thread_Manager::kill_thr (ACE_Thread_Descriptor *td, int signum)
01084 {
01085   ACE_TRACE ("ACE_Thread_Manager::kill_thr");
01086 
01087   ACE_thread_t tid = td->thr_id_;
01088 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
01089   
01090   tid += tid[0] == ACE_THR_ID_ALLOCATED  ?  1  :  0;
01091 #endif 
01092 
01093   int const result = ACE_Thread::kill (tid, signum);
01094 
01095   if (result != 0)
01096     {
01097       
01098       if (errno != ENOTSUP)
01099         this->thr_to_be_removed_.enqueue_tail (td);
01100 
01101       return -1;
01102     }
01103 
01104     return 0;
01105 }
01106 
01107 
01108 
01109 #define ACE_EXECUTE_OP(OP, ARG) \
01110   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); \
01111   ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); \
01112   ACE_FIND (this->find_thread (t_id), ptr); \
01113   if (ptr == 0) \
01114     { \
01115       errno = ENOENT; \
01116       return -1; \
01117     } \
01118   int result = OP (ptr, ARG); \
01119   ACE_Errno_Guard error (errno); \
01120   while (! this->thr_to_be_removed_.is_empty ()) { \
01121     ACE_Thread_Descriptor * td = 0; \
01122     this->thr_to_be_removed_.dequeue_head (td); \
01123     this->remove_thr (td, 1); \
01124   } \
01125   return result
01126 
01127 
01128 
01129 int
01130 ACE_Thread_Manager::suspend (ACE_thread_t t_id)
01131 {
01132   ACE_TRACE ("ACE_Thread_Manager::suspend");
01133   ACE_EXECUTE_OP (this->suspend_thr, 0);
01134 }
01135 
01136 
01137 
01138 int
01139 ACE_Thread_Manager::resume (ACE_thread_t t_id)
01140 {
01141   ACE_TRACE ("ACE_Thread_Manager::resume");
01142   ACE_EXECUTE_OP (this->resume_thr, 0);
01143 }
01144 
01145 
01146 
01147 int
01148 ACE_Thread_Manager::cancel (ACE_thread_t t_id, int async_cancel)
01149 {
01150   ACE_TRACE ("ACE_Thread_Manager::cancel");
01151   ACE_EXECUTE_OP (this->cancel_thr, async_cancel);
01152 }
01153 
01154 
01155 
01156 int
01157 ACE_Thread_Manager::kill (ACE_thread_t t_id, int signum)
01158 {
01159   ACE_TRACE ("ACE_Thread_Manager::kill");
01160   ACE_EXECUTE_OP (this->kill_thr, signum);
01161 }
01162 
01163 int
01164 ACE_Thread_Manager::check_state (ACE_UINT32 state,
01165                                  ACE_thread_t id,
01166                                  int enable)
01167 {
01168   ACE_TRACE ("ACE_Thread_Manager::check_state");
01169   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01170 
01171   ACE_UINT32 thr_state;
01172 
01173   int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ());
01174 
01175   
01176   
01177   if (self_check)
01178     {
01179       ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc ();
01180       if (desc == 0)
01181         return 0;               
01182       thr_state = desc->thr_state_;
01183     }
01184   else
01185     {
01186       
01187       ACE_FIND (this->find_thread (id), ptr);
01188       if (ptr == 0)
01189         return 0;
01190       thr_state = ptr->thr_state_;
01191     }
01192   if (enable)
01193     return ACE_BIT_ENABLED (thr_state, state);
01194 
01195   return ACE_BIT_DISABLED (thr_state, state);
01196 }
01197 
01198 
01199 
01200 int
01201 ACE_Thread_Manager::testterminate (ACE_thread_t t_id)
01202 {
01203   ACE_TRACE ("ACE_Thread_Manager::testterminate");
01204   return this->check_state (ACE_THR_TERMINATED, t_id);
01205 }
01206 
01207 
01208 
01209 int
01210 ACE_Thread_Manager::testsuspend (ACE_thread_t t_id)
01211 {
01212   ACE_TRACE ("ACE_Thread_Manager::testsuspend");
01213   return this->check_state (ACE_THR_SUSPENDED, t_id);
01214 }
01215 
01216 
01217 
01218 int
01219 ACE_Thread_Manager::testresume (ACE_thread_t t_id)
01220 {
01221   ACE_TRACE ("ACE_Thread_Manager::testresume");
01222   return this->check_state (ACE_THR_SUSPENDED, t_id, 0);
01223 }
01224 
01225 
01226 
01227 int
01228 ACE_Thread_Manager::testcancel (ACE_thread_t t_id)
01229 {
01230   ACE_TRACE ("ACE_Thread_Manager::testcancel");
01231   return this->check_state (ACE_THR_CANCELLED, t_id);
01232 }
01233 
01234 
01235 
01236 int
01237 ACE_Thread_Manager::hthread_within (ACE_hthread_t handle)
01238 {
01239   ACE_TRACE ("ACE_Thread_Manager::hthread_within");
01240   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01241 
01242   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01243        !iter.done ();
01244        iter.advance ())
01245     if (ACE_OS::thr_cmp(iter.next ()->thr_handle_, handle))
01246       return 1;
01247 
01248   return 0;
01249 }
01250 
01251 int
01252 ACE_Thread_Manager::thread_within (ACE_thread_t tid)
01253 {
01254   ACE_TRACE ("ACE_Thread_Manager::thread_within");
01255   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01256 
01257   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01258        !iter.done ();
01259        iter.advance ())
01260     if (ACE_OS::thr_equal (iter.next ()->thr_id_, tid))
01261       return 1;
01262 
01263   return 0;
01264 }
01265 
01266 
01267 
01268 int
01269 ACE_Thread_Manager::get_grp (ACE_thread_t t_id, int &grp_id)
01270 {
01271   ACE_TRACE ("ACE_Thread_Manager::get_grp");
01272   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01273 
01274   ACE_FIND (this->find_thread (t_id), ptr);
01275 
01276   if (ptr)
01277     grp_id = ptr->grp_id_;
01278   else
01279     return -1;
01280   return 0;
01281 }
01282 
01283 
01284 
01285 int
01286 ACE_Thread_Manager::set_grp (ACE_thread_t t_id, int grp_id)
01287 {
01288   ACE_TRACE ("ACE_Thread_Manager::set_grp");
01289   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01290 
01291   ACE_FIND (this->find_thread (t_id), ptr);
01292   if (ptr)
01293     ptr->grp_id_ = grp_id;
01294   else
01295     return -1;
01296   return 0;
01297 }
01298 
01299 
01300 
01301 int
01302 ACE_Thread_Manager::apply_grp (int grp_id,
01303                                ACE_THR_MEMBER_FUNC func,
01304                                int arg)
01305 {
01306   ACE_TRACE ("ACE_Thread_Manager::apply_grp");
01307   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01308   ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01309 
01310   int result = 0;
01311 
01312   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01313        !iter.done ();
01314        iter.advance ())
01315     if (iter.next ()->grp_id_ == grp_id)
01316       if ((this->*func) (iter.next (), arg) == -1)
01317         result = -1;
01318 
01319   
01320   
01321 
01322   if (! this->thr_to_be_removed_.is_empty ())
01323     {
01324       
01325       ACE_Errno_Guard error (errno);
01326 
01327       for (ACE_Thread_Descriptor *td;
01328            this->thr_to_be_removed_.dequeue_head (td) != -1;
01329            )
01330         this->remove_thr (td, 1);
01331     }
01332 
01333   return result;
01334 }
01335 
01336 int
01337 ACE_Thread_Manager::suspend_grp (int grp_id)
01338 {
01339   ACE_TRACE ("ACE_Thread_Manager::suspend_grp");
01340   return this->apply_grp (grp_id,
01341                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01342 }
01343 
01344 
01345 
01346 int
01347 ACE_Thread_Manager::resume_grp (int grp_id)
01348 {
01349   ACE_TRACE ("ACE_Thread_Manager::resume_grp");
01350   return this->apply_grp (grp_id,
01351                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01352 }
01353 
01354 
01355 
01356 int
01357 ACE_Thread_Manager::kill_grp (int grp_id, int signum)
01358 {
01359   ACE_TRACE ("ACE_Thread_Manager::kill_grp");
01360   return this->apply_grp (grp_id,
01361                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr), signum);
01362 }
01363 
01364 
01365 
01366 int
01367 ACE_Thread_Manager::cancel_grp (int grp_id, int async_cancel)
01368 {
01369   ACE_TRACE ("ACE_Thread_Manager::cancel_grp");
01370   return this->apply_grp (grp_id,
01371                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01372                           async_cancel);
01373 }
01374 
01375 int
01376 ACE_Thread_Manager::apply_all (ACE_THR_MEMBER_FUNC func, int arg)
01377 {
01378   ACE_TRACE ("ACE_Thread_Manager::apply_all");
01379   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01380   ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01381 
01382   int result = 0;
01383 
01384   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01385        !iter.done ();
01386        iter.advance ())
01387     if ((this->*func)(iter.next (), arg) == -1)
01388       result = -1;
01389 
01390   
01391   
01392 
01393   if (! this->thr_to_be_removed_.is_empty ())
01394     {
01395       
01396       ACE_Errno_Guard error (errno);
01397 
01398       for (ACE_Thread_Descriptor *td;
01399            this->thr_to_be_removed_.dequeue_head (td) != -1;
01400            )
01401         this->remove_thr (td, 1);
01402     }
01403 
01404   return result;
01405 }
01406 
01407 
01408 
01409 int
01410 ACE_Thread_Manager::resume_all (void)
01411 {
01412   ACE_TRACE ("ACE_Thread_Manager::resume_all");
01413   return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01414 }
01415 
01416 int
01417 ACE_Thread_Manager::suspend_all (void)
01418 {
01419   ACE_TRACE ("ACE_Thread_Manager::suspend_all");
01420   return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01421 }
01422 
01423 int
01424 ACE_Thread_Manager::kill_all (int sig)
01425 {
01426   ACE_TRACE ("ACE_Thread_Manager::kill_all");
01427   return this->apply_all (&ACE_Thread_Manager::kill_thr, sig);
01428 }
01429 
01430 int
01431 ACE_Thread_Manager::cancel_all (int async_cancel)
01432 {
01433   ACE_TRACE ("ACE_Thread_Manager::cancel_all");
01434   return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01435                           async_cancel);
01436 }
01437 
01438 int
01439 ACE_Thread_Manager::join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status)
01440 {
01441   ACE_TRACE ("ACE_Thread_Manager::join");
01442 
01443   ACE_Thread_Descriptor_Base tdb;
01444   int found = 0;
01445 
01446   {
01447     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01448 
01449 #if !defined (ACE_VXWORKS)
01450     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_);
01451          !biter.done ();
01452          biter.advance ())
01453       if (ACE_OS::thr_equal (biter.next ()->thr_id_, tid))
01454         {
01455           ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (0);
01456 # if defined (_AIX)
01457   
01458   
01459   
01460   
01461 
01462   
01463   
01464           if (ACE_Thread::join (tdb->thr_handle_,
01465                                 &tdb->thr_handle_,
01466                                 status) == -1)
01467 # else  
01468           if (ACE_Thread::join (tdb->thr_handle_, status) == -1)
01469 # endif 
01470             return -1;
01471 
01472 # if defined (ACE_HAS_PTHREADS_DRAFT4)  &&  defined (ACE_LACKS_SETDETACH)
01473           
01474           
01475           ::pthread_detach (&tdb->thr_handle_);
01476 # endif 
01477 
01478           delete tdb;
01479           return 0;
01480           
01481         }
01482 #endif 
01483 
01484     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01485          !iter.done ();
01486          iter.advance ())
01487       
01488       
01489       if (ACE_OS::thr_equal (iter.next ()->thr_id_,tid) &&
01490           (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON)
01491            || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE)))
01492         {
01493           tdb = *iter.next ();
01494           ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01495           found = 1;
01496           break;
01497         }
01498 
01499     if (found == 0)
01500       return -1;
01501     
01502   }
01503 
01504 # if defined (_AIX)
01505   
01506   
01507   
01508   
01509 
01510   
01511   
01512   if (ACE_Thread::join (tdb.thr_handle_, &tdb.thr_handle_, status) == -1)
01513 # else  
01514   if (ACE_Thread::join (tdb.thr_handle_, status) == -1)
01515 # endif 
01516     return -1;
01517 
01518 # if defined (ACE_HAS_PTHREADS_DRAFT4)  &&  defined (ACE_LACKS_SETDETACH)
01519   
01520   
01521 
01522   ::pthread_detach (&tdb.thr_handle_);
01523 # endif 
01524   return 0;
01525 }
01526 
01527 
01528 
01529 int
01530 ACE_Thread_Manager::wait_grp (int grp_id)
01531 {
01532   ACE_TRACE ("ACE_Thread_Manager::wait_grp");
01533 
01534   int copy_count = 0;
01535   ACE_Thread_Descriptor_Base *copy_table = 0;
01536 
01537   
01538   
01539   
01540   {
01541     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01542 
01543 #if !defined (ACE_VXWORKS)
01544     ACE_NEW_RETURN (copy_table,
01545                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()
01546                                                + this->terminated_thr_list_.size ()],
01547                     -1);
01548 #else
01549     ACE_NEW_RETURN (copy_table,
01550                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()],
01551                     -1);
01552 #endif 
01553 
01554     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01555          !iter.done ();
01556          iter.advance ())
01557       
01558       
01559       if (iter.next ()->grp_id_ == grp_id &&
01560           (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON)
01561            || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE)))
01562         {
01563           ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01564           copy_table[copy_count++] = *iter.next ();
01565         }
01566 
01567 #if !defined (ACE_VXWORKS)
01568     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_);
01569          !biter.done ();
01570          biter.advance ())
01571       
01572       
01573       if (biter.next ()->grp_id_ == grp_id)
01574         {
01575           ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (0);
01576           copy_table[copy_count++] = *tdb;
01577           delete tdb;
01578         }
01579 #endif 
01580   }
01581 
01582   
01583   int result = 0;
01584 
01585   for (int i = 0;
01586        i < copy_count && result != -1;
01587        i++)
01588     {
01589       if (ACE_Thread::join (copy_table[i].thr_handle_) == -1)
01590         result = -1;
01591 
01592 # if defined (ACE_HAS_PTHREADS_DRAFT4)  &&  defined (ACE_LACKS_SETDETACH)
01593       
01594       
01595       ::pthread_detach (©_table[i].thr_handle_);
01596 # endif 
01597     }
01598 
01599   delete [] copy_table;
01600 
01601   return result;
01602 }
01603 
01604 
01605 
01606 
01607 ACE_THR_FUNC_RETURN
01608 ACE_Thread_Manager::exit (ACE_THR_FUNC_RETURN status, int do_thr_exit)
01609 {
01610   ACE_TRACE ("ACE_Thread_Manager::exit");
01611 #if defined(ACE_USE_ONE_SHOT_AT_THREAD_EXIT)
01612   int close_handle = 0;
01613 #endif 
01614 
01615 #if defined (ACE_WIN32)
01616   
01617 
01618   if (do_thr_exit)
01619     {
01620 #if 0
01621       
01622       
01623 
01624       
01625       
01626       
01627       
01628       
01629       
01630       delete ACE_Thread_Exit::instance ();
01631 #endif 
01632       ACE_Thread::exit (status);
01633     }
01634 #endif 
01635 
01636 #if defined(ACE_USE_ONE_SHOT_AT_THREAD_EXIT)
01637   ACE_Cleanup_Info cleanup_info;
01638 
01639   
01640   
01641   {
01642     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
01643 
01644     
01645     
01646 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
01647     ACE_hthread_t id;
01648     ACE_OS::thr_self (id);
01649     ACE_Thread_Descriptor *td = this->find_hthread (id);
01650 #else  
01651     ACE_thread_t id = ACE_OS::thr_self ();
01652     ACE_Thread_Descriptor *td = this->find_thread (id);
01653 #endif 
01654 
01655     
01656     if (td != 0)
01657       {
01658         
01659         
01660 
01661         if (td->cleanup_info_.cleanup_hook_ != 0)
01662           {
01663             
01664             
01665             cleanup_info = td->cleanup_info_;
01666             td->cleanup_info_.cleanup_hook_ = 0;
01667           }
01668 
01669 #if !defined (ACE_VXWORKS)
01670         
01671         
01672 
01673         if (ACE_BIT_DISABLED (td->thr_state_, ACE_THR_JOINING))
01674           if (ACE_BIT_DISABLED (td->flags_, THR_DETACHED | THR_DAEMON)
01675               || ACE_BIT_ENABLED (td->flags_, THR_JOINABLE))
01676             {
01677               
01678               ACE_SET_BITS (td->thr_state_, ACE_THR_TERMINATED);
01679               this->register_as_terminated (td);
01680               
01681             }
01682 #if defined (ACE_WIN32)
01683           else
01684             {
01685               close_handle = 1;
01686             }
01687 #endif 
01688 #endif 
01689 
01690         
01691         this->remove_thr (td, close_handle);
01692       }
01693     
01694   }
01695 
01696   
01697   if (cleanup_info.cleanup_hook_ != 0)
01698     (*cleanup_info.cleanup_hook_) (cleanup_info.object_,
01699                                    cleanup_info.param_);
01700 #else 
01701   
01702   {
01703     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
01704 
01705     
01706     
01707 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
01708     ACE_hthread_t id;
01709     ACE_OS::thr_self (id);
01710     ACE_Thread_Descriptor* td = this->find_hthread (id);
01711 #else  
01712     ACE_thread_t id = ACE_OS::thr_self ();
01713     ACE_Thread_Descriptor* td = this->find_thread (id);
01714 #endif 
01715     if (td != 0)
01716      {
01717        
01718        
01719        td->terminate();
01720      }
01721   }
01722 
01723 
01724 #endif 
01725 
01726   if (do_thr_exit)
01727     {
01728       ACE_Thread::exit (status);
01729       
01730       
01731       
01732     }
01733 
01734   return 0;
01735 }
01736 
01737 
01738 
01739 int
01740 ACE_Thread_Manager::wait (const ACE_Time_Value *timeout,
01741                           bool abandon_detached_threads,
01742                           bool use_absolute_time)
01743 {
01744   ACE_TRACE ("ACE_Thread_Manager::wait");
01745 
01746   ACE_Time_Value local_timeout;
01747   
01748   if (use_absolute_time == false && timeout != 0)
01749     {
01750       local_timeout = *timeout;
01751       local_timeout += ACE_OS::gettimeofday ();
01752       timeout = &local_timeout;
01753     }
01754 
01755 #if !defined (ACE_VXWORKS)
01756   ACE_Double_Linked_List<ACE_Thread_Descriptor_Base> term_thr_list_copy;
01757 #endif 
01758 
01759 #if defined (ACE_HAS_THREADS)
01760   {
01761     
01762     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01763 
01764     if (ACE_Object_Manager::shutting_down () != 1)
01765       {
01766         
01767         if (abandon_detached_threads != 0)
01768           {
01769             ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01770             for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor>
01771                    iter (this->thr_list_);
01772                  !iter.done ();
01773                  iter.advance ())
01774               if (ACE_BIT_ENABLED (iter.next ()->flags_,
01775                                    THR_DETACHED | THR_DAEMON)
01776                   && ACE_BIT_DISABLED (iter.next ()->flags_, THR_JOINABLE))
01777                 {
01778                   this->thr_to_be_removed_.enqueue_tail (iter.next ());
01779                   ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01780                 }
01781 
01782             if (! this->thr_to_be_removed_.is_empty ())
01783               {
01784                 ACE_Thread_Descriptor *td;
01785                 while (this->thr_to_be_removed_.dequeue_head (td) != -1)
01786                   this->remove_thr (td, 1);
01787               }
01788           }
01789 
01790         while (this->thr_list_.size () > 0)
01791           if (this->zero_cond_.wait (timeout) == -1)
01792             return -1;
01793       }
01794     else
01795         
01796         
01797         this->remove_thr_all ();
01798 
01799 #if !defined (ACE_VXWORKS)
01800   ACE_Thread_Descriptor_Base* item = 0;
01801   while ((item = this->terminated_thr_list_.delete_head ()) != 0)
01802     {
01803       term_thr_list_copy.insert_tail (item);
01804     }
01805 #endif 
01806     
01807   }
01808 
01809 #if !defined (ACE_VXWORKS)
01810     
01811     
01812     ACE_Thread_Descriptor_Base *item = 0;
01813 
01814     while ((item = term_thr_list_copy.delete_head ()) != 0)
01815       {
01816         if (ACE_BIT_DISABLED (item->flags_, THR_DETACHED | THR_DAEMON)
01817             || ACE_BIT_ENABLED (item->flags_, THR_JOINABLE))
01818           
01819           ACE_Thread::join (item->thr_handle_);
01820 
01821 # if defined (ACE_HAS_PTHREADS_DRAFT4)  &&  defined (ACE_LACKS_SETDETACH)
01822         
01823         
01824         ::pthread_detach (&item->thr_handle_);
01825 # endif 
01826         delete item;
01827       }
01828 
01829 #endif 
01830 #else
01831   ACE_UNUSED_ARG (timeout);
01832   ACE_UNUSED_ARG (abandon_detached_threads);
01833 #endif 
01834 
01835   return 0;
01836 }
01837 
01838 int
01839 ACE_Thread_Manager::apply_task (ACE_Task_Base *task,
01840                                 ACE_THR_MEMBER_FUNC func,
01841                                 int arg)
01842 {
01843   ACE_TRACE ("ACE_Thread_Manager::apply_task");
01844   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01845   ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01846 
01847   int result = 0;
01848 
01849   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01850        !iter.done ();
01851        iter.advance ())
01852     if (iter.next ()->task_ == task
01853         && (this->*func) (iter.next (), arg) == -1)
01854       result = -1;
01855 
01856   
01857   
01858 
01859   if (! this->thr_to_be_removed_.is_empty ())
01860     {
01861       
01862       ACE_Errno_Guard error (errno);
01863 
01864       for (ACE_Thread_Descriptor *td;
01865            this->thr_to_be_removed_.dequeue_head (td) != -1;
01866            )
01867         this->remove_thr (td, 1);
01868     }
01869 
01870   return result;
01871 }
01872 
01873 
01874 
01875 int
01876 ACE_Thread_Manager::wait_task (ACE_Task_Base *task)
01877 {
01878   int copy_count = 0;
01879   ACE_Thread_Descriptor_Base *copy_table = 0;
01880 
01881   
01882   
01883   
01884   {
01885     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01886 
01887 #if !defined (ACE_VXWORKS)
01888     ACE_NEW_RETURN (copy_table,
01889                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()
01890                                                 + this->terminated_thr_list_.size ()],
01891                     -1);
01892 #else
01893     ACE_NEW_RETURN (copy_table,
01894                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()],
01895                     -1);
01896 #endif 
01897 
01898     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01899          !iter.done ();
01900          iter.advance ())
01901       
01902       
01903       if (iter.next ()->task_ == task &&
01904           (ACE_BIT_DISABLED (iter.next ()->flags_,
01905                              THR_DETACHED | THR_DAEMON)
01906            || ACE_BIT_ENABLED (iter.next ()->flags_,
01907                                THR_JOINABLE)))
01908         {
01909           ACE_SET_BITS (iter.next ()->thr_state_,
01910                         ACE_THR_JOINING);
01911           copy_table[copy_count++] = *iter.next ();
01912         }
01913 
01914 #if !defined (ACE_VXWORKS)
01915     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> titer (this->terminated_thr_list_);
01916          !titer.done ();
01917          titer.advance ())
01918       
01919       if (titer.next ()->task_ == task)
01920         {
01921           ACE_Thread_Descriptor_Base *tdb =
01922             titer.advance_and_remove (0);
01923           copy_table[copy_count++] = *tdb;
01924           delete tdb;
01925         }
01926 #endif 
01927   }
01928 
01929   
01930   int result = 0;
01931 
01932   for (int i = 0;
01933        i < copy_count && result != -1;
01934        i++)
01935     {
01936       if (ACE_Thread::join (copy_table[i].thr_handle_) == -1)
01937         result = -1;
01938 
01939 # if defined (ACE_HAS_PTHREADS_DRAFT4)  &&  defined (ACE_LACKS_SETDETACH)
01940       
01941       
01942       ::pthread_detach (©_table[i].thr_handle_);
01943 # endif 
01944     }
01945 
01946   delete [] copy_table;
01947 
01948   return result;
01949 }
01950 
01951 
01952 
01953 int
01954 ACE_Thread_Manager::suspend_task (ACE_Task_Base *task)
01955 {
01956   ACE_TRACE ("ACE_Thread_Manager::suspend_task");
01957   return this->apply_task (task,
01958                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01959 }
01960 
01961 
01962 int
01963 ACE_Thread_Manager::resume_task (ACE_Task_Base *task)
01964 {
01965   ACE_TRACE ("ACE_Thread_Manager::resume_task");
01966   return this->apply_task (task,
01967                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01968 }
01969 
01970 
01971 
01972 int
01973 ACE_Thread_Manager::kill_task (ACE_Task_Base *task, int )
01974 {
01975   ACE_TRACE ("ACE_Thread_Manager::kill_task");
01976   return this->apply_task (task,
01977                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr));
01978 }
01979 
01980 
01981 int
01982 ACE_Thread_Manager::cancel_task (ACE_Task_Base *task,
01983                                  int async_cancel)
01984 {
01985   ACE_TRACE ("ACE_Thread_Manager::cancel_task");
01986   return this->apply_task (task,
01987                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01988                            async_cancel);
01989 }
01990 
01991 
01992 
01993 
01994 
01995 ACE_Thread_Descriptor *
01996 ACE_Thread_Manager::find_task (ACE_Task_Base *task, size_t slot)
01997 {
01998   ACE_TRACE ("ACE_Thread_Manager::find_task");
01999 
02000   size_t i = 0;
02001 
02002   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02003        !iter.done ();
02004        iter.advance ())
02005     {
02006       if (i >= slot)
02007         break;
02008 
02009       if (task == iter.next ()->task_)
02010         return iter.next ();
02011 
02012       i++;
02013     }
02014 
02015   return 0;
02016 }
02017 
02018 
02019 
02020 int
02021 ACE_Thread_Manager::num_tasks_in_group (int grp_id)
02022 {
02023   ACE_TRACE ("ACE_Thread_Manager::num_tasks_in_group");
02024   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02025 
02026   int tasks_count = 0;
02027   size_t i = 0;
02028 
02029   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02030        !iter.done ();
02031        iter.advance ())
02032     {
02033       if (iter.next ()->grp_id_ == grp_id
02034           && this->find_task (iter.next ()->task_, i) == 0
02035           && iter.next ()->task_ != 0)
02036         tasks_count++;
02037 
02038       i++;
02039     }
02040   return tasks_count;
02041 }
02042 
02043 
02044 
02045 int
02046 ACE_Thread_Manager::num_threads_in_task (ACE_Task_Base *task)
02047 {
02048   ACE_TRACE ("ACE_Thread_Manager::num_threads_in_task");
02049   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02050 
02051   int threads_count = 0;
02052 
02053   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02054        !iter.done ();
02055        iter.advance ())
02056     if (iter.next ()->task_ == task)
02057       threads_count++;
02058 
02059   return threads_count;
02060 }
02061 
02062 
02063 
02064 ssize_t
02065 ACE_Thread_Manager::task_all_list (ACE_Task_Base *task_list[],
02066                                    size_t n)
02067 {
02068   ACE_TRACE ("ACE_Thread_Manager::task_all_list");
02069   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02070 
02071   size_t task_list_count = 0;
02072 
02073   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02074        !iter.done ();
02075        iter.advance ())
02076     {
02077       if (task_list_count >= n)
02078         break;
02079 
02080       ACE_Task_Base *task_p = iter.next ()->task_;
02081       if (0 != task_p)
02082         {
02083           
02084           
02085           size_t i = 0;
02086           for (; i < task_list_count; ++i)
02087             if (task_list[i] == task_p)
02088               break;
02089           if (i == task_list_count)        
02090             task_list[task_list_count++] = task_p;
02091         }
02092     }
02093 
02094   return task_list_count;
02095 }
02096 
02097 
02098 
02099 ssize_t
02100 ACE_Thread_Manager::thread_all_list (ACE_thread_t thread_list[],
02101                                      size_t n)
02102 {
02103   ACE_TRACE ("ACE_Thread_Manager::thread_all_list");
02104   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02105 
02106   size_t thread_count = 0;
02107 
02108   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02109        !iter.done ();
02110        iter.advance ())
02111     {
02112       if (thread_count >= n)
02113         break;
02114 
02115       thread_list[thread_count] = iter.next ()->thr_id_;
02116       thread_count ++;
02117     }
02118 
02119   return thread_count;
02120 }
02121 
02122 
02123 int
02124 ACE_Thread_Manager::thr_state (ACE_thread_t id,
02125                                ACE_UINT32& state)
02126 {
02127   ACE_TRACE ("ACE_Thread_Manager::thr_state");
02128   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02129 
02130   int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ());
02131 
02132   
02133   
02134   if (self_check)
02135     {
02136       ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc ();
02137       if (desc == 0)
02138         return 0;               
02139       state = desc->thr_state_;
02140     }
02141   else
02142     {
02143       
02144       ACE_FIND (this->find_thread (id), ptr);
02145       if (ptr == 0)
02146         return 0;
02147       state = ptr->thr_state_;
02148     }
02149 
02150   return 1;
02151 }
02152 
02153 
02154 
02155 ssize_t
02156 ACE_Thread_Manager::task_list (int grp_id,
02157                                ACE_Task_Base *task_list[],
02158                                size_t n)
02159 {
02160   ACE_TRACE ("ACE_Thread_Manager::task_list");
02161   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02162 
02163   ACE_Task_Base **task_list_iterator = task_list;
02164   size_t task_list_count = 0;
02165   size_t i = 0;
02166 
02167   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02168        !iter.done ();
02169        iter.advance ())
02170     {
02171       if (task_list_count >= n)
02172         break;
02173 
02174       if (iter.next ()->grp_id_ == grp_id
02175           && this->find_task (iter.next ()->task_, i) == 0)
02176         {
02177           task_list_iterator[task_list_count] = iter.next ()->task_;
02178           task_list_count++;
02179         }
02180 
02181       i++;
02182     }
02183 
02184   return task_list_count;
02185 }
02186 
02187 
02188 
02189 ssize_t
02190 ACE_Thread_Manager::thread_list (ACE_Task_Base *task,
02191                                  ACE_thread_t thread_list[],
02192                                  size_t n)
02193 {
02194   ACE_TRACE ("ACE_Thread_Manager::thread_list");
02195   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02196 
02197   size_t thread_count = 0;
02198 
02199   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02200        !iter.done ();
02201        iter.advance ())
02202     {
02203       if (thread_count >= n)
02204         break;
02205 
02206       if (iter.next ()->task_ == task)
02207         {
02208           thread_list[thread_count] = iter.next ()->thr_id_;
02209           thread_count++;
02210         }
02211     }
02212 
02213   return thread_count;
02214 }
02215 
02216 
02217 
02218 ssize_t
02219 ACE_Thread_Manager::hthread_list (ACE_Task_Base *task,
02220                                   ACE_hthread_t hthread_list[],
02221                                   size_t n)
02222 {
02223   ACE_TRACE ("ACE_Thread_Manager::hthread_list");
02224   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02225 
02226   size_t hthread_count = 0;
02227 
02228   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02229        !iter.done ();
02230        iter.advance ())
02231     {
02232       if (hthread_count >= n)
02233         break;
02234 
02235       if (iter.next ()->task_ == task)
02236         {
02237           hthread_list[hthread_count] = iter.next ()->thr_handle_;
02238           hthread_count++;
02239         }
02240     }
02241 
02242   return hthread_count;
02243 }
02244 
02245 ssize_t
02246 ACE_Thread_Manager::thread_grp_list (int grp_id,
02247                                      ACE_thread_t thread_list[],
02248                                      size_t n)
02249 {
02250   ACE_TRACE ("ACE_Thread_Manager::thread_grp_list");
02251   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02252 
02253   size_t thread_count = 0;
02254 
02255   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02256        !iter.done ();
02257        iter.advance ())
02258     {
02259       if (thread_count >= n)
02260         break;
02261 
02262       if (iter.next ()->grp_id_ == grp_id)
02263         {
02264           thread_list[thread_count] = iter.next ()->thr_id_;
02265           thread_count++;
02266         }
02267     }
02268 
02269   return thread_count;
02270 }
02271 
02272 
02273 
02274 ssize_t
02275 ACE_Thread_Manager::hthread_grp_list (int grp_id,
02276                                       ACE_hthread_t hthread_list[],
02277                                       size_t n)
02278 {
02279   ACE_TRACE ("ACE_Thread_Manager::hthread_grp_list");
02280   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02281 
02282   size_t hthread_count = 0;
02283 
02284   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02285        !iter.done ();
02286        iter.advance ())
02287     {
02288       if (hthread_count >= n)
02289         break;
02290 
02291       if (iter.next ()->grp_id_ == grp_id)
02292         {
02293           hthread_list[hthread_count] = iter.next ()->thr_handle_;
02294           hthread_count++;
02295         }
02296     }
02297 
02298   return hthread_count;
02299 }
02300 
02301 int
02302 ACE_Thread_Manager::set_grp (ACE_Task_Base *task, int grp_id)
02303 {
02304   ACE_TRACE ("ACE_Thread_Manager::set_grp");
02305   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02306 
02307   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02308        !iter.done ();
02309        iter.advance ())
02310     if (iter.next ()->task_ == task)
02311       iter.next ()->grp_id_ = grp_id;
02312 
02313   return 0;
02314 }
02315 
02316 int
02317 ACE_Thread_Manager::get_grp (ACE_Task_Base *task, int &grp_id)
02318 {
02319   ACE_TRACE ("ACE_Thread_Manager::get_grp");
02320   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02321 
02322   ACE_FIND (this->find_task (task), ptr);
02323   grp_id = ptr->grp_id_;
02324   return 0;
02325 }
02326 
02327 ACE_END_VERSIONED_NAMESPACE_DECL