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