Manages a pool of threads. More...
#include <Thread_Manager.h>

Public Types | |
| enum | { ACE_THR_IDLE = 0x00000000, ACE_THR_SPAWNED = 0x00000001, ACE_THR_RUNNING = 0x00000002, ACE_THR_SUSPENDED = 0x00000004, ACE_THR_CANCELLED = 0x00000008, ACE_THR_TERMINATED = 0x00000010, ACE_THR_JOINING = 0x10000000 } |
| typedef int(ACE_Thread_Manager::* | ACE_THR_MEMBER_FUNC )(ACE_Thread_Descriptor *, int) |
Public Member Functions | |
| ACE_Thread_Manager (size_t preaolloc=ACE_DEFAULT_THREAD_MANAGER_PREALLOC, size_t lwm=ACE_DEFAULT_THREAD_MANAGER_LWM, size_t inc=ACE_DEFAULT_THREAD_MANAGER_INC, size_t hwm=ACE_DEFAULT_THREAD_MANAGER_HWM) | |
| Initialization and termination methods. | |
| ~ACE_Thread_Manager (void) | |
| int | open (size_t size=0) |
| No-op. Currently unused. | |
| int | close (void) |
| int | spawn (ACE_THR_FUNC func, void *arg=0, long flags=THR_NEW_LWP|THR_JOINABLE|THR_INHERIT_SCHED, ACE_thread_t *t_id=0, ACE_hthread_t *t_handle=0, long priority=ACE_DEFAULT_THREAD_PRIORITY, int grp_id=-1, void *stack=0, size_t stack_size=ACE_DEFAULT_THREAD_STACKSIZE, const char **thr_name=0) |
| int | spawn_n (size_t n, ACE_THR_FUNC func, void *arg=0, long flags=THR_NEW_LWP|THR_JOINABLE|THR_INHERIT_SCHED, long priority=ACE_DEFAULT_THREAD_PRIORITY, int grp_id=-1, ACE_Task_Base *task=0, ACE_hthread_t thread_handles[]=0, void *stack[]=0, size_t stack_size[]=0, const char *thr_name[]=0) |
| int | spawn_n (ACE_thread_t thread_ids[], size_t n, ACE_THR_FUNC func, void *arg, long flags, long priority=ACE_DEFAULT_THREAD_PRIORITY, int grp_id=-1, void *stack[]=0, size_t stack_size[]=0, ACE_hthread_t thread_handles[]=0, ACE_Task_Base *task=0, const char *thr_name[]=0) |
| ACE_THR_FUNC_RETURN | exit (ACE_THR_FUNC_RETURN status=0, bool do_thread_exit=true) |
| int | wait (const ACE_Time_Value *timeout=0, bool abandon_detached_threads=false, bool use_absolute_time=true) |
| int | join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status=0) |
| Join a thread specified by tid. Do not wait on a detached thread. | |
| int | wait_grp (int grp_id) |
| int | thr_self (ACE_hthread_t &) |
| ACE_thread_t | thr_self (void) |
| ACE_Task_Base * | task (void) |
| int | kill_all (int signum) |
| int | kill (ACE_thread_t, int signum) |
| int | kill_grp (int grp_id, int signum) |
| int | cancel_all (int async_cancel=0) |
| int | cancel (ACE_thread_t, int async_cancel=0) |
| int | cancel_grp (int grp_id, int async_cancel=0) |
| int | testcancel (ACE_thread_t t_id) |
| int | testterminate (ACE_thread_t t_id) |
| int | set_grp (ACE_thread_t, int grp_id) |
| Set group ids for a particular thread id. | |
| int | get_grp (ACE_thread_t, int &grp_id) |
| Get group ids for a particular thread id. | |
| int | hthread_within (ACE_hthread_t handle) |
| int | thread_within (ACE_thread_t tid) |
| int | num_tasks_in_group (int grp_id) |
| Returns the number of ACE_Task_Base in a group. | |
| int | num_threads_in_task (ACE_Task_Base *task) |
| Returns the number of threads in an ACE_Task_Base. | |
| ssize_t | task_list (int grp_id, ACE_Task_Base *task_list[], size_t n) |
| ssize_t | thread_list (ACE_Task_Base *task, ACE_thread_t thread_list[], size_t n) |
| ssize_t | hthread_list (ACE_Task_Base *task, ACE_hthread_t hthread_list[], size_t n) |
| ssize_t | thread_grp_list (int grp_id, ACE_thread_t thread_list[], size_t n) |
| ssize_t | hthread_grp_list (int grp_id, ACE_hthread_t hthread_list[], size_t n) |
| ssize_t | task_all_list (ACE_Task_Base *task_list[], size_t n) |
| ssize_t | thread_all_list (ACE_thread_t thread_list[], size_t n) |
| int | set_grp (ACE_Task_Base *task, int grp_id) |
| Set group ids for a particular task. | |
| int | get_grp (ACE_Task_Base *task, int &grp_id) |
| Get group ids for a particular task. | |
| size_t | count_threads (void) const |
| int | thr_state (ACE_thread_t id, ACE_UINT32 &state) |
| int | at_exit (ACE_At_Thread_Exit *cleanup) |
| int | at_exit (ACE_At_Thread_Exit &cleanup) |
| int | at_exit (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param) |
| void | wait_on_exit (int dowait) |
| int | wait_on_exit (void) |
| void | dump (void) |
| Dump the state of an object. | |
Suspend and resume methods | |
| int | suspend_all (void) |
| Suspend all threads. | |
| int | suspend (ACE_thread_t) |
| Suspend a single thread. | |
| int | suspend_grp (int grp_id) |
| Suspend a group of threads. | |
| int | testsuspend (ACE_thread_t t_id) |
| int | resume_all (void) |
| Resume all stopped threads. | |
| int | resume (ACE_thread_t) |
| Resume a single thread. | |
| int | resume_grp (int grp_id) |
| Resume a group of threads. | |
| int | testresume (ACE_thread_t t_id) |
Task-related operations | |
| int | wait_task (ACE_Task_Base *task) |
| int | suspend_task (ACE_Task_Base *task) |
| int | resume_task (ACE_Task_Base *task) |
| int | kill_task (ACE_Task_Base *task, int signum) |
| int | cancel_task (ACE_Task_Base *task, int async_cancel=0) |
Static Public Member Functions | |
| static ACE_Thread_Manager * | instance (void) |
| Get pointer to a process-wide ACE_Thread_Manager. | |
| static ACE_Thread_Manager * | instance (ACE_Thread_Manager *) |
| static void | close_singleton (void) |
| Delete the dynamically allocated Singleton. | |
Public Attributes | |
| ACE_ALLOC_HOOK_DECLARE | |
| Declare the dynamic allocation hooks. | |
Protected Member Functions | |
| ACE_Thread_Descriptor * | thread_desc_self (void) |
| ACE_Thread_Descriptor * | thread_descriptor (ACE_thread_t) |
| ACE_Thread_Descriptor * | hthread_descriptor (ACE_hthread_t) |
| int | spawn_i (ACE_THR_FUNC func, void *arg, long flags, ACE_thread_t *=0, ACE_hthread_t *t_handle=0, long priority=ACE_DEFAULT_THREAD_PRIORITY, int grp_id=-1, void *stack=0, size_t stack_size=0, ACE_Task_Base *task=0, const char **thr_name=0) |
| Create a new thread (must be called with locks held). | |
| void | run_thread_exit_hooks (int i) |
| Run the registered hooks when the thread exits. | |
| ACE_Thread_Descriptor * | find_thread (ACE_thread_t t_id) |
| ACE_Thread_Descriptor * | find_hthread (ACE_hthread_t h_id) |
| ACE_Thread_Descriptor * | find_task (ACE_Task_Base *task, size_t slot=0) |
| int | insert_thr (ACE_thread_t t_id, ACE_hthread_t, int grp_id=-1, long flags=0) |
| Insert a thread in the table (checks for duplicates). | |
| int | append_thr (ACE_thread_t t_id, ACE_hthread_t, ACE_UINT32, int grp_id, ACE_Task_Base *task=0, long flags=0, ACE_Thread_Descriptor *td=0) |
| void | remove_thr (ACE_Thread_Descriptor *td, int close_handler) |
| Remove thread from the table. | |
| void | remove_thr_all (void) |
| Remove all threads from the table. | |
| int | check_state (ACE_UINT32 state, ACE_thread_t thread, int enable=1) |
| int | apply_task (ACE_Task_Base *task, ACE_THR_MEMBER_FUNC func, int=0) |
| Apply func to all members of the table that match the task. | |
| int | apply_grp (int grp_id, ACE_THR_MEMBER_FUNC func, int arg=0) |
| Apply func to all members of the table that match the grp_id. | |
| int | apply_all (ACE_THR_MEMBER_FUNC, int=0) |
| Apply func to all members of the table. | |
| int | join_thr (ACE_Thread_Descriptor *td, int=0) |
| Join the thread described in td. | |
| int | resume_thr (ACE_Thread_Descriptor *td, int=0) |
| Resume the thread described in td. | |
| int | suspend_thr (ACE_Thread_Descriptor *td, int=0) |
| Suspend the thread described in td. | |
| int | kill_thr (ACE_Thread_Descriptor *td, int signum) |
| Send signal signum to the thread described in td. | |
| int | cancel_thr (ACE_Thread_Descriptor *td, int async_cancel=0) |
| Set the cancellation flag for the thread described in td. | |
| int | register_as_terminated (ACE_Thread_Descriptor *td) |
| Register a thread as terminated and put it into the <terminated_thr_list_>. | |
Static Protected Member Functions | |
| static int | set_thr_exit (ACE_TSS_TYPE(ACE_Thread_Exit)*ptr) |
| Setting the static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_ pointer. | |
Protected Attributes | |
| ACE_Double_Linked_List < ACE_Thread_Descriptor > | thr_list_ |
| ACE_Double_Linked_List < ACE_Thread_Descriptor_Base > | terminated_thr_list_ |
| Collect terminated but not yet joined thread entries. | |
| ACE_Unbounded_Queue < ACE_Thread_Descriptor * > | thr_to_be_removed_ |
| Collect pointers to thread descriptors of threads to be removed later. | |
| int | grp_id_ |
| Keeps track of the next group id to assign. | |
| int | automatic_wait_ |
| ACE_Locked_Free_List < ACE_Thread_Descriptor, ACE_SYNCH_MUTEX > | thread_desc_freelist_ |
Static Private Member Functions | |
| static | ACE_TSS_TYPE (ACE_Thread_Exit)*thr_exit_ |
| Global ACE_TSS (ACE_Thread_Exit) object ptr. | |
Static Private Attributes | |
| static ACE_Thread_Manager * | thr_mgr_ = 0 |
| Pointer to a process-wide ACE_Thread_Manager. | |
| static bool | delete_thr_mgr_ = false |
| Must delete the thr_mgr_ if true. | |
Friends | |
| class | ACE_Thread_Control |
| class | ACE_Thread_Exit |
| class | ACE_Thread_Descriptor |
Manages a pool of threads.
This class allows operations on groups of threads atomically. The default behavior of thread manager is to wait on all threads under it's management when it gets destructed. Therefore, remember to remove a thread from thread manager if you don't want it to wait for the thread. There are also functions to disable this default wait-on-exit behavior. However, if your program depends on turning this off to run correctly, you are probably doing something wrong. Rule of thumb, use ACE_Thread to manage your daemon threads. Notice that if there're threads which live beyond the scope of main(), you are sure to have resource leaks in your program. Remember to wait on threads before exiting your main program if that could happen in your programs.
Definition at line 383 of file Thread_Manager.h.
| typedef int(ACE_Thread_Manager::* ACE_Thread_Manager::ACE_THR_MEMBER_FUNC)(ACE_Thread_Descriptor *, int) |
Definition at line 393 of file Thread_Manager.h.
| anonymous enum |
These are the various states a thread managed by the ACE_Thread_Manager can be in.
Definition at line 398 of file Thread_Manager.h.
00399 { 00400 /// Uninitialized. 00401 ACE_THR_IDLE = 0x00000000, 00402 00403 /// Created but not yet running. 00404 ACE_THR_SPAWNED = 0x00000001, 00405 00406 /// Thread is active (naturally, we don't know if it's actually 00407 /// *running* because we aren't the scheduler...). 00408 ACE_THR_RUNNING = 0x00000002, 00409 00410 /// Thread is suspended. 00411 ACE_THR_SUSPENDED = 0x00000004, 00412 00413 /// Thread has been cancelled (which is an indiction that it needs to 00414 /// terminate...). 00415 ACE_THR_CANCELLED = 0x00000008, 00416 00417 /// Thread has shutdown, but the slot in the thread manager hasn't 00418 /// been reclaimed yet. 00419 ACE_THR_TERMINATED = 0x00000010, 00420 00421 /// Join operation has been invoked on the thread by thread manager. 00422 ACE_THR_JOINING = 0x10000000 00423 };
| ACE_Thread_Manager::ACE_Thread_Manager | ( | size_t | preaolloc = ACE_DEFAULT_THREAD_MANAGER_PREALLOC, |
|
| size_t | lwm = ACE_DEFAULT_THREAD_MANAGER_LWM, |
|||
| size_t | inc = ACE_DEFAULT_THREAD_MANAGER_INC, |
|||
| size_t | hwm = ACE_DEFAULT_THREAD_MANAGER_HWM | |||
| ) |
Initialization and termination methods.
Internally, ACE_Thread_Manager keeps a freelist for caching resources it uses to keep track of managed threads (not the threads themselves.) prealloc, lwm, inc, determine the initial size, the low water mark, increment step, and high water mark of the freelist.
Definition at line 361 of file Thread_Manager.cpp.
00365 : grp_id_ (1), 00366 automatic_wait_ (1) 00367 #if defined (ACE_HAS_THREADS) 00368 , zero_cond_ (lock_) 00369 #endif /* ACE_HAS_THREADS */ 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 }
| ACE_Thread_Manager::~ACE_Thread_Manager | ( | void | ) |
Definition at line 456 of file Thread_Manager.cpp.
| static ACE_Thread_Manager::ACE_TSS_TYPE | ( | ACE_Thread_Exit | ) | [static, private] |
Global ACE_TSS (ACE_Thread_Exit) object ptr.
| int ACE_Thread_Manager::append_thr | ( | ACE_thread_t | t_id, | |
| ACE_hthread_t | t_handle, | |||
| ACE_UINT32 | thr_state, | |||
| int | grp_id, | |||
| ACE_Task_Base * | task = 0, |
|||
| long | flags = 0, |
|||
| ACE_Thread_Descriptor * | td = 0 | |||
| ) | [protected] |
Append a thread in the table (adds at the end, growing the table if necessary).
Definition at line 785 of file Thread_Manager.cpp.
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 // Setup the Thread_Manager. 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 }
| int ACE_Thread_Manager::apply_all | ( | ACE_THR_MEMBER_FUNC | func, | |
| int | arg = 0 | |||
| ) | [protected] |
Apply func to all members of the table.
Definition at line 1343 of file Thread_Manager.cpp.
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 // Must remove threads after we have traversed the thr_list_ to 01362 // prevent clobber thr_list_'s integrity. 01363 01364 if (! this->thr_to_be_removed_.is_empty ()) 01365 { 01366 // Save/restore errno. 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 }
| int ACE_Thread_Manager::apply_grp | ( | int | grp_id, | |
| ACE_THR_MEMBER_FUNC | func, | |||
| int | arg = 0 | |||
| ) | [protected] |
Apply func to all members of the table that match the grp_id.
Definition at line 1263 of file Thread_Manager.cpp.
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 // Must remove threads after we have traversed the thr_list_ to 01287 // prevent clobber thr_list_'s integrity. 01288 01289 if (! this->thr_to_be_removed_.is_empty ()) 01290 { 01291 // Save/restore errno. 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 }
| int ACE_Thread_Manager::apply_task | ( | ACE_Task_Base * | task, | |
| ACE_THR_MEMBER_FUNC | func, | |||
| int | arg = 0 | |||
| ) | [protected] |
Apply func to all members of the table that match the task.
Definition at line 1697 of file Thread_Manager.cpp.
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 // Must remove threads after we have traversed the thr_list_ to 01715 // prevent clobber thr_list_'s integrity. 01716 01717 if (! this->thr_to_be_removed_.is_empty ()) 01718 { 01719 // Save/restore errno. 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 }
| int ACE_Thread_Manager::at_exit | ( | void * | object, | |
| ACE_CLEANUP_FUNC | cleanup_hook, | |||
| void * | param | |||
| ) |
Register an object (or array) for cleanup at thread termination. "cleanup_hook" points to a (global, or static member) function that is called for the object or array when it to be destroyed. It may perform any necessary cleanup specific for that object or its class. "param" is passed as the second parameter to the "cleanup_hook" function; the first parameter is the object (or array) to be destroyed. "cleanup_hook", for example, may delete the object (or array). If <cleanup_hook> == 0, the <object> will _NOT_ get cleanup at thread exit. You can use this to cancel the previously added at_exit.
Definition at line 263 of file Thread_Manager.inl.
00266 { 00267 ACE_Thread_Descriptor *td = this->thread_desc_self (); 00268 if (td == 0) 00269 return -1; 00270 else 00271 return td->at_exit (object, cleanup_hook, param); 00272 }
| int ACE_Thread_Manager::at_exit | ( | ACE_At_Thread_Exit & | cleanup | ) |
Register an At_Thread_Exit hook and the ownership is retained for the caller. Normally used when the at_exit hook is created in stack.
Definition at line 253 of file Thread_Manager.inl.
00254 { 00255 ACE_Thread_Descriptor *td = this->thread_desc_self (); 00256 if (td == 0) 00257 return -1; 00258 else 00259 return td->at_exit (at); 00260 }
| int ACE_Thread_Manager::at_exit | ( | ACE_At_Thread_Exit * | cleanup | ) |
Register an At_Thread_Exit hook and the ownership is acquire by Thread_Descriptor, this is the usual case when the AT is dynamically allocated.
Definition at line 243 of file Thread_Manager.inl.
00244 { 00245 ACE_Thread_Descriptor *td = this->thread_desc_self (); 00246 if (td == 0) 00247 return -1; 00248 else 00249 return td->at_exit (at); 00250 }
| int ACE_Thread_Manager::cancel | ( | ACE_thread_t | t_id, | |
| int | async_cancel = 0 | |||
| ) |
Cancel a single thread.
Definition at line 1101 of file Thread_Manager.cpp.
01102 { 01103 ACE_TRACE ("ACE_Thread_Manager::cancel"); 01104 ACE_EXECUTE_OP (this->cancel_thr, async_cancel); 01105 }
| int ACE_Thread_Manager::cancel_all | ( | int | async_cancel = 0 |
) |
Cancel's all the threads.
Definition at line 1402 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::cancel_grp | ( | int | grp_id, | |
| int | async_cancel = 0 | |||
| ) |
Cancel a group of threads.
Definition at line 1334 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::cancel_task | ( | ACE_Task_Base * | task, | |
| int | async_cancel = 0 | |||
| ) |
Cancel all threads in an ACE_Task. If <async_cancel> is non-0, then asynchronously cancel these threads if the OS platform supports cancellation. Otherwise, perform a "cooperative" cancellation.
Definition at line 1837 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::cancel_thr | ( | ACE_Thread_Descriptor * | td, | |
| int | async_cancel = 0 | |||
| ) | [protected] |
Set the cancellation flag for the thread described in td.
Definition at line 1024 of file Thread_Manager.cpp.
01025 { 01026 ACE_TRACE ("ACE_Thread_Manager::cancel_thr"); 01027 // Must set the state first and then try to cancel the thread. 01028 ACE_SET_BITS (td->thr_state_, ACE_THR_CANCELLED); 01029 01030 if (async_cancel != 0) 01031 // Note that this call only does something relevant if the OS 01032 // platform supports asynchronous thread cancellation. Otherwise, 01033 // it's a no-op. 01034 return ACE_Thread::cancel (td->thr_id_); 01035 01036 return 0; 01037 }
| int ACE_Thread_Manager::check_state | ( | ACE_UINT32 | state, | |
| ACE_thread_t | thread, | |||
| int | enable = 1 | |||
| ) | [protected] |
Efficiently check whether thread is in a particular state. This call updates the TSS cache if possible to speed up subsequent searches.
Definition at line 1117 of file Thread_Manager.cpp.
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 // If we're checking the state of our thread, try to get the cached 01129 // value out of TSS to avoid lookup. 01130 if (self_check) 01131 { 01132 ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc (); 01133 if (desc == 0) 01134 return 0; // Always return false. 01135 thr_state = desc->thr_state_; 01136 } 01137 else 01138 { 01139 // Not calling from self, have to look it up from the list. 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 }
| int ACE_Thread_Manager::close | ( | void | ) |
Release all resources. By default, this method will wait until all threads exit. However, when called from close_singleton(), most global resources are destroyed and thus, close() does not try to wait; it simply cleans up internal thread records (the thread descriptor list).
Definition at line 439 of file Thread_Manager.cpp.
00440 { 00441 ACE_TRACE ("ACE_Thread_Manager::close"); 00442 00443 // Clean up the thread descriptor list. 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 }
| void ACE_Thread_Manager::close_singleton | ( | void | ) | [static] |
Delete the dynamically allocated Singleton.
Definition at line 416 of file Thread_Manager.cpp.
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 // First, we clean up the thread descriptor list. 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 }
| size_t ACE_Thread_Manager::count_threads | ( | void | ) | const |
Return a count of the current number of threads active in the <Thread_Manager>.
Definition at line 300 of file Thread_Manager.inl.
| void ACE_Thread_Manager::dump | ( | void | ) |
Dump the state of an object.
Definition at line 65 of file Thread_Manager.cpp.
00066 { 00067 #if defined (ACE_HAS_DUMP) 00068 ACE_TRACE ("ACE_Thread_Manager::dump"); 00069 // Cast away const-ness of this in order to use its non-const lock_. 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 /* ACE_HAS_DUMP */ 00087 }
| ACE_THR_FUNC_RETURN ACE_Thread_Manager::exit | ( | ACE_THR_FUNC_RETURN | status = 0, |
|
| bool | do_thread_exit = true | |||
| ) |
Called to clean up when a thread exits.
| do_thread_exit | If non-0 then ACE_Thread::exit is called to exit the thread | |
| status | If ACE_Thread_Exit is called, this is passed as the exit value of the thread. Should _not_ be called by main thread. |
Definition at line 1547 of file Thread_Manager.cpp.
01548 { 01549 ACE_TRACE ("ACE_Thread_Manager::exit"); 01550 #if defined (ACE_WIN32) 01551 // Remove detached thread handle. 01552 01553 if (do_thread_exit) 01554 { 01555 #if 0 01556 // @@ This callback is now taken care of by TSS_Cleanup. Do we 01557 // need it anymore? 01558 01559 // On Win32, if we really wants to exit from a thread, we must 01560 // first clean up the thread specific storage. By doing so, 01561 // ACE_Thread_Manager::exit will be called again with 01562 // do_thr_exit = 0 and cleaning up the ACE_Cleanup_Info (but not 01563 // exiting the thread.) After the following call returns, we 01564 // are safe to exit this thread. 01565 delete ACE_Thread_Exit::instance (); 01566 #endif /* 0 */ 01567 ACE_Thread::exit (status); 01568 } 01569 #endif /* ACE_WIN32 */ 01570 01571 // Just hold onto the guard while finding this thread's id and 01572 { 01573 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); 01574 01575 // Find the thread id, but don't use the cache. It might have been 01576 // deleted already. 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 // @@ We call Thread_Descriptor terminate this realize the cleanup 01582 // process itself. 01583 td->terminate(); 01584 } 01585 } 01586 01587 if (do_thread_exit) 01588 { 01589 ACE_Thread::exit (status); 01590 // On reasonable systems <ACE_Thread::exit> should not return. 01591 // However, due to horrible semantics with Win32 thread-specific 01592 // storage this call can return (don't ask...). 01593 } 01594 01595 return 0; 01596 }
| ACE_Thread_Descriptor * ACE_Thread_Manager::find_hthread | ( | ACE_hthread_t | h_id | ) | [protected] |
Locate the index of the table slot occupied by <h_id>. Returns -1 if <h_id> is not in the table doesn't contain <h_id>.
Definition at line 823 of file Thread_Manager.cpp.
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 }
| ACE_Thread_Descriptor * ACE_Thread_Manager::find_task | ( | ACE_Task_Base * | task, | |
| size_t | slot = 0 | |||
| ) | [protected] |
Locate the thread descriptor address of the list occupied by task. Returns 0 if task is not in the table doesn't contain task.
Definition at line 1851 of file Thread_Manager.cpp.
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 }
| ACE_Thread_Descriptor * ACE_Thread_Manager::find_thread | ( | ACE_thread_t | t_id | ) | [protected] |
Locate the index of the table slot occupied by <t_id>. Returns -1 if <t_id> is not in the table doesn't contain <t_id>.
Definition at line 842 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::get_grp | ( | ACE_Task_Base * | task, | |
| int & | grp_id | |||
| ) |
Get group ids for a particular task.
Definition at line 2213 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::get_grp | ( | ACE_thread_t | t_id, | |
| int & | grp_id | |||
| ) |
Get group ids for a particular thread id.
Definition at line 1230 of file Thread_Manager.cpp.
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 }
| ACE_Thread_Descriptor * ACE_Thread_Manager::hthread_descriptor | ( | ACE_hthread_t | thr_handle | ) | [protected] |
Return a pointer to the thread's Thread_Descriptor, 0 if fail.
Definition at line 332 of file Thread_Manager.cpp.
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 }
| ssize_t ACE_Thread_Manager::hthread_grp_list | ( | int | grp_id, | |
| ACE_hthread_t | hthread_list[], | |||
| size_t | n | |||
| ) |
Returns in hthread_list a list of up to n thread handles in a group grp_id. The caller must allocate memory for hthread_list.
Definition at line 2165 of file Thread_Manager.cpp.
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 }
| ssize_t ACE_Thread_Manager::hthread_list | ( | ACE_Task_Base * | task, | |
| ACE_hthread_t | hthread_list[], | |||
| size_t | n | |||
| ) |
Returns in hthread_list a list of up to n thread handles in an ACE_Task_Base. The caller must allocate memory for hthread_list. In case of an error, -1 is returned. If no requested values are found, 0 is returned, otherwise correct number of retrieved values are returned.
Definition at line 2105 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::hthread_within | ( | ACE_hthread_t | handle | ) |
Check if the thread is managed by the thread manager. Return true if the thread is found, false otherwise.
Definition at line 1190 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::insert_thr | ( | ACE_thread_t | t_id, | |
| ACE_hthread_t | t_handle, | |||
| int | grp_id = -1, |
|||
| long | flags = 0 | |||
| ) | [protected] |
Insert a thread in the table (checks for duplicates).
Definition at line 862 of file Thread_Manager.cpp.
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 // Check for duplicates and bail out if we're already registered... 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 }
| ACE_Thread_Manager * ACE_Thread_Manager::instance | ( | ACE_Thread_Manager * | tm | ) | [static] |
Set pointer to a process-wide ACE_Thread_Manager and return existing pointer.
Definition at line 401 of file Thread_Manager.cpp.
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 // We can't safely delete it since we don't know who created it! 00409 ACE_Thread_Manager::delete_thr_mgr_ = false; 00410 00411 ACE_Thread_Manager::thr_mgr_ = tm; 00412 return t; 00413 }
| ACE_Thread_Manager * ACE_Thread_Manager::instance | ( | void | ) | [static] |
Get pointer to a process-wide ACE_Thread_Manager.
Definition at line 378 of file Thread_Manager.cpp.
00379 { 00380 ACE_TRACE ("ACE_Thread_Manager::instance"); 00381 00382 if (ACE_Thread_Manager::thr_mgr_ == 0) 00383 { 00384 // Perform Double-Checked Locking Optimization. 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 }
| int ACE_Thread_Manager::join | ( | ACE_thread_t | tid, | |
| ACE_THR_FUNC_RETURN * | status = 0 | |||
| ) |
Join a thread specified by tid. Do not wait on a detached thread.
Definition at line 1410 of file Thread_Manager.cpp.
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 // return immediately if we've found the thread we want to join. 01435 return 0; 01436 } 01437 } 01438 #endif /* !ACE_HAS_VXTHREADS */ 01439 01440 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); 01441 !iter.done (); 01442 iter.advance ()) 01443 { 01444 // If threads are created as THR_DETACHED or THR_DAEMON, we 01445 // can't help much. 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 // Didn't find the thread we want or the thread is not joinable. 01460 } 01461 01462 if (ACE_Thread::join (tdb.thr_handle_, status) == -1) 01463 return -1; 01464 01465 return 0; 01466 }
| int ACE_Thread_Manager::join_thr | ( | ACE_Thread_Descriptor * | td, | |
| int | = 0 | |||
| ) | [protected] |
Join the thread described in td.
Definition at line 972 of file Thread_Manager.cpp.
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 // Since the thread are being joined, we should 00979 // let it remove itself from the list. 00980 00981 // this->remove_thr (td); 00982 errno = result; 00983 return -1; 00984 } 00985 00986 return 0; 00987 }
| int ACE_Thread_Manager::kill | ( | ACE_thread_t | t_id, | |
| int | signum | |||
| ) |
Send the signum to a single thread. Not supported on platforms that do not have advanced signal support, such as Win32.
Definition at line 1110 of file Thread_Manager.cpp.
01111 { 01112 ACE_TRACE ("ACE_Thread_Manager::kill"); 01113 ACE_EXECUTE_OP (this->kill_thr, signum); 01114 }
| int ACE_Thread_Manager::kill_all | ( | int | signum | ) |
Send signum to all stopped threads. Not supported on platforms that do not have advanced signal support, such as Win32.
Definition at line 1395 of file Thread_Manager.cpp.
01396 { 01397 ACE_TRACE ("ACE_Thread_Manager::kill_all"); 01398 return this->apply_all (&ACE_Thread_Manager::kill_thr, sig); 01399 }
| int ACE_Thread_Manager::kill_grp | ( | int | grp_id, | |
| int | signum | |||
| ) |
Send signum to a group of threads, not supported on platforms that do not have advanced signal support, such as Win32.
Definition at line 1324 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::kill_task | ( | ACE_Task_Base * | task, | |
| int | signum | |||
| ) |
Send a signal signum to all threads in an ACE_Task.
Definition at line 1828 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::kill_thr | ( | ACE_Thread_Descriptor * | td, | |
| int | signum | |||
| ) | [protected] |
Send signal signum to the thread described in td.
Definition at line 1040 of file Thread_Manager.cpp.
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 // Only remove a thread from us when there is a "real" error. 01051 if (errno != ENOTSUP) 01052 this->thr_to_be_removed_.enqueue_tail (td); 01053 01054 return -1; 01055 } 01056 01057 return 0; 01058 }
| int ACE_Thread_Manager::num_tasks_in_group | ( | int | grp_id | ) |
Returns the number of ACE_Task_Base in a group.
Definition at line 1876 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::num_threads_in_task | ( | ACE_Task_Base * | task | ) |
Returns the number of threads in an ACE_Task_Base.
Definition at line 1903 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::open | ( | size_t | size = 0 |
) |
No-op. Currently unused.
Definition at line 236 of file Thread_Manager.inl.
| int ACE_Thread_Manager::register_as_terminated | ( | ACE_Thread_Descriptor * | td | ) | [protected] |
Register a thread as terminated and put it into the <terminated_thr_list_>.
Definition at line 287 of file Thread_Manager.inl.
00288 { 00289 #if defined (ACE_HAS_VXTHREADS) 00290 ACE_UNUSED_ARG (td); 00291 #else /* ! ACE_HAS_VXTHREADS */ 00292 ACE_Thread_Descriptor_Base *tdb = 0; 00293 ACE_NEW_RETURN (tdb, ACE_Thread_Descriptor_Base (*td), -1); 00294 this->terminated_thr_list_.insert_tail (tdb); 00295 #endif /* !ACE_HAS_VXTHREADS */ 00296 return 0; 00297 }
| void ACE_Thread_Manager::remove_thr | ( | ACE_Thread_Descriptor * | td, | |
| int | close_handler | |||
| ) | [protected] |
Remove thread from the table.
Definition at line 920 of file Thread_Manager.cpp.
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 /* ACE_WIN32 */ 00934 00935 this->thread_desc_freelist_.add (td); 00936 00937 #if defined (ACE_HAS_THREADS) 00938 // Tell all waiters when there are no more threads left in the pool. 00939 if (this->thr_list_.size () == 0) 00940 this->zero_cond_.broadcast (); 00941 #endif /* ACE_HAS_THREADS */ 00942 }
| void ACE_Thread_Manager::remove_thr_all | ( | void | ) | [protected] |
Remove all threads from the table.
Definition at line 947 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::resume | ( | ACE_thread_t | t_id | ) |
Resume a single thread.
Definition at line 1092 of file Thread_Manager.cpp.
01093 { 01094 ACE_TRACE ("ACE_Thread_Manager::resume"); 01095 ACE_EXECUTE_OP (this->resume_thr, 0); 01096 }
| int ACE_Thread_Manager::resume_all | ( | void | ) |
Resume all stopped threads.
Definition at line 1381 of file Thread_Manager.cpp.
01382 { 01383 ACE_TRACE ("ACE_Thread_Manager::resume_all"); 01384 return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr)); 01385 }
| int ACE_Thread_Manager::resume_grp | ( | int | grp_id | ) |
Resume a group of threads.
Definition at line 1314 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::resume_task | ( | ACE_Task_Base * | task | ) |
Resume all threads in an ACE_Task.
Definition at line 1818 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::resume_thr | ( | ACE_Thread_Descriptor * | td, | |
| int | = 0 | |||
| ) | [protected] |
Resume the thread described in td.
Definition at line 1007 of file Thread_Manager.cpp.
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 }
| void ACE_Thread_Manager::run_thread_exit_hooks | ( | int | i | ) | [protected] |
Run the registered hooks when the thread exits.
Definition at line 891 of file Thread_Manager.cpp.
00892 { 00893 #if 0 // currently unused! 00894 ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks"); 00895 00896 // @@ Currently, we have just one hook. This should clearly be 00897 // generalized to support an arbitrary number of hooks. 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 /* 0 */ 00915 }
| int ACE_Thread_Manager::set_grp | ( | ACE_Task_Base * | task, | |
| int | grp_id | |||
| ) |
Set group ids for a particular task.
Definition at line 2194 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::set_grp | ( | ACE_thread_t | t_id, | |
| int | grp_id | |||
| ) |
Set group ids for a particular thread id.
Definition at line 1247 of file Thread_Manager.cpp.
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 }
| static int ACE_Thread_Manager::set_thr_exit | ( | ACE_TSS_TYPE(ACE_Thread_Exit)* | ptr | ) | [static, protected] |
Setting the static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_ pointer.
| int ACE_Thread_Manager::spawn | ( | ACE_THR_FUNC | func, | |
| void * | arg = 0, |
|||
| long | flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, |
|||
| ACE_thread_t * | t_id = 0, |
|||
| ACE_hthread_t * | t_handle = 0, |
|||
| long | priority = ACE_DEFAULT_THREAD_PRIORITY, |
|||
| int | grp_id = -1, |
|||
| void * | stack = 0, |
|||
| size_t | stack_size = ACE_DEFAULT_THREAD_STACKSIZE, |
|||
| const char ** | thr_name = 0 | |||
| ) |
Create a new thread, which executes func with argument arg.
| func | The function that is called in the spawned thread. | |
| arg | The value passed to each spawned thread's func. | |
| flags | Flags to control attributes of the spawned threads. |
| t_id | Pointer to a location to receive the spawned thread's ID. If 0, the ID is not returned. | |
| t_handle | Pointer to a location to receive the spawned thread's thread handle. If 0, the handle is not returned. | |
| priority | The priority at which the thread is spawned. | |
| grp_id | The thread group that the spawned thread is added to. If -1 is specified, a new thread group is created for the spawned thread. | |
| stack | Pointers to the base of a pre-allocated stack space for the thread's stack. If 0, the platform allocates stack space for the thread. If a stack is specified, it is recommended that stack_size also be supplied to specify the size of the stack. Not all platforms support pre-allocated stacks. If stack is specified for a platform which does not allow pre-allocated stack space this parameter is ignored. | |
| stack_size | Indicate how large the thread's stack should be, in bytes. If a pre-allocated stack pointer is passed in stack, stack_size indicates the size of that stack area. If no pre-allocated stack is passed, the stack size specified is passed to the operating system to request that it allocate a stack of the specified size. | |
| thr_name | Pointer to a name to assign to the spawned thread. This is only meaningful for platforms that have a capacity to name threads (e.g., VxWorks and some varieties of Pthreads). This argument is ignored if specified as 0 and on platforms that do not have the capability to name threads. |
| -1 | on failure; errno contains an error value. | |
| The | group id of the spawned thread. |
Definition at line 659 of file Thread_Manager.cpp.
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_++; // Increment the group 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 }
| int ACE_Thread_Manager::spawn_i | ( | ACE_THR_FUNC | func, | |
| void * | arg, | |||
| long | flags, | |||
| ACE_thread_t * | t_id = 0, |
|||
| ACE_hthread_t * | t_handle = 0, |
|||
| long | priority = ACE_DEFAULT_THREAD_PRIORITY, |
|||
| int | grp_id = -1, |
|||
| void * | stack = 0, |
|||
| size_t | stack_size = 0, |
|||
| ACE_Task_Base * | task = 0, |
|||
| const char ** | thr_name = 0 | |||
| ) | [protected] |
Create a new thread (must be called with locks held).
Definition at line 543 of file Thread_Manager.cpp.
00554 { 00555 // First, threads created by Thread Manager should not be daemon threads. 00556 // Using assertion is probably a bit too strong. However, it helps 00557 // finding this kind of error as early as possible. Perhaps we can replace 00558 // assertion by returning error. 00559 ACE_ASSERT (ACE_BIT_DISABLED (flags, THR_DAEMON)); 00560 00561 // Create a new thread running <func>. *Must* be called with the 00562 // <lock_> held... 00563 // Get a "new" Thread Descriptor from the freelist. 00564 auto_ptr<ACE_Thread_Descriptor> new_thr_desc (this->thread_desc_freelist_.remove ()); 00565 00566 // Reset thread descriptor status 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 /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ 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 // Acquire the <sync_> lock to block the spawned thread from 00599 // removing this Thread Descriptor before it gets put into our 00600 // thread table. 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 // _Don't_ clobber errno here! result is either 0 or -1, and 00617 // ACE_OS::thr_create () already set errno! D. Levine 28 Mar 1997 00618 // errno = result; 00619 ACE_Errno_Guard guard (errno); // Lock release may smash errno 00620 new_thr_desc->sync_->release (); 00621 return -1; 00622 } 00623 auto_thread_args.release (); 00624 00625 #if defined (ACE_HAS_WTHREADS) 00626 // Have to duplicate handle if client asks for it. 00627 // @@ How are thread handles implemented on AIX? Do they 00628 // also need to be duplicated? 00629 if (t_handle != 0) 00630 # if defined (ACE_LACKS_DUPLICATEHANDLE) 00631 *t_handle = thr_handle; 00632 # else /* ! ACE_LACKS_DUP */ 00633 (void) ::DuplicateHandle (::GetCurrentProcess (), 00634 thr_handle, 00635 ::GetCurrentProcess (), 00636 t_handle, 00637 0, 00638 TRUE, 00639 DUPLICATE_SAME_ACCESS); 00640 # endif /* ! ACE_LACKS_DUP */ 00641 #else /* ! ACE_HAS_WTHREADS */ 00642 if (t_handle != 0) 00643 *t_handle = thr_handle; 00644 #endif /* ! ACE_HAS_WTHREADS */ 00645 00646 // append_thr also put the <new_thr_desc> into Thread_Manager's 00647 // double-linked list. Only after this point, can we manipulate 00648 // double-linked list from a spawned thread's context. 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 }
| int ACE_Thread_Manager::spawn_n | ( | ACE_thread_t | thread_ids[], | |
| size_t | n, | |||
| ACE_THR_FUNC | func, | |||
| void * | arg, | |||
| long | flags, | |||
| long | priority = ACE_DEFAULT_THREAD_PRIORITY, |
|||
| int | grp_id = -1, |
|||
| void * | stack[] = 0, |
|||
| size_t | stack_size[] = 0, |
|||
| ACE_hthread_t | thread_handles[] = 0, |
|||
| ACE_Task_Base * | task = 0, |
|||
| const char * | thr_name[] = 0 | |||
| ) |
Spawn a specified number of threads, all of which execute func with argument arg.
| thread_ids | An array to receive the thread IDs of successfully spawned buffer. If 0, the thread IDs are not returned. If specified, the array must be at least n entries. | |
| n | The number of threads to spawn. | |
| func | The function that is called in the spawned thread. | |
| arg | The value passed to each spawned thread's func. | |
| flags | Flags to control attributes of the spawned threads. |
| priority | The priority at which the threads are spawned. | |
| grp_id | The thread group that the spawned threads are added to. If -1 is specified, a new thread group is created for the spawned threads. | |
| stack | An array of n pointers to pre-allocated stack space for each thread's stack. If specified as 0, the platform allocates stack space for each thread. If a stack is specified, it is recommended that a stack_size element also be supplied that specifies the size of the stack. Not all platforms support pre-allocated stacks. If stack is specified for a platform which does not allow pre-allocated stack space this parameter is ignored. | |
| stack_size | An array of n values which indicate how large each thread's stack should be, in bytes. If pre-allocated stacks are passed in stacks, these sizes are for those stacks. If no pre-allocated stacks are passed, the stack sizes are specified to the operating system to request that it allocate stacks of the specified sizes. If an array entry is 0, the platform defaults are used for the corresponding thread. If a 0 array pointer is specified, platform defaults are used for all thread stack sizes. | |
| thread_handles | An array of n entries which will receive the thread handles of the spawned threads. | |
| task | The ACE_Task that the spawned threads are associated with. If 0, the threads are not associated with an ACE_Task. This argument is usually assigned by the ACE_Task_Base::activate() method to associate the spawned threads with the spawning ACE_Task object. | |
| thr_name | An array of names to assign to the spawned threads. This is only meaningful for platforms that have a capacity to name threads (e.g., VxWorks and some varieties of Pthreads). This argument is ignored if specified as 0 and on platforms that do not have the capability to name threads. |
ACE_Thread_Manager can manipulate threads in groups based on grp_id or task using functions such as kill_grp() or cancel_task().
| -1 | on failure; errno contains an error value. | |
| The | group id of the threads. |
Definition at line 741 of file Thread_Manager.cpp.
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_++; // Increment the group id. 00759 00760 for (size_t i = 0; i < n; i++) 00761 { 00762 // @@ What should happen if this fails?! e.g., should we try to 00763 // cancel the other threads that we've already spawned or what? 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 }
| int ACE_Thread_Manager::spawn_n | ( | size_t | n, | |
| ACE_THR_FUNC | func, | |||
| void * | arg = 0, |
|||
| long | flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, |
|||
| long | priority = ACE_DEFAULT_THREAD_PRIORITY, |
|||
| int | grp_id = -1, |
|||
| ACE_Task_Base * | task = 0, |
|||
| ACE_hthread_t | thread_handles[] = 0, |
|||
| void * | stack[] = 0, |
|||
| size_t | stack_size[] = 0, |
|||
| const char * | thr_name[] = 0 | |||
| ) |
Spawn a specified number of threads, all of which execute func with argument arg.
| n | The number of threads to spawn. | |
| func | The function that is called in the spawned thread. | |
| arg | The value passed to each spawned thread's func. | |
| flags | Flags to control attributes of the spawned threads. |
| priority | The priority at which the threads are spawned. | |
| grp_id | The thread group that the spawned threads are added to. If -1 is specified, a new thread group is created for the spawned threads. | |
| task | The ACE_Task that the spawned threads are associated with. If 0, the threads are not associated with an ACE_Task. This argument is usually assigned by the ACE_Task_Base::activate() method to associate the spawned threads with the spawning ACE_Task object. | |
| thread_handles | An array of n entries which will receive the thread handles of the spawned threads. | |
| stack | An array of n pointers to pre-allocated stack space for each thread's stack. If specified as 0, the platform allocates stack space for each thread. If a stack is specified, it is recommended that a stack_size element also be supplied that specifies the size of the stack. Not all platforms support pre-allocated stacks. If stack is specified for a platform which does not allow pre-allocated stack space this parameter is ignored. | |
| stack_size | An array of n values which indicate how large each thread's stack should be, in bytes. If pre-allocated stacks are passed in stacks, these sizes are for those stacks. If no pre-allocated stacks are passed, the stack sizes are specified to the operating system to request that it allocate stacks of the specified sizes. If an array entry is 0, the platform defaults are used for the corresponding thread. If a 0 array pointer is specified, platform defaults are used for all thread stack sizes. | |
| thr_name | An array of names to assign to the spawned threads. This is only meaningful for platforms that have a capacity to name threads (e.g., VxWorks and some varieties of Pthreads). This argument is ignored if specified as 0 and on platforms that do not have the capability to name threads. |
ACE_Thread_Manager can manipulate threads in groups based on grp_id or task using functions such as kill_grp() or cancel_task().
| -1 | on failure; errno contains an error value. | |
| The | group id of the threads. |
Definition at line 699 of file Thread_Manager.cpp.
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_++; // Increment the group id. 00716 00717 for (size_t i = 0; i < n; i++) 00718 { 00719 // @@ What should happen if this fails?! e.g., should we try to 00720 // cancel the other threads that we've already spawned or what? 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 }
| int ACE_Thread_Manager::suspend | ( | ACE_thread_t | t_id | ) |
Suspend a single thread.
Definition at line 1083 of file Thread_Manager.cpp.
01084 { 01085 ACE_TRACE ("ACE_Thread_Manager::suspend"); 01086 ACE_EXECUTE_OP (this->suspend_thr, 0); 01087 }
| int ACE_Thread_Manager::suspend_all | ( | void | ) |
Suspend all threads.
Definition at line 1388 of file Thread_Manager.cpp.
01389 { 01390 ACE_TRACE ("ACE_Thread_Manager::suspend_all"); 01391 return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr)); 01392 }
| int ACE_Thread_Manager::suspend_grp | ( | int | grp_id | ) |
Suspend a group of threads.
Definition at line 1304 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::suspend_task | ( | ACE_Task_Base * | task | ) |
Suspend all threads in an ACE_Task.
Definition at line 1809 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::suspend_thr | ( | ACE_Thread_Descriptor * | td, | |
| int | = 0 | |||
| ) | [protected] |
Suspend the thread described in td.
Definition at line 990 of file Thread_Manager.cpp.
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 }
| ACE_Task_Base * ACE_Thread_Manager::task | ( | void | ) |
Returns a pointer to the current ACE_Task_Base we're executing in if this thread is indeed running in an ACE_Task_Base, else return 0.
Definition at line 223 of file Thread_Manager.inl.
00224 { 00225 ACE_TRACE ("ACE_Thread_Manager::task"); 00226 00227 ACE_Thread_Descriptor *td = this->thread_desc_self () ; 00228 00229 if (td == 0) 00230 return 0; 00231 else 00232 return td->task (); 00233 }
| ssize_t ACE_Thread_Manager::task_all_list | ( | ACE_Task_Base * | task_list[], | |
| size_t | n | |||
| ) |
Returns a list of ACE_Task_Base pointers corresponding to the tasks that have active threads managed by this instance.
| task_list | is a pointer to an array to receive the list of pointers. The caller is responsible for supplying an array with at least
| |
| n | The maximum number of ACE_Task_Base pointers to write in
|
| If | successful, the number of pointers returned, which will be no greater than
|
Definition at line 1926 of file Thread_Manager.cpp.
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 // This thread has a task pointer; see if it's already in the 01948 // list. Don't add duplicates. 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) // No match - add this one 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 }
| ssize_t ACE_Thread_Manager::task_list | ( | int | grp_id, | |
| ACE_Task_Base * | task_list[], | |||
| size_t | n | |||
| ) |
Returns a list of ACE_Task_Base pointers corresponding to the tasks that have active threads in a specified thread group.
| grp_id | The thread group ID to obtain task pointers for. | |
| task_list | is a pointer to an array to receive the list of pointers. The caller is responsible for supplying an array with at least
| |
| n | The maximum number of ACE_Task_Base pointers to write in
|
| If | successful, the number of pointers returned, which will be no greater than
|
Definition at line 2038 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::testcancel | ( | ACE_thread_t | t_id | ) |
True if t_id is cancelled, else false. Always return false if t_id is not managed by the Thread_Manager.
Definition at line 1181 of file Thread_Manager.cpp.
01182 { 01183 ACE_TRACE ("ACE_Thread_Manager::testcancel"); 01184 return this->check_state (ACE_THR_CANCELLED, t_id); 01185 }
| int ACE_Thread_Manager::testresume | ( | ACE_thread_t | t_id | ) |
True if t_id is active (i.e., resumed), else false. Always return false if t_id is not managed by the Thread_Manager.
Definition at line 1172 of file Thread_Manager.cpp.
01173 { 01174 ACE_TRACE ("ACE_Thread_Manager::testresume"); 01175 return this->check_state (ACE_THR_SUSPENDED, t_id, 0); 01176 }
| int ACE_Thread_Manager::testsuspend | ( | ACE_thread_t | t_id | ) |
True if t_id is inactive (i.e., suspended), else false. Always return false if t_id is not managed by the Thread_Manager.
Definition at line 1163 of file Thread_Manager.cpp.
01164 { 01165 ACE_TRACE ("ACE_Thread_Manager::testsuspend"); 01166 return this->check_state (ACE_THR_SUSPENDED, t_id); 01167 }
| int ACE_Thread_Manager::testterminate | ( | ACE_thread_t | t_id | ) |
True if t_id has terminated (i.e., is no longer running), but the slot in the thread manager hasn't been reclaimed yet, else false. Always return false if t_id is not managed by the Thread_Manager.
Definition at line 1154 of file Thread_Manager.cpp.
01155 { 01156 ACE_TRACE ("ACE_Thread_Manager::testterminate"); 01157 return this->check_state (ACE_THR_TERMINATED, t_id); 01158 }
| ACE_thread_t ACE_Thread_Manager::thr_self | ( | void | ) |
Return the unique ID of the calling thread. Same as calling ACE_Thread::self().
Definition at line 216 of file Thread_Manager.inl.
00217 { 00218 ACE_TRACE ("ACE_Thread_Manager::thr_self"); 00219 return ACE_Thread::self (); 00220 }
| int ACE_Thread_Manager::thr_self | ( | ACE_hthread_t & | self | ) |
Return the "real" handle to the calling thread, caching it if necessary in TSS to speed up subsequent lookups. This is necessary since on some platforms (e.g., Windows) we can't get this handle via direct method calls. Notice that you should *not* close the handle passed back from this method. It is used internally by Thread Manager. On the other hand, you *have to* use this internal thread handle when working on Thread_Manager. Return -1 if fail.
Definition at line 344 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::thr_state | ( | ACE_thread_t | id, | |
| ACE_UINT32 & | state | |||
| ) |
Get the state of the thread. Returns false if the thread is not managed by this thread manager.
Definition at line 1998 of file Thread_Manager.cpp.
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 // If we're checking the state of our thread, try to get the cached 02007 // value out of TSS to avoid lookup. 02008 if (self_check) 02009 { 02010 ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc (); 02011 02012 if (desc == 0) 02013 { 02014 return 0; // Always return false. 02015 } 02016 02017 state = desc->thr_state_; 02018 } 02019 else 02020 { 02021 // Not calling from self, have to look it up from the list. 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 }
| ssize_t ACE_Thread_Manager::thread_all_list | ( | ACE_thread_t | thread_list[], | |
| size_t | n | |||
| ) |
Returns in thread_list a list of up to n thread ids. The caller must allocate the memory for thread_list. In case of an error, -1 is returned. If no requested values are found, 0 is returned, otherwise correct number of retrieved values are returned.
Definition at line 1972 of file Thread_Manager.cpp.
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 }
| ACE_Thread_Descriptor * ACE_Thread_Manager::thread_desc_self | ( | void | ) | [protected] |
Get a pointer to the calling thread's own thread_descriptor. This must be called from a spawn thread. This function will fetch the info from TSS.
Definition at line 186 of file Thread_Manager.inl.
00187 { 00188 // This method must be called with lock held. 00189 00190 // Try to get it from cache. 00191 ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc (); 00192 00193 #if 1 00194 // ACE_ASSERT (desc != 0); 00195 // Thread descriptor should always get cached. 00196 #else 00197 if (desc == 0) 00198 { 00199 ACE_thread_t id = ACE_OS::thr_self (); 00200 00201 desc = this->find_thread (id); 00202 00203 // Thread descriptor adapter might not have been put into the 00204 // list yet. 00205 if (desc != 0) 00206 // Update the TSS cache. 00207 ACE_LOG_MSG->thr_desc (desc); 00208 } 00209 #endif 00210 return desc; 00211 }
| ACE_Thread_Descriptor * ACE_Thread_Manager::thread_descriptor | ( | ACE_thread_t | thr_id | ) | [protected] |
Return a pointer to the thread's Thread_Descriptor, 0 if fail.
Definition at line 322 of file Thread_Manager.cpp.
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 }
| ssize_t ACE_Thread_Manager::thread_grp_list | ( | int | grp_id, | |
| ACE_thread_t | thread_list[], | |||
| size_t | n | |||
| ) |
Returns in thread_list a list of up to n thread ids in a group grp_id. The caller must allocate the memory for thread_list. In case of an error, -1 is returned. If no requested values are found, 0 is returned, otherwise correct number of retrieved values are returned.
Definition at line 2134 of file Thread_Manager.cpp.
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 }
| ssize_t ACE_Thread_Manager::thread_list | ( | ACE_Task_Base * | task, | |
| ACE_thread_t | thread_list[], | |||
| size_t | n | |||
| ) |
Returns in thread_list a list of up to n thread ids in an ACE_Task_Base. The caller must allocate the memory for thread_list. In case of an error, -1 is returned. If no requested values are found, 0 is returned, otherwise correct number of retrieved values are returned.
Definition at line 2074 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::thread_within | ( | ACE_thread_t | tid | ) |
Definition at line 1209 of file Thread_Manager.cpp.
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 }
| int ACE_Thread_Manager::wait | ( | const ACE_Time_Value * | timeout = 0, |
|
| bool | abandon_detached_threads = false, |
|||
| bool | use_absolute_time = true | |||
| ) |
Block until there are no more threads running in this thread manager or timeout expires.
| timeout | is treated as "absolute" time by default, but this can be changed to "relative" time by setting the use_absolute_time to false. | |
| abandon_detached_threads | If true, wait() will first check thru its thread list for threads with THR_DETACHED or THR_DAEMON flags set and remove these threads. Notice that unlike other wait_*() methods, by default, wait() does wait on all thread spawned by this thread manager no matter the detached flags are set or not unless it is called with abandon_detached_threads flag set. | |
| use_absolute_time | If true then treat timeout as absolute time, else relative time. |
ACE_Object_Manager is shutting down (as a result of program rundown via ACE::fini()), it will not wait for any threads to complete. If you must wait for threads spawned by this thread manager to complete and you are in a ACE rundown situation (such as your object is being destroyed by the ACE_Object_Manager) you can use wait_grp() instead. Definition at line 1601 of file Thread_Manager.cpp.
01604 { 01605 ACE_TRACE ("ACE_Thread_Manager::wait"); 01606 01607 ACE_Time_Value local_timeout; 01608 // Check to see if we're using absolute time or not. 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 /* ACE_HAS_VXTHREADS */ 01619 01620 #if defined (ACE_HAS_THREADS) 01621 { 01622 // Just hold onto the guard while waiting. 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 // Program is not shutting down. Perform a normal wait on threads. 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 // Program is shutting down, no chance to wait on threads. 01659 // Therefore, we'll just remove threads from the list. 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 /* ACE_HAS_VXTHREADS */ 01669 // Release the guard, giving other threads a chance to run. 01670 } 01671 01672 #if !defined (ACE_HAS_VXTHREADS) 01673 // @@ VxWorks doesn't support thr_join (yet.) We are working 01674 // on our implementation. Chorus'es thr_join seems broken. 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 // Detached handles shouldn't reached here. 01682 (void) ACE_Thread::join (item->thr_handle_); 01683 01684 delete item; 01685 } 01686 01687 #endif /* !ACE_HAS_VXTHREADS */ 01688 #else 01689 ACE_UNUSED_ARG (timeout); 01690 ACE_UNUSED_ARG (abandon_detached_threads); 01691 #endif /* ACE_HAS_THREADS */ 01692 01693 return 0; 01694 }
| int ACE_Thread_Manager::wait_grp | ( | int | grp_id | ) |
Block until there are no more threads running in a group. Returns 0 on success and -1 on failure. Notice that wait_grp will not wait on detached threads.
Definition at line 1471 of file Thread_Manager.cpp.
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 // We have to make sure that while we wait for these threads to 01479 // exit, we do not have the lock. Therefore we make a copy of all 01480 // interesting entries and let go of the lock. 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 /* !ACE_HAS_VXTHREADS */ 01494 01495 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); 01496 !iter.done (); 01497 iter.advance ()) 01498 { 01499 // If threads are created as THR_DETACHED or THR_DAEMON, we 01500 // can't help much. 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 // If threads are created as THR_DETACHED or THR_DAEMON, we 01516 // can't help much. 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 /* !ACE_HAS_VXTHREADS */ 01525 } 01526 01527 // Now actually join() with all the threads in this group. 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 }
| int ACE_Thread_Manager::wait_on_exit | ( | void | ) |
Definition at line 281 of file Thread_Manager.inl.
00282 { 00283 return this->automatic_wait_; 00284 }
| void ACE_Thread_Manager::wait_on_exit | ( | int | dowait | ) |
Access function to determine whether the Thread_Manager will wait for its thread to exit or not when being closing down.
Definition at line 275 of file Thread_Manager.inl.
00276 { 00277 this->automatic_wait_ = do_wait; 00278 }
| int ACE_Thread_Manager::wait_task | ( | ACE_Task_Base * | task | ) |
Block until there are no more threads running in a specified task. This method will not wait for either detached or daemon threads; the threads must have been spawned with the THR_JOINABLE flag. Upon successful completion, the threads have been joined, so further attempts to join with any of the waited-for threads will fail.
| task | The ACE_Task_Base object whose threads are to waited for. |
| 0 | Success. | |
| -1 | Failure (consult errno for further information). |
Definition at line 1734 of file Thread_Manager.cpp.
01735 { 01736 int copy_count = 0; 01737 ACE_Thread_Descriptor_Base *copy_table = 0; 01738 01739 // We have to make sure that while we wait for these threads to 01740 // exit, we do not have the lock. Therefore we make a copy of all 01741 // interesting entries and let go of the lock. 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 /* !ACE_HAS_VXTHREADS */ 01755 01756 for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); 01757 !iter.done (); 01758 iter.advance ()) 01759 { 01760 // If threads are created as THR_DETACHED or THR_DAEMON, we 01761 // can't wait on them here. 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 // If threads are created as THR_DETACHED or THR_DAEMON, we can't help much here. 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 /* !ACE_HAS_VXTHREADS */ 01788 } 01789 01790 // Now to do the actual work 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 }
friend class ACE_Thread_Control [friend] |
Definition at line 386 of file Thread_Manager.h.
friend class ACE_Thread_Descriptor [friend] |
Definition at line 390 of file Thread_Manager.h.
friend class ACE_Thread_Exit [friend] |
Definition at line 389 of file Thread_Manager.h.
Declare the dynamic allocation hooks.
Definition at line 1082 of file Thread_Manager.h.
int ACE_Thread_Manager::automatic_wait_ [protected] |
Set if we want the Thread_Manager to wait on all threads before being closed, reset otherwise.
Definition at line 1228 of file Thread_Manager.h.
bool ACE_Thread_Manager::delete_thr_mgr_ = false [static, private] |
Must delete the thr_mgr_ if true.
Definition at line 1247 of file Thread_Manager.h.
int ACE_Thread_Manager::grp_id_ [protected] |
Keeps track of the next group id to assign.
Definition at line 1224 of file Thread_Manager.h.
ACE_Double_Linked_List<ACE_Thread_Descriptor_Base> ACE_Thread_Manager::terminated_thr_list_ [protected] |
Collect terminated but not yet joined thread entries.
Definition at line 1217 of file Thread_Manager.h.
Keeping a list of thread descriptors within the thread manager. Double-linked list enables us to cache the entries in TSS and adding/removing thread descriptor entries without affecting other thread's descriptor entries.
Definition at line 1213 of file Thread_Manager.h.
ACE_Thread_Manager * ACE_Thread_Manager::thr_mgr_ = 0 [static, private] |
Pointer to a process-wide ACE_Thread_Manager.
Definition at line 1244 of file Thread_Manager.h.
Collect pointers to thread descriptors of threads to be removed later.
Definition at line 1221 of file Thread_Manager.h.
ACE_Locked_Free_List<ACE_Thread_Descriptor, ACE_SYNCH_MUTEX> ACE_Thread_Manager::thread_desc_freelist_ [protected] |
Definition at line 1239 of file Thread_Manager.h.
1.6.1