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 79134 2007-07-31 18:23:50Z johnnyw $")
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 int ACE_Thread_Manager::delete_thr_mgr_ = 0;
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, int 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_VXWORKS)
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_ = 1;
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_ = 0;
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_ = 0;
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 {
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 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
00595
00596
00597
00598
00599
00600
00601 if (t_id == 0)
00602 {
00603 ACE_NEW_RETURN (t_id,
00604 char*,
00605 -1);
00606 ACE_NEW_RETURN (*t_id,
00607 char[16],
00608 -1);
00609
00610
00611 (*t_id)[0] = ACE_THR_ID_ALLOCATED;
00612 (*t_id)[1] = '\0';
00613 }
00614 #else
00615 ACE_thread_t thr_id;
00616 if (t_id == 0)
00617 t_id = &thr_id;
00618 #endif
00619
00620 new_thr_desc->sync_->acquire ();
00621
00622
00623
00624
00625 int const result = ACE_Thread::spawn (func,
00626 args,
00627 flags,
00628 t_id,
00629 &thr_handle,
00630 priority,
00631 stack,
00632 stack_size,
00633 thread_args);
00634
00635 if (result != 0)
00636 {
00637
00638
00639
00640 ACE_Errno_Guard guard (errno);
00641 new_thr_desc->sync_->release ();
00642 return -1;
00643 }
00644 auto_thread_args.release ();
00645
00646 #if defined (ACE_HAS_WTHREADS)
00647
00648
00649
00650 if (t_handle != 0)
00651 # if defined (ACE_HAS_WINCE)
00652 *t_handle = thr_handle;
00653 # else
00654 (void) ::DuplicateHandle (::GetCurrentProcess (),
00655 thr_handle,
00656 ::GetCurrentProcess (),
00657 t_handle,
00658 0,
00659 TRUE,
00660 DUPLICATE_SAME_ACCESS);
00661 # endif
00662 #else
00663 if (t_handle != 0)
00664 *t_handle = thr_handle;
00665 #endif
00666
00667
00668
00669
00670 return this->append_thr (*t_id,
00671 thr_handle,
00672 ACE_THR_SPAWNED,
00673 grp_id,
00674 task,
00675 flags,
00676 new_thr_desc.release ());
00677 }
00678
00679 int
00680 ACE_Thread_Manager::spawn (ACE_THR_FUNC func,
00681 void *args,
00682 long flags,
00683 ACE_thread_t *t_id,
00684 ACE_hthread_t *t_handle,
00685 long priority,
00686 int grp_id,
00687 void *stack,
00688 size_t stack_size)
00689 {
00690 ACE_TRACE ("ACE_Thread_Manager::spawn");
00691
00692 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00693
00694 if (grp_id == -1)
00695 grp_id = this->grp_id_++;
00696
00697 if (priority != ACE_DEFAULT_THREAD_PRIORITY)
00698 ACE_CLR_BITS (flags, THR_INHERIT_SCHED);
00699
00700 if (this->spawn_i (func,
00701 args,
00702 flags,
00703 t_id,
00704 t_handle,
00705 priority,
00706 grp_id,
00707 stack,
00708 stack_size,
00709 0) == -1)
00710 return -1;
00711
00712 return grp_id;
00713 }
00714
00715
00716
00717 int
00718 ACE_Thread_Manager::spawn_n (size_t n,
00719 ACE_THR_FUNC func,
00720 void *args,
00721 long flags,
00722 long priority,
00723 int grp_id,
00724 ACE_Task_Base *task,
00725 ACE_hthread_t thread_handles[],
00726 void *stack[],
00727 size_t stack_size[])
00728 {
00729 ACE_TRACE ("ACE_Thread_Manager::spawn_n");
00730 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00731
00732 if (grp_id == -1)
00733 grp_id = this->grp_id_++;
00734
00735 for (size_t i = 0; i < n; i++)
00736 {
00737
00738
00739 if (this->spawn_i (func,
00740 args,
00741 flags,
00742 0,
00743 thread_handles == 0 ? 0 : &thread_handles[i],
00744 priority,
00745 grp_id,
00746 stack == 0 ? 0 : stack[i],
00747 stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i],
00748 task) == -1)
00749 return -1;
00750 }
00751
00752 return grp_id;
00753 }
00754
00755
00756
00757 int
00758 ACE_Thread_Manager::spawn_n (ACE_thread_t thread_ids[],
00759 size_t n,
00760 ACE_THR_FUNC func,
00761 void *args,
00762 long flags,
00763 long priority,
00764 int grp_id,
00765 void *stack[],
00766 size_t stack_size[],
00767 ACE_hthread_t thread_handles[],
00768 ACE_Task_Base *task)
00769 {
00770 ACE_TRACE ("ACE_Thread_Manager::spawn_n");
00771 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00772
00773 if (grp_id == -1)
00774 grp_id = this->grp_id_++;
00775
00776 for (size_t i = 0; i < n; i++)
00777 {
00778
00779
00780 if (this->spawn_i (func,
00781 args,
00782 flags,
00783 thread_ids == 0 ? 0 : &thread_ids[i],
00784 thread_handles == 0 ? 0 : &thread_handles[i],
00785 priority,
00786 grp_id,
00787 stack == 0 ? 0 : stack[i],
00788 stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i],
00789 task) == -1)
00790 return -1;
00791 }
00792
00793 return grp_id;
00794 }
00795
00796
00797
00798
00799 int
00800 ACE_Thread_Manager::append_thr (ACE_thread_t t_id,
00801 ACE_hthread_t t_handle,
00802 ACE_UINT32 thr_state,
00803 int grp_id,
00804 ACE_Task_Base *task,
00805 long flags,
00806 ACE_Thread_Descriptor *td)
00807 {
00808 ACE_TRACE ("ACE_Thread_Manager::append_thr");
00809 ACE_Thread_Descriptor *thr_desc = 0;
00810
00811 if (td == 0)
00812 {
00813 ACE_NEW_RETURN (thr_desc,
00814 ACE_Thread_Descriptor,
00815 -1);
00816 thr_desc->tm_ = this;
00817
00818 }
00819 else
00820 thr_desc = td;
00821
00822 thr_desc->thr_id_ = t_id;
00823 thr_desc->thr_handle_ = t_handle;
00824 thr_desc->grp_id_ = grp_id;
00825 thr_desc->task_ = task;
00826 thr_desc->flags_ = flags;
00827
00828 this->thr_list_.insert_head (thr_desc);
00829 ACE_SET_BITS (thr_desc->thr_state_, thr_state);
00830 thr_desc->sync_->release ();
00831
00832 return 0;
00833 }
00834
00835
00836
00837 ACE_Thread_Descriptor *
00838 ACE_Thread_Manager::find_hthread (ACE_hthread_t h_id)
00839 {
00840 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
00841 !iter.done ();
00842 iter.advance ())
00843 if (ACE_OS::thr_cmp (iter.next ()->thr_handle_, h_id))
00844 return iter.next ();
00845
00846 return 0;
00847 }
00848
00849
00850
00851
00852 ACE_Thread_Descriptor *
00853 ACE_Thread_Manager::find_thread (ACE_thread_t t_id)
00854 {
00855 ACE_TRACE ("ACE_Thread_Manager::find_thread");
00856
00857 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
00858 !iter.done ();
00859 iter.advance ())
00860 if (ACE_OS::thr_equal (iter.next ()->thr_id_, t_id))
00861 return iter.next ();
00862 return 0;
00863 }
00864
00865
00866
00867
00868 int
00869 ACE_Thread_Manager::insert_thr (ACE_thread_t t_id,
00870 ACE_hthread_t t_handle,
00871 int grp_id,
00872 long flags)
00873 {
00874 ACE_TRACE ("ACE_Thread_Manager::insert_thr");
00875 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00876
00877
00878 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
00879 if (this->find_hthread (t_handle) != 0 )
00880 return -1;
00881 #else
00882 if (this->find_thread (t_id) != 0 )
00883 return -1;
00884 #endif
00885
00886 if (grp_id == -1)
00887 grp_id = this->grp_id_++;
00888
00889 if (this->append_thr (t_id,
00890 t_handle,
00891 ACE_THR_SPAWNED,
00892 grp_id,
00893 0,
00894 flags) == -1)
00895 return -1;
00896
00897 return grp_id;
00898 }
00899
00900
00901
00902 void
00903 ACE_Thread_Manager::run_thread_exit_hooks (int i)
00904 {
00905 #if 0 // currently unused!
00906 ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks");
00907
00908
00909
00910
00911 ACE_Thread_Descriptor *td = this->thread_desc_self ();
00912 if (td != 0 && td->cleanup_info.cleanup_hook_ != 0)
00913 {
00914 (*td->cleanup_info_.cleanup_hook_)
00915 (td->cleanup_info_.object_,
00916 td->cleanup_info_.param_);
00917
00918 td->cleanup_info_.cleanup_hook_ = 0;
00919 }
00920 ACE_UNUSED_ARG (i);
00921 #else
00922 ACE_UNUSED_ARG (i);
00923 #endif
00924 }
00925
00926
00927
00928 void
00929 ACE_Thread_Manager::remove_thr (ACE_Thread_Descriptor *td,
00930 int close_handler)
00931 {
00932 ACE_TRACE ("ACE_Thread_Manager::remove_thr");
00933
00934 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
00935 ACE_thread_t tid = td->self ();
00936 #endif
00937
00938 td->tm_ = 0;
00939 this->thr_list_.remove (td);
00940
00941 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
00942
00943 if (tid && tid[0] == ACE_THR_ID_ALLOCATED)
00944 {
00945 delete [] tid;
00946 }
00947 #endif
00948
00949 #if defined (ACE_WIN32)
00950 if (close_handler != 0)
00951 ::CloseHandle (td->thr_handle_);
00952 #else
00953 ACE_UNUSED_ARG (close_handler);
00954 #endif
00955
00956 this->thread_desc_freelist_.add (td);
00957
00958 #if defined (ACE_HAS_THREADS)
00959
00960 if (this->thr_list_.size () == 0)
00961 this->zero_cond_.broadcast ();
00962 #endif
00963 }
00964
00965
00966
00967 void
00968 ACE_Thread_Manager::remove_thr_all (void)
00969 {
00970 ACE_Thread_Descriptor *td = 0;
00971
00972 while ((td = this->thr_list_.delete_head ()) != 0)
00973 {
00974 this->remove_thr (td, 1);
00975 }
00976 }
00977
00978
00979
00980 #define ACE_THR_OP(OP,STATE) \
00981 int result = OP (td->thr_handle_); \
00982 if (result == -1) { \
00983 if (errno != ENOTSUP) \
00984 this->thr_to_be_removed_.enqueue_tail (td); \
00985 return -1; \
00986 } \
00987 else { \
00988 ACE_SET_BITS (td->thr_state_, STATE); \
00989 return 0; \
00990 }
00991
00992 int
00993 ACE_Thread_Manager::join_thr (ACE_Thread_Descriptor *td, int)
00994 {
00995 ACE_TRACE ("ACE_Thread_Manager::join_thr");
00996 int const result = ACE_Thread::join (td->thr_handle_);
00997 if (result != 0)
00998 {
00999
01000
01001
01002
01003 errno = result;
01004 return -1;
01005 }
01006
01007 return 0;
01008 }
01009
01010 int
01011 ACE_Thread_Manager::suspend_thr (ACE_Thread_Descriptor *td, int)
01012 {
01013 ACE_TRACE ("ACE_Thread_Manager::suspend_thr");
01014
01015 int const result = ACE_Thread::suspend (td->thr_handle_);
01016 if (result == -1) {
01017 if (errno != ENOTSUP)
01018 this->thr_to_be_removed_.enqueue_tail (td);
01019 return -1;
01020 }
01021 else {
01022 ACE_SET_BITS (td->thr_state_, ACE_THR_SUSPENDED);
01023 return 0;
01024 }
01025 }
01026
01027 int
01028 ACE_Thread_Manager::resume_thr (ACE_Thread_Descriptor *td, int)
01029 {
01030 ACE_TRACE ("ACE_Thread_Manager::resume_thr");
01031
01032 int const result = ACE_Thread::resume (td->thr_handle_);
01033 if (result == -1) {
01034 if (errno != ENOTSUP)
01035 this->thr_to_be_removed_.enqueue_tail (td);
01036 return -1;
01037 }
01038 else {
01039 ACE_CLR_BITS (td->thr_state_, ACE_THR_SUSPENDED);
01040 return 0;
01041 }
01042 }
01043
01044 int
01045 ACE_Thread_Manager::cancel_thr (ACE_Thread_Descriptor *td, int async_cancel)
01046 {
01047 ACE_TRACE ("ACE_Thread_Manager::cancel_thr");
01048
01049 ACE_SET_BITS (td->thr_state_, ACE_THR_CANCELLED);
01050
01051 if (async_cancel != 0)
01052
01053
01054
01055 return ACE_Thread::cancel (td->thr_id_);
01056
01057 return 0;
01058 }
01059
01060 int
01061 ACE_Thread_Manager::kill_thr (ACE_Thread_Descriptor *td, int signum)
01062 {
01063 ACE_TRACE ("ACE_Thread_Manager::kill_thr");
01064
01065 ACE_thread_t tid = td->thr_id_;
01066 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
01067
01068 tid += tid[0] == ACE_THR_ID_ALLOCATED ? 1 : 0;
01069 #endif
01070
01071 int const result = ACE_Thread::kill (tid, signum);
01072
01073 if (result != 0)
01074 {
01075
01076 if (errno != ENOTSUP)
01077 this->thr_to_be_removed_.enqueue_tail (td);
01078
01079 return -1;
01080 }
01081
01082 return 0;
01083 }
01084
01085
01086
01087 #define ACE_EXECUTE_OP(OP, ARG) \
01088 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); \
01089 ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); \
01090 ACE_FIND (this->find_thread (t_id), ptr); \
01091 if (ptr == 0) \
01092 { \
01093 errno = ENOENT; \
01094 return -1; \
01095 } \
01096 int result = OP (ptr, ARG); \
01097 ACE_Errno_Guard error (errno); \
01098 while (! this->thr_to_be_removed_.is_empty ()) { \
01099 ACE_Thread_Descriptor * td = 0; \
01100 this->thr_to_be_removed_.dequeue_head (td); \
01101 this->remove_thr (td, 1); \
01102 } \
01103 return result
01104
01105
01106
01107 int
01108 ACE_Thread_Manager::suspend (ACE_thread_t t_id)
01109 {
01110 ACE_TRACE ("ACE_Thread_Manager::suspend");
01111 ACE_EXECUTE_OP (this->suspend_thr, 0);
01112 }
01113
01114
01115
01116 int
01117 ACE_Thread_Manager::resume (ACE_thread_t t_id)
01118 {
01119 ACE_TRACE ("ACE_Thread_Manager::resume");
01120 ACE_EXECUTE_OP (this->resume_thr, 0);
01121 }
01122
01123
01124
01125 int
01126 ACE_Thread_Manager::cancel (ACE_thread_t t_id, int async_cancel)
01127 {
01128 ACE_TRACE ("ACE_Thread_Manager::cancel");
01129 ACE_EXECUTE_OP (this->cancel_thr, async_cancel);
01130 }
01131
01132
01133
01134 int
01135 ACE_Thread_Manager::kill (ACE_thread_t t_id, int signum)
01136 {
01137 ACE_TRACE ("ACE_Thread_Manager::kill");
01138 ACE_EXECUTE_OP (this->kill_thr, signum);
01139 }
01140
01141 int
01142 ACE_Thread_Manager::check_state (ACE_UINT32 state,
01143 ACE_thread_t id,
01144 int enable)
01145 {
01146 ACE_TRACE ("ACE_Thread_Manager::check_state");
01147 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01148
01149 ACE_UINT32 thr_state;
01150
01151 int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ());
01152
01153
01154
01155 if (self_check)
01156 {
01157 ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc ();
01158 if (desc == 0)
01159 return 0;
01160 thr_state = desc->thr_state_;
01161 }
01162 else
01163 {
01164
01165 ACE_FIND (this->find_thread (id), ptr);
01166 if (ptr == 0)
01167 return 0;
01168 thr_state = ptr->thr_state_;
01169 }
01170 if (enable)
01171 return ACE_BIT_ENABLED (thr_state, state);
01172
01173 return ACE_BIT_DISABLED (thr_state, state);
01174 }
01175
01176
01177
01178 int
01179 ACE_Thread_Manager::testterminate (ACE_thread_t t_id)
01180 {
01181 ACE_TRACE ("ACE_Thread_Manager::testterminate");
01182 return this->check_state (ACE_THR_TERMINATED, t_id);
01183 }
01184
01185
01186
01187 int
01188 ACE_Thread_Manager::testsuspend (ACE_thread_t t_id)
01189 {
01190 ACE_TRACE ("ACE_Thread_Manager::testsuspend");
01191 return this->check_state (ACE_THR_SUSPENDED, t_id);
01192 }
01193
01194
01195
01196 int
01197 ACE_Thread_Manager::testresume (ACE_thread_t t_id)
01198 {
01199 ACE_TRACE ("ACE_Thread_Manager::testresume");
01200 return this->check_state (ACE_THR_SUSPENDED, t_id, 0);
01201 }
01202
01203
01204
01205 int
01206 ACE_Thread_Manager::testcancel (ACE_thread_t t_id)
01207 {
01208 ACE_TRACE ("ACE_Thread_Manager::testcancel");
01209 return this->check_state (ACE_THR_CANCELLED, t_id);
01210 }
01211
01212
01213
01214 int
01215 ACE_Thread_Manager::hthread_within (ACE_hthread_t handle)
01216 {
01217 ACE_TRACE ("ACE_Thread_Manager::hthread_within");
01218 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01219
01220 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01221 !iter.done ();
01222 iter.advance ())
01223 if (ACE_OS::thr_cmp(iter.next ()->thr_handle_, handle))
01224 return 1;
01225
01226 return 0;
01227 }
01228
01229 int
01230 ACE_Thread_Manager::thread_within (ACE_thread_t tid)
01231 {
01232 ACE_TRACE ("ACE_Thread_Manager::thread_within");
01233 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01234
01235 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01236 !iter.done ();
01237 iter.advance ())
01238 if (ACE_OS::thr_equal (iter.next ()->thr_id_, tid))
01239 return 1;
01240
01241 return 0;
01242 }
01243
01244
01245
01246 int
01247 ACE_Thread_Manager::get_grp (ACE_thread_t t_id, int &grp_id)
01248 {
01249 ACE_TRACE ("ACE_Thread_Manager::get_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
01254 if (ptr)
01255 grp_id = ptr->grp_id_;
01256 else
01257 return -1;
01258 return 0;
01259 }
01260
01261
01262
01263 int
01264 ACE_Thread_Manager::set_grp (ACE_thread_t t_id, int grp_id)
01265 {
01266 ACE_TRACE ("ACE_Thread_Manager::set_grp");
01267 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01268
01269 ACE_FIND (this->find_thread (t_id), ptr);
01270 if (ptr)
01271 ptr->grp_id_ = grp_id;
01272 else
01273 return -1;
01274 return 0;
01275 }
01276
01277
01278
01279 int
01280 ACE_Thread_Manager::apply_grp (int grp_id,
01281 ACE_THR_MEMBER_FUNC func,
01282 int arg)
01283 {
01284 ACE_TRACE ("ACE_Thread_Manager::apply_grp");
01285 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01286 ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01287
01288 int result = 0;
01289
01290 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01291 !iter.done ();
01292 iter.advance ())
01293 if (iter.next ()->grp_id_ == grp_id)
01294 if ((this->*func) (iter.next (), arg) == -1)
01295 result = -1;
01296
01297
01298
01299
01300 if (! this->thr_to_be_removed_.is_empty ())
01301 {
01302
01303 ACE_Errno_Guard error (errno);
01304
01305 for (ACE_Thread_Descriptor *td;
01306 this->thr_to_be_removed_.dequeue_head (td) != -1;
01307 )
01308 this->remove_thr (td, 1);
01309 }
01310
01311 return result;
01312 }
01313
01314 int
01315 ACE_Thread_Manager::suspend_grp (int grp_id)
01316 {
01317 ACE_TRACE ("ACE_Thread_Manager::suspend_grp");
01318 return this->apply_grp (grp_id,
01319 ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01320 }
01321
01322
01323
01324 int
01325 ACE_Thread_Manager::resume_grp (int grp_id)
01326 {
01327 ACE_TRACE ("ACE_Thread_Manager::resume_grp");
01328 return this->apply_grp (grp_id,
01329 ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01330 }
01331
01332
01333
01334 int
01335 ACE_Thread_Manager::kill_grp (int grp_id, int signum)
01336 {
01337 ACE_TRACE ("ACE_Thread_Manager::kill_grp");
01338 return this->apply_grp (grp_id,
01339 ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr), signum);
01340 }
01341
01342
01343
01344 int
01345 ACE_Thread_Manager::cancel_grp (int grp_id, int async_cancel)
01346 {
01347 ACE_TRACE ("ACE_Thread_Manager::cancel_grp");
01348 return this->apply_grp (grp_id,
01349 ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01350 async_cancel);
01351 }
01352
01353 int
01354 ACE_Thread_Manager::apply_all (ACE_THR_MEMBER_FUNC func, int arg)
01355 {
01356 ACE_TRACE ("ACE_Thread_Manager::apply_all");
01357 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01358 ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01359
01360 int result = 0;
01361
01362 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01363 !iter.done ();
01364 iter.advance ())
01365 if ((this->*func)(iter.next (), arg) == -1)
01366 result = -1;
01367
01368
01369
01370
01371 if (! this->thr_to_be_removed_.is_empty ())
01372 {
01373
01374 ACE_Errno_Guard error (errno);
01375
01376 for (ACE_Thread_Descriptor *td;
01377 this->thr_to_be_removed_.dequeue_head (td) != -1;
01378 )
01379 this->remove_thr (td, 1);
01380 }
01381
01382 return result;
01383 }
01384
01385
01386
01387 int
01388 ACE_Thread_Manager::resume_all (void)
01389 {
01390 ACE_TRACE ("ACE_Thread_Manager::resume_all");
01391 return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01392 }
01393
01394 int
01395 ACE_Thread_Manager::suspend_all (void)
01396 {
01397 ACE_TRACE ("ACE_Thread_Manager::suspend_all");
01398 return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01399 }
01400
01401 int
01402 ACE_Thread_Manager::kill_all (int sig)
01403 {
01404 ACE_TRACE ("ACE_Thread_Manager::kill_all");
01405 return this->apply_all (&ACE_Thread_Manager::kill_thr, sig);
01406 }
01407
01408 int
01409 ACE_Thread_Manager::cancel_all (int async_cancel)
01410 {
01411 ACE_TRACE ("ACE_Thread_Manager::cancel_all");
01412 return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01413 async_cancel);
01414 }
01415
01416 int
01417 ACE_Thread_Manager::join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status)
01418 {
01419 ACE_TRACE ("ACE_Thread_Manager::join");
01420
01421 ACE_Thread_Descriptor_Base tdb;
01422 int found = 0;
01423
01424 {
01425 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01426
01427 #if !defined (ACE_VXWORKS)
01428 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_);
01429 !biter.done ();
01430 biter.advance ())
01431 if (ACE_OS::thr_equal (biter.next ()->thr_id_, tid))
01432 {
01433 ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (0);
01434 # if defined (_AIX)
01435
01436
01437
01438
01439
01440
01441
01442 if (ACE_Thread::join (tdb->thr_handle_,
01443 &tdb->thr_handle_,
01444 status) == -1)
01445 # else
01446 if (ACE_Thread::join (tdb->thr_handle_, status) == -1)
01447 # endif
01448 return -1;
01449
01450 # if defined (ACE_HAS_PTHREADS_DRAFT4) && defined (ACE_LACKS_SETDETACH)
01451
01452
01453 ::pthread_detach (&tdb->thr_handle_);
01454 # endif
01455
01456 delete tdb;
01457 return 0;
01458
01459 }
01460 #endif
01461
01462 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01463 !iter.done ();
01464 iter.advance ())
01465
01466
01467 if (ACE_OS::thr_equal (iter.next ()->thr_id_,tid) &&
01468 (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON)
01469 || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE)))
01470 {
01471 tdb = *iter.next ();
01472 ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01473 found = 1;
01474 break;
01475 }
01476
01477 if (found == 0)
01478 return -1;
01479
01480 }
01481
01482 # if defined (_AIX)
01483
01484
01485
01486
01487
01488
01489
01490 if (ACE_Thread::join (tdb.thr_handle_, &tdb.thr_handle_, status) == -1)
01491 # else
01492 if (ACE_Thread::join (tdb.thr_handle_, status) == -1)
01493 # endif
01494 return -1;
01495
01496 # if defined (ACE_HAS_PTHREADS_DRAFT4) && defined (ACE_LACKS_SETDETACH)
01497
01498
01499
01500 ::pthread_detach (&tdb.thr_handle_);
01501 # endif
01502 return 0;
01503 }
01504
01505
01506
01507 int
01508 ACE_Thread_Manager::wait_grp (int grp_id)
01509 {
01510 ACE_TRACE ("ACE_Thread_Manager::wait_grp");
01511
01512 int copy_count = 0;
01513 ACE_Thread_Descriptor_Base *copy_table = 0;
01514
01515
01516
01517
01518 {
01519 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01520
01521 #if !defined (ACE_VXWORKS)
01522 ACE_NEW_RETURN (copy_table,
01523 ACE_Thread_Descriptor_Base [this->thr_list_.size ()
01524 + this->terminated_thr_list_.size ()],
01525 -1);
01526 #else
01527 ACE_NEW_RETURN (copy_table,
01528 ACE_Thread_Descriptor_Base [this->thr_list_.size ()],
01529 -1);
01530 #endif
01531
01532 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01533 !iter.done ();
01534 iter.advance ())
01535
01536
01537 if (iter.next ()->grp_id_ == grp_id &&
01538 (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON)
01539 || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE)))
01540 {
01541 ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01542 copy_table[copy_count++] = *iter.next ();
01543 }
01544
01545 #if !defined (ACE_VXWORKS)
01546 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_);
01547 !biter.done ();
01548 biter.advance ())
01549
01550
01551 if (biter.next ()->grp_id_ == grp_id)
01552 {
01553 ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (0);
01554 copy_table[copy_count++] = *tdb;
01555 delete tdb;
01556 }
01557 #endif
01558 }
01559
01560
01561 int result = 0;
01562
01563 for (int i = 0;
01564 i < copy_count && result != -1;
01565 i++)
01566 {
01567 if (ACE_Thread::join (copy_table[i].thr_handle_) == -1)
01568 result = -1;
01569
01570 # if defined (ACE_HAS_PTHREADS_DRAFT4) && defined (ACE_LACKS_SETDETACH)
01571
01572
01573 ::pthread_detach (©_table[i].thr_handle_);
01574 # endif
01575 }
01576
01577 delete [] copy_table;
01578
01579 return result;
01580 }
01581
01582
01583
01584
01585 ACE_THR_FUNC_RETURN
01586 ACE_Thread_Manager::exit (ACE_THR_FUNC_RETURN status, int do_thr_exit)
01587 {
01588 ACE_TRACE ("ACE_Thread_Manager::exit");
01589 #if defined (ACE_WIN32)
01590
01591
01592 if (do_thr_exit)
01593 {
01594 #if 0
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604 delete ACE_Thread_Exit::instance ();
01605 #endif
01606 ACE_Thread::exit (status);
01607 }
01608 #endif
01609
01610
01611 {
01612 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
01613
01614
01615
01616 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
01617 ACE_hthread_t id;
01618 ACE_OS::thr_self (id);
01619 ACE_Thread_Descriptor* td = this->find_hthread (id);
01620 #else
01621 ACE_thread_t id = ACE_OS::thr_self ();
01622 ACE_Thread_Descriptor* td = this->find_thread (id);
01623 #endif
01624 if (td != 0)
01625 {
01626
01627
01628 td->terminate();
01629 }
01630 }
01631
01632 if (do_thr_exit)
01633 {
01634 ACE_Thread::exit (status);
01635
01636
01637
01638 }
01639
01640 return 0;
01641 }
01642
01643
01644
01645 int
01646 ACE_Thread_Manager::wait (const ACE_Time_Value *timeout,
01647 bool abandon_detached_threads,
01648 bool use_absolute_time)
01649 {
01650 ACE_TRACE ("ACE_Thread_Manager::wait");
01651
01652 ACE_Time_Value local_timeout;
01653
01654 if (use_absolute_time == false && timeout != 0)
01655 {
01656 local_timeout = *timeout;
01657 local_timeout += ACE_OS::gettimeofday ();
01658 timeout = &local_timeout;
01659 }
01660
01661 #if !defined (ACE_VXWORKS)
01662 ACE_Double_Linked_List<ACE_Thread_Descriptor_Base> term_thr_list_copy;
01663 #endif
01664
01665 #if defined (ACE_HAS_THREADS)
01666 {
01667
01668 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01669
01670 if (ACE_Object_Manager::shutting_down () != 1)
01671 {
01672
01673 if (abandon_detached_threads != 0)
01674 {
01675 ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01676 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor>
01677 iter (this->thr_list_);
01678 !iter.done ();
01679 iter.advance ())
01680 if (ACE_BIT_ENABLED (iter.next ()->flags_,
01681 THR_DETACHED | THR_DAEMON)
01682 && ACE_BIT_DISABLED (iter.next ()->flags_, THR_JOINABLE))
01683 {
01684 this->thr_to_be_removed_.enqueue_tail (iter.next ());
01685 ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01686 }
01687
01688 if (! this->thr_to_be_removed_.is_empty ())
01689 {
01690 ACE_Thread_Descriptor *td;
01691 while (this->thr_to_be_removed_.dequeue_head (td) != -1)
01692 this->remove_thr (td, 1);
01693 }
01694 }
01695
01696 while (this->thr_list_.size () > 0)
01697 if (this->zero_cond_.wait (timeout) == -1)
01698 return -1;
01699 }
01700 else
01701
01702
01703 this->remove_thr_all ();
01704
01705 #if !defined (ACE_VXWORKS)
01706 ACE_Thread_Descriptor_Base* item = 0;
01707 while ((item = this->terminated_thr_list_.delete_head ()) != 0)
01708 {
01709 term_thr_list_copy.insert_tail (item);
01710 }
01711 #endif
01712
01713 }
01714
01715 #if !defined (ACE_VXWORKS)
01716
01717
01718 ACE_Thread_Descriptor_Base *item = 0;
01719
01720 while ((item = term_thr_list_copy.delete_head ()) != 0)
01721 {
01722 if (ACE_BIT_DISABLED (item->flags_, THR_DETACHED | THR_DAEMON)
01723 || ACE_BIT_ENABLED (item->flags_, THR_JOINABLE))
01724
01725 (void) ACE_Thread::join (item->thr_handle_);
01726
01727 # if defined (ACE_HAS_PTHREADS_DRAFT4) && defined (ACE_LACKS_SETDETACH)
01728
01729
01730 ::pthread_detach (&item->thr_handle_);
01731 # endif
01732 delete item;
01733 }
01734
01735 #endif
01736 #else
01737 ACE_UNUSED_ARG (timeout);
01738 ACE_UNUSED_ARG (abandon_detached_threads);
01739 #endif
01740
01741 return 0;
01742 }
01743
01744 int
01745 ACE_Thread_Manager::apply_task (ACE_Task_Base *task,
01746 ACE_THR_MEMBER_FUNC func,
01747 int arg)
01748 {
01749 ACE_TRACE ("ACE_Thread_Manager::apply_task");
01750 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01751 ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01752
01753 int result = 0;
01754
01755 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01756 !iter.done ();
01757 iter.advance ())
01758 if (iter.next ()->task_ == task
01759 && (this->*func) (iter.next (), arg) == -1)
01760 result = -1;
01761
01762
01763
01764
01765 if (! this->thr_to_be_removed_.is_empty ())
01766 {
01767
01768 ACE_Errno_Guard error (errno);
01769
01770 for (ACE_Thread_Descriptor *td;
01771 this->thr_to_be_removed_.dequeue_head (td) != -1;
01772 )
01773 this->remove_thr (td, 1);
01774 }
01775
01776 return result;
01777 }
01778
01779
01780
01781 int
01782 ACE_Thread_Manager::wait_task (ACE_Task_Base *task)
01783 {
01784 int copy_count = 0;
01785 ACE_Thread_Descriptor_Base *copy_table = 0;
01786
01787
01788
01789
01790 {
01791 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01792
01793 #if !defined (ACE_VXWORKS)
01794 ACE_NEW_RETURN (copy_table,
01795 ACE_Thread_Descriptor_Base [this->thr_list_.size ()
01796 + this->terminated_thr_list_.size ()],
01797 -1);
01798 #else
01799 ACE_NEW_RETURN (copy_table,
01800 ACE_Thread_Descriptor_Base [this->thr_list_.size ()],
01801 -1);
01802 #endif
01803
01804 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01805 !iter.done ();
01806 iter.advance ())
01807
01808
01809 if (iter.next ()->task_ == task &&
01810 (ACE_BIT_DISABLED (iter.next ()->flags_,
01811 THR_DETACHED | THR_DAEMON)
01812 || ACE_BIT_ENABLED (iter.next ()->flags_,
01813 THR_JOINABLE)))
01814 {
01815 ACE_SET_BITS (iter.next ()->thr_state_,
01816 ACE_THR_JOINING);
01817 copy_table[copy_count++] = *iter.next ();
01818 }
01819
01820 #if !defined (ACE_VXWORKS)
01821 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> titer (this->terminated_thr_list_);
01822 !titer.done ();
01823 titer.advance ())
01824
01825 if (titer.next ()->task_ == task)
01826 {
01827 ACE_Thread_Descriptor_Base *tdb =
01828 titer.advance_and_remove (0);
01829 copy_table[copy_count++] = *tdb;
01830 delete tdb;
01831 }
01832 #endif
01833 }
01834
01835
01836 int result = 0;
01837
01838 for (int i = 0;
01839 i < copy_count && result != -1;
01840 i++)
01841 {
01842 if (ACE_Thread::join (copy_table[i].thr_handle_) == -1)
01843 result = -1;
01844
01845 # if defined (ACE_HAS_PTHREADS_DRAFT4) && defined (ACE_LACKS_SETDETACH)
01846
01847
01848 ::pthread_detach (©_table[i].thr_handle_);
01849 # endif
01850 }
01851
01852 delete [] copy_table;
01853
01854 return result;
01855 }
01856
01857
01858
01859 int
01860 ACE_Thread_Manager::suspend_task (ACE_Task_Base *task)
01861 {
01862 ACE_TRACE ("ACE_Thread_Manager::suspend_task");
01863 return this->apply_task (task,
01864 ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01865 }
01866
01867
01868 int
01869 ACE_Thread_Manager::resume_task (ACE_Task_Base *task)
01870 {
01871 ACE_TRACE ("ACE_Thread_Manager::resume_task");
01872 return this->apply_task (task,
01873 ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01874 }
01875
01876
01877
01878 int
01879 ACE_Thread_Manager::kill_task (ACE_Task_Base *task, int )
01880 {
01881 ACE_TRACE ("ACE_Thread_Manager::kill_task");
01882 return this->apply_task (task,
01883 ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr));
01884 }
01885
01886
01887 int
01888 ACE_Thread_Manager::cancel_task (ACE_Task_Base *task,
01889 int async_cancel)
01890 {
01891 ACE_TRACE ("ACE_Thread_Manager::cancel_task");
01892 return this->apply_task (task,
01893 ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01894 async_cancel);
01895 }
01896
01897
01898
01899
01900
01901 ACE_Thread_Descriptor *
01902 ACE_Thread_Manager::find_task (ACE_Task_Base *task, size_t slot)
01903 {
01904 ACE_TRACE ("ACE_Thread_Manager::find_task");
01905
01906 size_t i = 0;
01907
01908 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01909 !iter.done ();
01910 iter.advance ())
01911 {
01912 if (i >= slot)
01913 break;
01914
01915 if (task == iter.next ()->task_)
01916 return iter.next ();
01917
01918 i++;
01919 }
01920
01921 return 0;
01922 }
01923
01924
01925
01926 int
01927 ACE_Thread_Manager::num_tasks_in_group (int grp_id)
01928 {
01929 ACE_TRACE ("ACE_Thread_Manager::num_tasks_in_group");
01930 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01931
01932 int tasks_count = 0;
01933 size_t i = 0;
01934
01935 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01936 !iter.done ();
01937 iter.advance ())
01938 {
01939 if (iter.next ()->grp_id_ == grp_id
01940 && this->find_task (iter.next ()->task_, i) == 0
01941 && iter.next ()->task_ != 0)
01942 tasks_count++;
01943
01944 i++;
01945 }
01946 return tasks_count;
01947 }
01948
01949
01950
01951 int
01952 ACE_Thread_Manager::num_threads_in_task (ACE_Task_Base *task)
01953 {
01954 ACE_TRACE ("ACE_Thread_Manager::num_threads_in_task");
01955 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01956
01957 int threads_count = 0;
01958
01959 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01960 !iter.done ();
01961 iter.advance ())
01962 if (iter.next ()->task_ == task)
01963 threads_count++;
01964
01965 return threads_count;
01966 }
01967
01968
01969
01970 ssize_t
01971 ACE_Thread_Manager::task_all_list (ACE_Task_Base *task_list[],
01972 size_t n)
01973 {
01974 ACE_TRACE ("ACE_Thread_Manager::task_all_list");
01975 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01976
01977 size_t task_list_count = 0;
01978
01979 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01980 !iter.done ();
01981 iter.advance ())
01982 {
01983 if (task_list_count >= n)
01984 break;
01985
01986 ACE_Task_Base *task_p = iter.next ()->task_;
01987 if (0 != task_p)
01988 {
01989
01990
01991 size_t i = 0;
01992 for (; i < task_list_count; ++i)
01993 if (task_list[i] == task_p)
01994 break;
01995 if (i == task_list_count)
01996 task_list[task_list_count++] = task_p;
01997 }
01998 }
01999
02000 return task_list_count;
02001 }
02002
02003
02004
02005 ssize_t
02006 ACE_Thread_Manager::thread_all_list (ACE_thread_t thread_list[],
02007 size_t n)
02008 {
02009 ACE_TRACE ("ACE_Thread_Manager::thread_all_list");
02010 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02011
02012 size_t thread_count = 0;
02013
02014 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02015 !iter.done ();
02016 iter.advance ())
02017 {
02018 if (thread_count >= n)
02019 break;
02020
02021 thread_list[thread_count] = iter.next ()->thr_id_;
02022 thread_count ++;
02023 }
02024
02025 return thread_count;
02026 }
02027
02028
02029 int
02030 ACE_Thread_Manager::thr_state (ACE_thread_t id,
02031 ACE_UINT32& state)
02032 {
02033 ACE_TRACE ("ACE_Thread_Manager::thr_state");
02034 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02035
02036 int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ());
02037
02038
02039
02040 if (self_check)
02041 {
02042 ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc ();
02043 if (desc == 0)
02044 return 0;
02045 state = desc->thr_state_;
02046 }
02047 else
02048 {
02049
02050 ACE_FIND (this->find_thread (id), ptr);
02051 if (ptr == 0)
02052 return 0;
02053 state = ptr->thr_state_;
02054 }
02055
02056 return 1;
02057 }
02058
02059
02060
02061 ssize_t
02062 ACE_Thread_Manager::task_list (int grp_id,
02063 ACE_Task_Base *task_list[],
02064 size_t n)
02065 {
02066 ACE_TRACE ("ACE_Thread_Manager::task_list");
02067 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02068
02069 ACE_Task_Base **task_list_iterator = task_list;
02070 size_t task_list_count = 0;
02071 size_t i = 0;
02072
02073 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02074 !iter.done ();
02075 iter.advance ())
02076 {
02077 if (task_list_count >= n)
02078 break;
02079
02080 if (iter.next ()->grp_id_ == grp_id
02081 && this->find_task (iter.next ()->task_, i) == 0)
02082 {
02083 task_list_iterator[task_list_count] = iter.next ()->task_;
02084 task_list_count++;
02085 }
02086
02087 i++;
02088 }
02089
02090 return task_list_count;
02091 }
02092
02093
02094
02095 ssize_t
02096 ACE_Thread_Manager::thread_list (ACE_Task_Base *task,
02097 ACE_thread_t thread_list[],
02098 size_t n)
02099 {
02100 ACE_TRACE ("ACE_Thread_Manager::thread_list");
02101 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02102
02103 size_t thread_count = 0;
02104
02105 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02106 !iter.done ();
02107 iter.advance ())
02108 {
02109 if (thread_count >= n)
02110 break;
02111
02112 if (iter.next ()->task_ == task)
02113 {
02114 thread_list[thread_count] = iter.next ()->thr_id_;
02115 thread_count++;
02116 }
02117 }
02118
02119 return thread_count;
02120 }
02121
02122
02123
02124 ssize_t
02125 ACE_Thread_Manager::hthread_list (ACE_Task_Base *task,
02126 ACE_hthread_t hthread_list[],
02127 size_t n)
02128 {
02129 ACE_TRACE ("ACE_Thread_Manager::hthread_list");
02130 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02131
02132 size_t hthread_count = 0;
02133
02134 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02135 !iter.done ();
02136 iter.advance ())
02137 {
02138 if (hthread_count >= n)
02139 break;
02140
02141 if (iter.next ()->task_ == task)
02142 {
02143 hthread_list[hthread_count] = iter.next ()->thr_handle_;
02144 hthread_count++;
02145 }
02146 }
02147
02148 return hthread_count;
02149 }
02150
02151 ssize_t
02152 ACE_Thread_Manager::thread_grp_list (int grp_id,
02153 ACE_thread_t thread_list[],
02154 size_t n)
02155 {
02156 ACE_TRACE ("ACE_Thread_Manager::thread_grp_list");
02157 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02158
02159 size_t thread_count = 0;
02160
02161 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02162 !iter.done ();
02163 iter.advance ())
02164 {
02165 if (thread_count >= n)
02166 break;
02167
02168 if (iter.next ()->grp_id_ == grp_id)
02169 {
02170 thread_list[thread_count] = iter.next ()->thr_id_;
02171 thread_count++;
02172 }
02173 }
02174
02175 return thread_count;
02176 }
02177
02178
02179
02180 ssize_t
02181 ACE_Thread_Manager::hthread_grp_list (int grp_id,
02182 ACE_hthread_t hthread_list[],
02183 size_t n)
02184 {
02185 ACE_TRACE ("ACE_Thread_Manager::hthread_grp_list");
02186 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02187
02188 size_t hthread_count = 0;
02189
02190 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02191 !iter.done ();
02192 iter.advance ())
02193 {
02194 if (hthread_count >= n)
02195 break;
02196
02197 if (iter.next ()->grp_id_ == grp_id)
02198 {
02199 hthread_list[hthread_count] = iter.next ()->thr_handle_;
02200 hthread_count++;
02201 }
02202 }
02203
02204 return hthread_count;
02205 }
02206
02207 int
02208 ACE_Thread_Manager::set_grp (ACE_Task_Base *task, int grp_id)
02209 {
02210 ACE_TRACE ("ACE_Thread_Manager::set_grp");
02211 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02212
02213 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02214 !iter.done ();
02215 iter.advance ())
02216 if (iter.next ()->task_ == task)
02217 iter.next ()->grp_id_ = grp_id;
02218
02219 return 0;
02220 }
02221
02222 int
02223 ACE_Thread_Manager::get_grp (ACE_Task_Base *task, int &grp_id)
02224 {
02225 ACE_TRACE ("ACE_Thread_Manager::get_grp");
02226 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02227
02228 ACE_FIND (this->find_task (task), ptr);
02229 grp_id = ptr->grp_id_;
02230 return 0;
02231 }
02232
02233 ACE_END_VERSIONED_NAMESPACE_DECL