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