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.
{ /// Uninitialized. ACE_THR_IDLE = 0x00000000, /// Created but not yet running. ACE_THR_SPAWNED = 0x00000001, /// Thread is active (naturally, we don't know if it's actually /// *running* because we aren't the scheduler...). ACE_THR_RUNNING = 0x00000002, /// Thread is suspended. ACE_THR_SUSPENDED = 0x00000004, /// Thread has been cancelled (which is an indiction that it needs to /// terminate...). ACE_THR_CANCELLED = 0x00000008, /// Thread has shutdown, but the slot in the thread manager hasn't /// been reclaimed yet. ACE_THR_TERMINATED = 0x00000010, /// Join operation has been invoked on the thread by thread manager. ACE_THR_JOINING = 0x10000000 };
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.
: grp_id_ (1), automatic_wait_ (1) #if defined (ACE_HAS_THREADS) , zero_cond_ (lock_) #endif /* ACE_HAS_THREADS */ , thread_desc_freelist_ (ACE_FREE_LIST_WITH_POOL, prealloc, lwm, hwm, inc) { ACE_TRACE ("ACE_Thread_Manager::ACE_Thread_Manager"); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::append_thr"); ACE_Thread_Descriptor *thr_desc = 0; if (td == 0) { ACE_NEW_RETURN (thr_desc, ACE_Thread_Descriptor, -1); thr_desc->tm_ = this; // Setup the Thread_Manager. } else thr_desc = td; thr_desc->thr_id_ = t_id; thr_desc->thr_handle_ = t_handle; thr_desc->grp_id_ = grp_id; thr_desc->task_ = task; thr_desc->flags_ = flags; this->thr_list_.insert_head (thr_desc); ACE_SET_BITS (thr_desc->thr_state_, thr_state); thr_desc->sync_->release (); return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::apply_all"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); int result = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if ((this->*func)(iter.next (), arg) == -1) { result = -1; } } // Must remove threads after we have traversed the thr_list_ to // prevent clobber thr_list_'s integrity. if (! this->thr_to_be_removed_.is_empty ()) { // Save/restore errno. ACE_Errno_Guard error (errno); for (ACE_Thread_Descriptor *td; this->thr_to_be_removed_.dequeue_head (td) != -1; ) this->remove_thr (td, 1); } return result; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::apply_grp"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1)); ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); int result = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (iter.next ()->grp_id_ == grp_id) { if ((this->*func) (iter.next (), arg) == -1) { result = -1; } } } // Must remove threads after we have traversed the thr_list_ to // prevent clobber thr_list_'s integrity. if (! this->thr_to_be_removed_.is_empty ()) { // Save/restore errno. ACE_Errno_Guard error (errno); for (ACE_Thread_Descriptor *td; this->thr_to_be_removed_.dequeue_head (td) != -1; ) this->remove_thr (td, 1); } return result; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::apply_task"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); int result = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) if (iter.next ()->task_ == task && (this->*func) (iter.next (), arg) == -1) result = -1; // Must remove threads after we have traversed the thr_list_ to // prevent clobber thr_list_'s integrity. if (! this->thr_to_be_removed_.is_empty ()) { // Save/restore errno. ACE_Errno_Guard error (errno); for (ACE_Thread_Descriptor *td = 0; this->thr_to_be_removed_.dequeue_head (td) != -1; ) this->remove_thr (td, 1); } return result; }
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.
{ ACE_Thread_Descriptor *td = this->thread_desc_self (); if (td == 0) return -1; else return td->at_exit (at); }
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.
{ ACE_Thread_Descriptor *td = this->thread_desc_self (); if (td == 0) return -1; else return td->at_exit (at); }
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.
{ ACE_Thread_Descriptor *td = this->thread_desc_self (); if (td == 0) return -1; else return td->at_exit (object, cleanup_hook, param); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::cancel"); ACE_EXECUTE_OP (this->cancel_thr, async_cancel); }
int ACE_Thread_Manager::cancel_all | ( | int | async_cancel = 0 |
) |
Cancel's all the threads.
Definition at line 1402 of file Thread_Manager.cpp.
{ ACE_TRACE ("ACE_Thread_Manager::cancel_all"); return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr), async_cancel); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::cancel_grp"); return this->apply_grp (grp_id, ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr), async_cancel); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::cancel_task"); return this->apply_task (task, ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr), async_cancel); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::cancel_thr"); // Must set the state first and then try to cancel the thread. ACE_SET_BITS (td->thr_state_, ACE_THR_CANCELLED); if (async_cancel != 0) // Note that this call only does something relevant if the OS // platform supports asynchronous thread cancellation. Otherwise, // it's a no-op. return ACE_Thread::cancel (td->thr_id_); return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::check_state"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); ACE_UINT32 thr_state; int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ()); // If we're checking the state of our thread, try to get the cached // value out of TSS to avoid lookup. if (self_check) { ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc (); if (desc == 0) return 0; // Always return false. thr_state = desc->thr_state_; } else { // Not calling from self, have to look it up from the list. ACE_FIND (this->find_thread (id), ptr); if (ptr == 0) return 0; thr_state = ptr->thr_state_; } if (enable) return ACE_BIT_ENABLED (thr_state, state); return ACE_BIT_DISABLED (thr_state, state); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::close"); // Clean up the thread descriptor list. if (this->automatic_wait_) this->wait (0, 1); else { ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); this->remove_thr_all (); } return 0; }
void ACE_Thread_Manager::close_singleton | ( | void | ) | [static] |
Delete the dynamically allocated Singleton.
Definition at line 416 of file Thread_Manager.cpp.
{ ACE_TRACE ("ACE_Thread_Manager::close_singleton"); ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Static_Object_Lock::instance ())); if (ACE_Thread_Manager::delete_thr_mgr_) { // First, we clean up the thread descriptor list. ACE_Thread_Manager::thr_mgr_->close (); delete ACE_Thread_Manager::thr_mgr_; ACE_Thread_Manager::thr_mgr_ = 0; ACE_Thread_Manager::delete_thr_mgr_ = false; } ACE_Thread_Exit::cleanup (ACE_Thread_Manager::thr_exit_); }
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.
{ #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_Thread_Manager::dump"); // Cast away const-ness of this in order to use its non-const lock_. ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, ((ACE_Thread_Manager *) this)->lock_)); ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ngrp_id_ = %d"), this->grp_id_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncurrent_count_ = %d"), this->thr_list_.size ())); for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { iter.next ()->dump (); } ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ }
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.
{ ACE_TRACE ("ACE_Thread_Manager::exit"); #if defined (ACE_WIN32) // Remove detached thread handle. if (do_thread_exit) { #if 0 // @@ This callback is now taken care of by TSS_Cleanup. Do we // need it anymore? // On Win32, if we really wants to exit from a thread, we must // first clean up the thread specific storage. By doing so, // ACE_Thread_Manager::exit will be called again with // do_thr_exit = 0 and cleaning up the ACE_Cleanup_Info (but not // exiting the thread.) After the following call returns, we // are safe to exit this thread. delete ACE_Thread_Exit::instance (); #endif /* 0 */ ACE_Thread::exit (status); } #endif /* ACE_WIN32 */ // Just hold onto the guard while finding this thread's id and { ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); // Find the thread id, but don't use the cache. It might have been // deleted already. ACE_thread_t const id = ACE_OS::thr_self (); ACE_Thread_Descriptor* td = this->find_thread (id); if (td != 0) { // @@ We call Thread_Descriptor terminate this realize the cleanup // process itself. td->terminate(); } } if (do_thread_exit) { ACE_Thread::exit (status); // On reasonable systems <ACE_Thread::exit> should not return. // However, due to horrible semantics with Win32 thread-specific // storage this call can return (don't ask...). } return 0; }
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.
{ for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (ACE_OS::thr_cmp (iter.next ()->thr_handle_, h_id)) { return iter.next (); } } return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::find_task"); size_t i = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (i >= slot) break; if (task == iter.next ()->task_) return iter.next (); ++i; } return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::find_thread"); for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (ACE_OS::thr_equal (iter.next ()->thr_id_, t_id)) { return iter.next (); } } return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::get_grp"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); ACE_FIND (this->find_thread (t_id), ptr); if (ptr) grp_id = ptr->grp_id_; else return -1; return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::get_grp"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); ACE_FIND (this->find_task (task), ptr); grp_id = ptr->grp_id_; return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::hthread_descriptor"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); ACE_FIND (this->find_hthread (thr_handle), ptr); return ptr; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::hthread_grp_list"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); size_t hthread_count = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (hthread_count >= n) { break; } if (iter.next ()->grp_id_ == grp_id) { hthread_list[hthread_count] = iter.next ()->thr_handle_; hthread_count++; } } return ACE_Utils::truncate_cast<ssize_t> (hthread_count); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::hthread_list"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); size_t hthread_count = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (hthread_count >= n) { break; } if (iter.next ()->task_ == task) { hthread_list[hthread_count] = iter.next ()->thr_handle_; ++hthread_count; } } return ACE_Utils::truncate_cast<ssize_t> (hthread_count); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::hthread_within"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1)); for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (ACE_OS::thr_cmp(iter.next ()->thr_handle_, handle)) { return 1; } } return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::insert_thr"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); // Check for duplicates and bail out if we're already registered... if (this->find_thread (t_id) != 0 ) return -1; if (grp_id == -1) grp_id = this->grp_id_++; if (this->append_thr (t_id, t_handle, ACE_THR_SPAWNED, grp_id, 0, flags) == -1) return -1; return grp_id; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::instance"); ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Static_Object_Lock::instance (), 0)); ACE_Thread_Manager *t = ACE_Thread_Manager::thr_mgr_; // We can't safely delete it since we don't know who created it! ACE_Thread_Manager::delete_thr_mgr_ = false; ACE_Thread_Manager::thr_mgr_ = tm; return t; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::instance"); if (ACE_Thread_Manager::thr_mgr_ == 0) { // Perform Double-Checked Locking Optimization. ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Static_Object_Lock::instance (), 0)); if (ACE_Thread_Manager::thr_mgr_ == 0) { ACE_NEW_RETURN (ACE_Thread_Manager::thr_mgr_, ACE_Thread_Manager, 0); ACE_Thread_Manager::delete_thr_mgr_ = true; } } return ACE_Thread_Manager::thr_mgr_; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::join"); bool found = false; ACE_Thread_Descriptor_Base tdb; { ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); #if !defined (ACE_HAS_VXTHREADS) for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_); !biter.done (); biter.advance ()) { if (ACE_OS::thr_equal (biter.next ()->thr_id_, tid)) { ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (false); if (ACE_Thread::join (tdb->thr_handle_, status) == -1) { return -1; } delete tdb; // return immediately if we've found the thread we want to join. return 0; } } #endif /* !ACE_HAS_VXTHREADS */ for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { // If threads are created as THR_DETACHED or THR_DAEMON, we // can't help much. if (ACE_OS::thr_equal (iter.next ()->thr_id_,tid) && (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON) || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE))) { tdb = *iter.next (); ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING); found = 1; break; } } if (!found) return -1; // Didn't find the thread we want or the thread is not joinable. } if (ACE_Thread::join (tdb.thr_handle_, status) == -1) return -1; return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::join_thr"); int const result = ACE_Thread::join (td->thr_handle_); if (result != 0) { // Since the thread are being joined, we should // let it remove itself from the list. // this->remove_thr (td); errno = result; return -1; } return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::kill"); ACE_EXECUTE_OP (this->kill_thr, signum); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::kill_all"); return this->apply_all (&ACE_Thread_Manager::kill_thr, sig); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::kill_grp"); return this->apply_grp (grp_id, ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr), signum); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::kill_task"); return this->apply_task (task, ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr)); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::kill_thr"); ACE_thread_t tid = td->thr_id_; int const result = ACE_Thread::kill (tid, signum); if (result != 0) { // Only remove a thread from us when there is a "real" error. if (errno != ENOTSUP) this->thr_to_be_removed_.enqueue_tail (td); return -1; } return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::num_tasks_in_group"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); int tasks_count = 0; size_t i = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (iter.next ()->grp_id_ == grp_id && this->find_task (iter.next ()->task_, i) == 0 && iter.next ()->task_ != 0) { ++tasks_count; } ++i; } return tasks_count; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::num_threads_in_task"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); int threads_count = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (iter.next ()->task_ == task) { ++threads_count; } } return threads_count; }
int ACE_Thread_Manager::open | ( | size_t | size = 0 |
) |
No-op. Currently unused.
Definition at line 236 of file Thread_Manager.inl.
{ // Currently no-op. return 0; }
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.
{ #if defined (ACE_HAS_VXTHREADS) ACE_UNUSED_ARG (td); #else /* ! ACE_HAS_VXTHREADS */ ACE_Thread_Descriptor_Base *tdb = 0; ACE_NEW_RETURN (tdb, ACE_Thread_Descriptor_Base (*td), -1); this->terminated_thr_list_.insert_tail (tdb); #endif /* !ACE_HAS_VXTHREADS */ return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::remove_thr"); td->tm_ = 0; this->thr_list_.remove (td); #if defined (ACE_WIN32) if (close_handler != 0) ::CloseHandle (td->thr_handle_); #else ACE_UNUSED_ARG (close_handler); #endif /* ACE_WIN32 */ this->thread_desc_freelist_.add (td); #if defined (ACE_HAS_THREADS) // Tell all waiters when there are no more threads left in the pool. if (this->thr_list_.size () == 0) this->zero_cond_.broadcast (); #endif /* ACE_HAS_THREADS */ }
void ACE_Thread_Manager::remove_thr_all | ( | void | ) | [protected] |
Remove all threads from the table.
Definition at line 947 of file Thread_Manager.cpp.
{ ACE_Thread_Descriptor *td = 0; while ((td = this->thr_list_.delete_head ()) != 0) { this->remove_thr (td, 1); } }
int ACE_Thread_Manager::resume | ( | ACE_thread_t | t_id | ) |
Resume a single thread.
Definition at line 1092 of file Thread_Manager.cpp.
{ ACE_TRACE ("ACE_Thread_Manager::resume"); ACE_EXECUTE_OP (this->resume_thr, 0); }
int ACE_Thread_Manager::resume_all | ( | void | ) |
Resume all stopped threads.
Definition at line 1381 of file Thread_Manager.cpp.
{ ACE_TRACE ("ACE_Thread_Manager::resume_all"); return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr)); }
int ACE_Thread_Manager::resume_grp | ( | int | grp_id | ) |
Resume a group of threads.
Definition at line 1314 of file Thread_Manager.cpp.
{ ACE_TRACE ("ACE_Thread_Manager::resume_grp"); return this->apply_grp (grp_id, ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr)); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::resume_task"); return this->apply_task (task, ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr)); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::resume_thr"); int const result = ACE_Thread::resume (td->thr_handle_); if (result == -1) { if (errno != ENOTSUP) this->thr_to_be_removed_.enqueue_tail (td); return -1; } else { ACE_CLR_BITS (td->thr_state_, ACE_THR_SUSPENDED); return 0; } }
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.
{ #if 0 // currently unused! ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks"); // @@ Currently, we have just one hook. This should clearly be // generalized to support an arbitrary number of hooks. ACE_Thread_Descriptor *td = this->thread_desc_self (); for (ACE_Cleanup_Info_Node *iter = td->cleanup_info_->pop_front (); iter != 0; iter = cleanup_info_->pop_front ()) { if (iter->cleanup_hook () != 0) { (*iter->cleanup_hook ()) (iter->object (), iter->param ()); } delete iter; } ACE_UNUSED_ARG (i); #else ACE_UNUSED_ARG (i); #endif /* 0 */ }
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.
{ ACE_TRACE ("ACE_Thread_Manager::set_grp"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); ACE_FIND (this->find_thread (t_id), ptr); if (ptr) ptr->grp_id_ = grp_id; else return -1; return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::set_grp"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (iter.next ()->task_ == task) { iter.next ()->grp_id_ = grp_id; } } return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::spawn"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); if (grp_id == -1) grp_id = this->grp_id_++; // Increment the group id. if (priority != ACE_DEFAULT_THREAD_PRIORITY) ACE_CLR_BITS (flags, THR_INHERIT_SCHED); if (this->spawn_i (func, args, flags, t_id, t_handle, priority, grp_id, stack, stack_size, 0, thr_name) == -1) return -1; return grp_id; }
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.
{ // First, threads created by Thread Manager should not be daemon threads. // Using assertion is probably a bit too strong. However, it helps // finding this kind of error as early as possible. Perhaps we can replace // assertion by returning error. ACE_ASSERT (ACE_BIT_DISABLED (flags, THR_DAEMON)); // Create a new thread running <func>. *Must* be called with the // <lock_> held... // Get a "new" Thread Descriptor from the freelist. auto_ptr<ACE_Thread_Descriptor> new_thr_desc (this->thread_desc_freelist_.remove ()); // Reset thread descriptor status new_thr_desc->reset (this); ACE_Thread_Adapter *thread_args = 0; # if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) ACE_NEW_RETURN (thread_args, ACE_Thread_Adapter (func, args, (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME, this, new_thr_desc.get (), ACE_OS_Object_Manager::seh_except_selector(), ACE_OS_Object_Manager::seh_except_handler()), -1); # else ACE_NEW_RETURN (thread_args, ACE_Thread_Adapter (func, args, (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME, this, new_thr_desc.get ()), -1); # endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ auto_ptr <ACE_Base_Thread_Adapter> auto_thread_args (static_cast<ACE_Base_Thread_Adapter *> (thread_args)); ACE_TRACE ("ACE_Thread_Manager::spawn_i"); ACE_hthread_t thr_handle; ACE_thread_t thr_id; if (t_id == 0) t_id = &thr_id; // Acquire the <sync_> lock to block the spawned thread from // removing this Thread Descriptor before it gets put into our // thread table. new_thr_desc->sync_->acquire (); int const result = ACE_Thread::spawn (func, args, flags, t_id, &thr_handle, priority, stack, stack_size, thread_args, thr_name); if (result != 0) { // _Don't_ clobber errno here! result is either 0 or -1, and // ACE_OS::thr_create () already set errno! D. Levine 28 Mar 1997 // errno = result; ACE_Errno_Guard guard (errno); // Lock release may smash errno new_thr_desc->sync_->release (); return -1; } auto_thread_args.release (); #if defined (ACE_HAS_WTHREADS) // Have to duplicate handle if client asks for it. // @@ How are thread handles implemented on AIX? Do they // also need to be duplicated? if (t_handle != 0) # if defined (ACE_LACKS_DUPLICATEHANDLE) *t_handle = thr_handle; # else /* ! ACE_LACKS_DUP */ (void) ::DuplicateHandle (::GetCurrentProcess (), thr_handle, ::GetCurrentProcess (), t_handle, 0, TRUE, DUPLICATE_SAME_ACCESS); # endif /* ! ACE_LACKS_DUP */ #else /* ! ACE_HAS_WTHREADS */ if (t_handle != 0) *t_handle = thr_handle; #endif /* ! ACE_HAS_WTHREADS */ // append_thr also put the <new_thr_desc> into Thread_Manager's // double-linked list. Only after this point, can we manipulate // double-linked list from a spawned thread's context. return this->append_thr (*t_id, thr_handle, ACE_THR_SPAWNED, grp_id, task, flags, new_thr_desc.release ()); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::spawn_n"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); if (grp_id == -1) grp_id = this->grp_id_++; // Increment the group id. for (size_t i = 0; i < n; i++) { // @@ What should happen if this fails?! e.g., should we try to // cancel the other threads that we've already spawned or what? if (this->spawn_i (func, args, flags, thread_ids == 0 ? 0 : &thread_ids[i], thread_handles == 0 ? 0 : &thread_handles[i], priority, grp_id, stack == 0 ? 0 : stack[i], stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i], task, thr_name == 0 ? 0 : &thr_name [i]) == -1) return -1; } return grp_id; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::spawn_n"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); if (grp_id == -1) grp_id = this->grp_id_++; // Increment the group id. for (size_t i = 0; i < n; i++) { // @@ What should happen if this fails?! e.g., should we try to // cancel the other threads that we've already spawned or what? if (this->spawn_i (func, args, flags, 0, thread_handles == 0 ? 0 : &thread_handles[i], priority, grp_id, stack == 0 ? 0 : stack[i], stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i], task, thr_name == 0 ? 0 : &thr_name [i]) == -1) return -1; } return grp_id; }
int ACE_Thread_Manager::suspend | ( | ACE_thread_t | t_id | ) |
Suspend a single thread.
Definition at line 1083 of file Thread_Manager.cpp.
{ ACE_TRACE ("ACE_Thread_Manager::suspend"); ACE_EXECUTE_OP (this->suspend_thr, 0); }
int ACE_Thread_Manager::suspend_all | ( | void | ) |
Suspend all threads.
Definition at line 1388 of file Thread_Manager.cpp.
{ ACE_TRACE ("ACE_Thread_Manager::suspend_all"); return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr)); }
int ACE_Thread_Manager::suspend_grp | ( | int | grp_id | ) |
Suspend a group of threads.
Definition at line 1304 of file Thread_Manager.cpp.
{ ACE_TRACE ("ACE_Thread_Manager::suspend_grp"); return this->apply_grp (grp_id, ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr)); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::suspend_task"); return this->apply_task (task, ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr)); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::suspend_thr"); int const result = ACE_Thread::suspend (td->thr_handle_); if (result == -1) { if (errno != ENOTSUP) this->thr_to_be_removed_.enqueue_tail (td); return -1; } else { ACE_SET_BITS (td->thr_state_, ACE_THR_SUSPENDED); return 0; } }
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.
{ ACE_TRACE ("ACE_Thread_Manager::task"); ACE_Thread_Descriptor *td = this->thread_desc_self () ; if (td == 0) return 0; else return td->task (); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::task_all_list"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); size_t task_list_count = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (task_list_count >= n) { break; } ACE_Task_Base *task_p = iter.next ()->task_; if (0 != task_p) { // This thread has a task pointer; see if it's already in the // list. Don't add duplicates. size_t i = 0; for (; i < task_list_count; ++i) { if (task_list[i] == task_p) { break; } } if (i == task_list_count) // No match - add this one { task_list[task_list_count++] = task_p; } } } return ACE_Utils::truncate_cast<ssize_t> (task_list_count); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::task_list"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); ACE_Task_Base **task_list_iterator = task_list; size_t task_list_count = 0; size_t i = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (task_list_count >= n) { break; } if (iter.next ()->grp_id_ == grp_id && this->find_task (iter.next ()->task_, i) == 0) { task_list_iterator[task_list_count] = iter.next ()->task_; ++task_list_count; } ++i; } return ACE_Utils::truncate_cast<ssize_t> (task_list_count); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::testcancel"); return this->check_state (ACE_THR_CANCELLED, t_id); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::testresume"); return this->check_state (ACE_THR_SUSPENDED, t_id, 0); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::testsuspend"); return this->check_state (ACE_THR_SUSPENDED, t_id); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::testterminate"); return this->check_state (ACE_THR_TERMINATED, t_id); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::thr_self"); ACE_Thread_Descriptor *desc = this->thread_desc_self (); if (desc == 0) return -1; else desc->self (self); return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::thr_self"); return ACE_Thread::self (); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::thr_state"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); int const self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ()); // If we're checking the state of our thread, try to get the cached // value out of TSS to avoid lookup. if (self_check) { ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc (); if (desc == 0) { return 0; // Always return false. } state = desc->thr_state_; } else { // Not calling from self, have to look it up from the list. ACE_FIND (this->find_thread (id), ptr); if (ptr == 0) { return 0; } state = ptr->thr_state_; } return 1; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::thread_all_list"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); size_t thread_count = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (thread_count >= n) { break; } thread_list[thread_count] = iter.next ()->thr_id_; ++thread_count; } return ACE_Utils::truncate_cast<ssize_t> (thread_count); }
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.
{ // This method must be called with lock held. // Try to get it from cache. ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc (); #if 1 // ACE_ASSERT (desc != 0); // Thread descriptor should always get cached. #else if (desc == 0) { ACE_thread_t id = ACE_OS::thr_self (); desc = this->find_thread (id); // Thread descriptor adapter might not have been put into the // list yet. if (desc != 0) // Update the TSS cache. ACE_LOG_MSG->thr_desc (desc); } #endif return desc; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::thread_descriptor"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); ACE_FIND (this->find_thread (thr_id), ptr); return ptr; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::thread_grp_list"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); size_t thread_count = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (thread_count >= n) { break; } if (iter.next ()->grp_id_ == grp_id) { thread_list[thread_count] = iter.next ()->thr_id_; thread_count++; } } return ACE_Utils::truncate_cast<ssize_t> (thread_count); }
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.
{ ACE_TRACE ("ACE_Thread_Manager::thread_list"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); size_t thread_count = 0; for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (thread_count >= n) { break; } if (iter.next ()->task_ == task) { thread_list[thread_count] = iter.next ()->thr_id_; ++thread_count; } } return ACE_Utils::truncate_cast<ssize_t> (thread_count); }
int ACE_Thread_Manager::thread_within | ( | ACE_thread_t | tid | ) |
Definition at line 1209 of file Thread_Manager.cpp.
{ ACE_TRACE ("ACE_Thread_Manager::thread_within"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1)); for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (ACE_OS::thr_equal (iter.next ()->thr_id_, tid)) { return 1; } } return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::wait"); ACE_Time_Value local_timeout; // Check to see if we're using absolute time or not. if (use_absolute_time == false && timeout != 0) { local_timeout = *timeout; local_timeout += ACE_OS::gettimeofday (); timeout = &local_timeout; } #if !defined (ACE_HAS_VXTHREADS) ACE_Double_Linked_List<ACE_Thread_Descriptor_Base> term_thr_list_copy; #endif /* ACE_HAS_VXTHREADS */ #if defined (ACE_HAS_THREADS) { // Just hold onto the guard while waiting. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); if (ACE_Object_Manager::shutting_down () != 1) { // Program is not shutting down. Perform a normal wait on threads. if (abandon_detached_threads != 0) { ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { if (ACE_BIT_ENABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON) && ACE_BIT_DISABLED (iter.next ()->flags_, THR_JOINABLE)) { this->thr_to_be_removed_.enqueue_tail (iter.next ()); ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING); } } if (! this->thr_to_be_removed_.is_empty ()) { ACE_Thread_Descriptor *td = 0; while (this->thr_to_be_removed_.dequeue_head (td) != -1) this->remove_thr (td, 1); } } while (this->thr_list_.size () > 0) if (this->zero_cond_.wait (timeout) == -1) return -1; } else // Program is shutting down, no chance to wait on threads. // Therefore, we'll just remove threads from the list. this->remove_thr_all (); #if !defined (ACE_HAS_VXTHREADS) ACE_Thread_Descriptor_Base* item = 0; while ((item = this->terminated_thr_list_.delete_head ()) != 0) { term_thr_list_copy.insert_tail (item); } #endif /* ACE_HAS_VXTHREADS */ // Release the guard, giving other threads a chance to run. } #if !defined (ACE_HAS_VXTHREADS) // @@ VxWorks doesn't support thr_join (yet.) We are working // on our implementation. Chorus'es thr_join seems broken. ACE_Thread_Descriptor_Base *item = 0; while ((item = term_thr_list_copy.delete_head ()) != 0) { if (ACE_BIT_DISABLED (item->flags_, THR_DETACHED | THR_DAEMON) || ACE_BIT_ENABLED (item->flags_, THR_JOINABLE)) // Detached handles shouldn't reached here. (void) ACE_Thread::join (item->thr_handle_); delete item; } #endif /* !ACE_HAS_VXTHREADS */ #else ACE_UNUSED_ARG (timeout); ACE_UNUSED_ARG (abandon_detached_threads); #endif /* ACE_HAS_THREADS */ return 0; }
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.
{ ACE_TRACE ("ACE_Thread_Manager::wait_grp"); int copy_count = 0; ACE_Thread_Descriptor_Base *copy_table = 0; // We have to make sure that while we wait for these threads to // exit, we do not have the lock. Therefore we make a copy of all // interesting entries and let go of the lock. { ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); #if !defined (ACE_HAS_VXTHREADS) ACE_NEW_RETURN (copy_table, ACE_Thread_Descriptor_Base [this->thr_list_.size () + this->terminated_thr_list_.size ()], -1); #else ACE_NEW_RETURN (copy_table, ACE_Thread_Descriptor_Base [this->thr_list_.size ()], -1); #endif /* !ACE_HAS_VXTHREADS */ for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { // If threads are created as THR_DETACHED or THR_DAEMON, we // can't help much. if (iter.next ()->grp_id_ == grp_id && (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON) || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE))) { ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING); copy_table[copy_count++] = *iter.next (); } } #if !defined (ACE_HAS_VXTHREADS) for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_); !biter.done (); biter.advance ()) { // If threads are created as THR_DETACHED or THR_DAEMON, we // can't help much. if (biter.next ()->grp_id_ == grp_id) { ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (false); copy_table[copy_count++] = *tdb; delete tdb; } } #endif /* !ACE_HAS_VXTHREADS */ } // Now actually join() with all the threads in this group. int result = 0; for (int i = 0; i < copy_count && result != -1; i++) { if (ACE_Thread::join (copy_table[i].thr_handle_) == -1) result = -1; } delete [] copy_table; return result; }
int ACE_Thread_Manager::wait_on_exit | ( | void | ) |
Definition at line 281 of file Thread_Manager.inl.
{ return this->automatic_wait_; }
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.
{ this->automatic_wait_ = do_wait; }
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.
{ int copy_count = 0; ACE_Thread_Descriptor_Base *copy_table = 0; // We have to make sure that while we wait for these threads to // exit, we do not have the lock. Therefore we make a copy of all // interesting entries and let go of the lock. { ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); #if !defined (ACE_HAS_VXTHREADS) ACE_NEW_RETURN (copy_table, ACE_Thread_Descriptor_Base [this->thr_list_.size () + this->terminated_thr_list_.size ()], -1); #else ACE_NEW_RETURN (copy_table, ACE_Thread_Descriptor_Base [this->thr_list_.size ()], -1); #endif /* !ACE_HAS_VXTHREADS */ for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_); !iter.done (); iter.advance ()) { // If threads are created as THR_DETACHED or THR_DAEMON, we // can't wait on them here. if (iter.next ()->task_ == task && (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON) || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE))) { ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING); copy_table[copy_count++] = *iter.next (); } } #if !defined (ACE_HAS_VXTHREADS) for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> titer (this->terminated_thr_list_); !titer.done (); titer.advance ()) { // If threads are created as THR_DETACHED or THR_DAEMON, we can't help much here. if (titer.next ()->task_ == task) { ACE_Thread_Descriptor_Base *tdb = titer.advance_and_remove (false); copy_table[copy_count++] = *tdb; delete tdb; } } #endif /* !ACE_HAS_VXTHREADS */ } // Now to do the actual work int result = 0; for (int i = 0; i < copy_count && result != -1; i++) { if (ACE_Thread::join (copy_table[i].thr_handle_) == -1) result = -1; } delete [] copy_table; return result; }
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.