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