ACE_Thread_Manager Class Reference

Manages a pool of threads. More...

#include <Thread_Manager.h>

Collaboration diagram for ACE_Thread_Manager:

Collaboration graph
[legend]
List of all members.

Public Types

typedef int(ACE_Thread_Manager::*) ACE_THR_MEMBER_FUNC (ACE_Thread_Descriptor *, int)
 ACE_THR_IDLE = 0x00000000
 Uninitialized.
 ACE_THR_SPAWNED = 0x00000001
 Created but not yet running.
 ACE_THR_RUNNING = 0x00000002
 ACE_THR_SUSPENDED = 0x00000004
 Thread is suspended.
 ACE_THR_CANCELLED = 0x00000008
 ACE_THR_TERMINATED = 0x00000010
 ACE_THR_JOINING = 0x10000000
 Join operation has been invoked on the thread by thread manager.
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
}

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_Basetask (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
Suspend/resume is not supported on all platforms. For example, Pthreads does not support these functions.

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_Managerinstance (void)
 Get pointer to a process-wide ACE_Thread_Manager.
static ACE_Thread_Managerinstance (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_Descriptorthread_desc_self (void)
ACE_Thread_Descriptorthread_descriptor (ACE_thread_t)
ACE_Thread_Descriptorhthread_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_Descriptorfind_thread (ACE_thread_t t_id)
ACE_Thread_Descriptorfind_hthread (ACE_hthread_t h_id)
ACE_Thread_Descriptorfind_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_Descriptorthr_list_
ACE_Double_Linked_List< ACE_Thread_Descriptor_Baseterminated_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_Managerthr_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

Detailed Description

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 380 of file Thread_Manager.h.


Member Typedef Documentation

typedef int(ACE_Thread_Manager::*) ACE_Thread_Manager::ACE_THR_MEMBER_FUNC(ACE_Thread_Descriptor *, int)

Definition at line 390 of file Thread_Manager.h.


Member Enumeration Documentation

anonymous enum

These are the various states a thread managed by the ACE_Thread_Manager can be in.

Enumerator:
ACE_THR_IDLE  Uninitialized.
ACE_THR_SPAWNED  Created but not yet running.
ACE_THR_RUNNING  Thread is active (naturally, we don't know if it's actually running* because we aren't the scheduler...).
ACE_THR_SUSPENDED  Thread is suspended.
ACE_THR_CANCELLED  Thread has been cancelled (which is an indiction that it needs to terminate...).
ACE_THR_TERMINATED  Thread has shutdown, but the slot in the thread manager hasn't been reclaimed yet.
ACE_THR_JOINING  Join operation has been invoked on the thread by thread manager.

Definition at line 395 of file Thread_Manager.h.

00396   {
00397     /// Uninitialized.
00398     ACE_THR_IDLE = 0x00000000,
00399 
00400     /// Created but not yet running.
00401     ACE_THR_SPAWNED = 0x00000001,
00402 
00403     /// Thread is active (naturally, we don't know if it's actually
00404     /// *running* because we aren't the scheduler...).
00405     ACE_THR_RUNNING = 0x00000002,
00406 
00407     /// Thread is suspended.
00408     ACE_THR_SUSPENDED = 0x00000004,
00409 
00410     /// Thread has been cancelled (which is an indiction that it needs to
00411     /// terminate...).
00412     ACE_THR_CANCELLED = 0x00000008,
00413 
00414     /// Thread has shutdown, but the slot in the thread manager hasn't
00415     /// been reclaimed yet.
00416     ACE_THR_TERMINATED = 0x00000010,
00417 
00418     /// Join operation has been invoked on the thread by thread manager.
00419     ACE_THR_JOINING = 0x10000000
00420   };


Constructor & Destructor Documentation

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.

See also:
ACE_Free_List

Definition at line 362 of file Thread_Manager.cpp.

References ACE_TRACE.

00366   : grp_id_ (1),
00367     automatic_wait_ (1)
00368 #if defined (ACE_HAS_THREADS)
00369     , zero_cond_ (lock_)
00370 #endif /* ACE_HAS_THREADS */
00371     , thread_desc_freelist_ (ACE_FREE_LIST_WITH_POOL,
00372                              prealloc, lwm, hwm, inc)
00373 {
00374   ACE_TRACE ("ACE_Thread_Manager::ACE_Thread_Manager");
00375 }

ACE_Thread_Manager::~ACE_Thread_Manager ( void   ) 

Definition at line 457 of file Thread_Manager.cpp.

References ACE_TRACE, and close().

00458 {
00459   ACE_TRACE ("ACE_Thread_Manager::~ACE_Thread_Manager");
00460   this->close ();
00461 }


Member Function Documentation

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  ,
ACE_UINT32  ,
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 786 of file Thread_Manager.cpp.

References ACE_NEW_RETURN, ACE_SET_BITS, ACE_TRACE, ACE_OS_Thread_Descriptor::flags_, ACE_Thread_Descriptor_Base::grp_id_, ACE_Thread_Descriptor::sync_, task(), ACE_Thread_Descriptor_Base::task_, ACE_Thread_Descriptor_Base::thr_handle_, ACE_Thread_Descriptor_Base::thr_id_, thr_list_, ACE_Thread_Descriptor_Base::thr_state_, and ACE_Thread_Descriptor::tm_.

Referenced by spawn_i().

00793 {
00794   ACE_TRACE ("ACE_Thread_Manager::append_thr");
00795   ACE_Thread_Descriptor *thr_desc = 0;
00796 
00797   if (td == 0)
00798     {
00799       ACE_NEW_RETURN (thr_desc,
00800                       ACE_Thread_Descriptor,
00801                       -1);
00802       thr_desc->tm_ = this;
00803       // Setup the Thread_Manager.
00804     }
00805   else
00806     thr_desc = td;
00807 
00808   thr_desc->thr_id_ = t_id;
00809   thr_desc->thr_handle_ = t_handle;
00810   thr_desc->grp_id_ = grp_id;
00811   thr_desc->task_ = task;
00812   thr_desc->flags_ = flags;
00813 
00814   this->thr_list_.insert_head (thr_desc);
00815   ACE_SET_BITS (thr_desc->thr_state_, thr_state);
00816   thr_desc->sync_->release ();
00817 
00818   return 0;
00819 }

int ACE_Thread_Manager::apply_all ( ACE_THR_MEMBER_FUNC  ,
int  = 0 
) [protected]

Apply func to all members of the table.

Definition at line 1319 of file Thread_Manager.cpp.

References ACE_ASSERT, ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Unbounded_Queue< T >::dequeue_head(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and thr_to_be_removed_.

Referenced by cancel_all(), kill_all(), resume_all(), and suspend_all().

01320 {
01321   ACE_TRACE ("ACE_Thread_Manager::apply_all");
01322   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01323   ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01324 
01325   int result = 0;
01326 
01327   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01328        !iter.done ();
01329        iter.advance ())
01330     if ((this->*func)(iter.next (), arg) == -1)
01331       result = -1;
01332 
01333   // Must remove threads after we have traversed the thr_list_ to
01334   // prevent clobber thr_list_'s integrity.
01335 
01336   if (! this->thr_to_be_removed_.is_empty ())
01337     {
01338       // Save/restore errno.
01339       ACE_Errno_Guard error (errno);
01340 
01341       for (ACE_Thread_Descriptor *td;
01342            this->thr_to_be_removed_.dequeue_head (td) != -1;
01343            )
01344         this->remove_thr (td, 1);
01345     }
01346 
01347   return result;
01348 }

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 1245 of file Thread_Manager.cpp.

References ACE_ASSERT, ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Unbounded_Queue< T >::dequeue_head(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and thr_to_be_removed_.

Referenced by cancel_grp(), kill_grp(), resume_grp(), and suspend_grp().

01248 {
01249   ACE_TRACE ("ACE_Thread_Manager::apply_grp");
01250   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01251   ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01252 
01253   int result = 0;
01254 
01255   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01256        !iter.done ();
01257        iter.advance ())
01258     if (iter.next ()->grp_id_ == grp_id)
01259       if ((this->*func) (iter.next (), arg) == -1)
01260         result = -1;
01261 
01262   // Must remove threads after we have traversed the thr_list_ to
01263   // prevent clobber thr_list_'s integrity.
01264 
01265   if (! this->thr_to_be_removed_.is_empty ())
01266     {
01267       // Save/restore errno.
01268       ACE_Errno_Guard error (errno);
01269 
01270       for (ACE_Thread_Descriptor *td;
01271            this->thr_to_be_removed_.dequeue_head (td) != -1;
01272            )
01273         this->remove_thr (td, 1);
01274     }
01275 
01276   return result;
01277 }

int ACE_Thread_Manager::apply_task ( ACE_Task_Base task,
ACE_THR_MEMBER_FUNC  func,
int  = 0 
) [protected]

Apply func to all members of the table that match the task.

Definition at line 1681 of file Thread_Manager.cpp.

References ACE_ASSERT, ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Unbounded_Queue< T >::dequeue_head(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), task(), and thr_to_be_removed_.

Referenced by cancel_task(), kill_task(), resume_task(), and suspend_task().

01684 {
01685   ACE_TRACE ("ACE_Thread_Manager::apply_task");
01686   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01687   ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01688 
01689   int result = 0;
01690 
01691   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01692        !iter.done ();
01693        iter.advance ())
01694     if (iter.next ()->task_ == task
01695         && (this->*func) (iter.next (), arg) == -1)
01696       result = -1;
01697 
01698   // Must remove threads after we have traversed the thr_list_ to
01699   // prevent clobber thr_list_'s integrity.
01700 
01701   if (! this->thr_to_be_removed_.is_empty ())
01702     {
01703       // Save/restore errno.
01704       ACE_Errno_Guard error (errno);
01705 
01706       for (ACE_Thread_Descriptor *td;
01707            this->thr_to_be_removed_.dequeue_head (td) != -1;
01708            )
01709         this->remove_thr (td, 1);
01710     }
01711 
01712   return result;
01713 }

ACE_INLINE int ACE_Thread_Manager::at_exit ( void *  object,
ACE_CLEANUP_FUNC  cleanup_hook,
void *  param 
)

Deprecated:
This function is deprecated. Please use the previous two at_exit method. Notice that you should avoid mixing this method with the previous two at_exit methods.
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 264 of file Thread_Manager.inl.

References ACE_Thread_Descriptor::at_exit(), and thread_desc_self().

00267 {
00268   ACE_Thread_Descriptor *td = this->thread_desc_self ();
00269   if (td == 0)
00270     return -1;
00271   else
00272     return td->at_exit (object,
00273                         cleanup_hook,
00274                         param);
00275 }

ACE_INLINE 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 254 of file Thread_Manager.inl.

References ACE_Thread_Descriptor::at_exit(), and thread_desc_self().

00255 {
00256   ACE_Thread_Descriptor *td = this->thread_desc_self ();
00257   if (td == 0)
00258     return -1;
00259   else
00260     return td->at_exit (at);
00261 }

ACE_INLINE 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 244 of file Thread_Manager.inl.

References ACE_Thread_Descriptor::at_exit(), and thread_desc_self().

Referenced by ACE_OS_Thread_Adapter::invoke(), ACE_Thread_Adapter::invoke_i(), and ACE_Task_Base::svc_run().

00245 {
00246   ACE_Thread_Descriptor *td = this->thread_desc_self ();
00247   if (td == 0)
00248     return -1;
00249   else
00250     return td->at_exit (at);
00251 }

int ACE_Thread_Manager::cancel ( ACE_thread_t  ,
int  async_cancel = 0 
)

Cancel a single thread.

Definition at line 1091 of file Thread_Manager.cpp.

References ACE_EXECUTE_OP, and ACE_TRACE.

01092 {
01093   ACE_TRACE ("ACE_Thread_Manager::cancel");
01094   ACE_EXECUTE_OP (this->cancel_thr, async_cancel);
01095 }

int ACE_Thread_Manager::cancel_all ( int  async_cancel = 0  ) 

Cancel's all the threads.

Definition at line 1374 of file Thread_Manager.cpp.

References ACE_TRACE, apply_all(), and cancel_thr().

01375 {
01376   ACE_TRACE ("ACE_Thread_Manager::cancel_all");
01377   return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01378                           async_cancel);
01379 }

int ACE_Thread_Manager::cancel_grp ( int  grp_id,
int  async_cancel = 0 
)

Cancel a group of threads.

Definition at line 1310 of file Thread_Manager.cpp.

References ACE_TRACE, apply_grp(), and cancel_thr().

01311 {
01312   ACE_TRACE ("ACE_Thread_Manager::cancel_grp");
01313   return this->apply_grp (grp_id,
01314                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01315                           async_cancel);
01316 }

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 1818 of file Thread_Manager.cpp.

References ACE_TRACE, apply_task(), cancel_thr(), and task().

01820 {
01821   ACE_TRACE ("ACE_Thread_Manager::cancel_task");
01822   return this->apply_task (task,
01823                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01824                            async_cancel);
01825 }

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 1014 of file Thread_Manager.cpp.

References ACE_SET_BITS, ACE_THR_CANCELLED, ACE_TRACE, ACE_Thread::cancel(), ACE_Thread_Descriptor_Base::thr_id_, and ACE_Thread_Descriptor_Base::thr_state_.

Referenced by cancel_all(), cancel_grp(), and cancel_task().

01015 {
01016   ACE_TRACE ("ACE_Thread_Manager::cancel_thr");
01017   // Must set the state first and then try to cancel the thread.
01018   ACE_SET_BITS (td->thr_state_, ACE_THR_CANCELLED);
01019 
01020   if (async_cancel != 0)
01021     // Note that this call only does something relevant if the OS
01022     // platform supports asynchronous thread cancellation.  Otherwise,
01023     // it's a no-op.
01024     return ACE_Thread::cancel (td->thr_id_);
01025 
01026   return 0;
01027 }

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 1107 of file Thread_Manager.cpp.

References ACE_BIT_DISABLED, ACE_BIT_ENABLED, ACE_FIND, ACE_GUARD_RETURN, ACE_LOG_MSG, ACE_TRACE, ACE_OS::thr_equal(), ACE_OS::thr_self(), thr_state(), and ACE_Thread_Descriptor_Base::thr_state_.

Referenced by testcancel(), testresume(), testsuspend(), and testterminate().

01110 {
01111   ACE_TRACE ("ACE_Thread_Manager::check_state");
01112   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01113 
01114   ACE_UINT32 thr_state;
01115 
01116   int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ());
01117 
01118   // If we're checking the state of our thread, try to get the cached
01119   // value out of TSS to avoid lookup.
01120   if (self_check)
01121     {
01122       ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc ();
01123       if (desc == 0)
01124         return 0;               // Always return false.
01125       thr_state = desc->thr_state_;
01126     }
01127   else
01128     {
01129       // Not calling from self, have to look it up from the list.
01130       ACE_FIND (this->find_thread (id), ptr);
01131       if (ptr == 0)
01132         return 0;
01133       thr_state = ptr->thr_state_;
01134     }
01135   if (enable)
01136     return ACE_BIT_ENABLED (thr_state, state);
01137 
01138   return ACE_BIT_DISABLED (thr_state, state);
01139 }

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 440 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, remove_thr_all(), and wait().

Referenced by ~ACE_Thread_Manager().

00441 {
00442   ACE_TRACE ("ACE_Thread_Manager::close");
00443 
00444   // Clean up the thread descriptor list.
00445   if (this->automatic_wait_)
00446     this->wait (0, 1);
00447   else
00448     {
00449       ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00450 
00451       this->remove_thr_all ();
00452     }
00453 
00454   return 0;
00455 }

void ACE_Thread_Manager::close_singleton ( void   )  [static]

Delete the dynamically allocated Singleton.

Definition at line 417 of file Thread_Manager.cpp.

References ACE_GUARD, ACE_TRACE, and ACE_Thread_Exit::cleanup().

Referenced by ACE_Object_Manager::fini().

00418 {
00419   ACE_TRACE ("ACE_Thread_Manager::close_singleton");
00420 
00421   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00422                      *ACE_Static_Object_Lock::instance ()));
00423 
00424   if (ACE_Thread_Manager::delete_thr_mgr_)
00425     {
00426       // First, we clean up the thread descriptor list.
00427       ACE_Thread_Manager::thr_mgr_->close ();
00428       delete ACE_Thread_Manager::thr_mgr_;
00429       ACE_Thread_Manager::thr_mgr_ = 0;
00430       ACE_Thread_Manager::delete_thr_mgr_ = false;
00431     }
00432 
00433   ACE_Thread_Exit::cleanup (ACE_Thread_Manager::thr_exit_);
00434 }

ACE_INLINE 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 303 of file Thread_Manager.inl.

References thr_list_.

00304 {
00305   return this->thr_list_.size ();
00306 }

void ACE_Thread_Manager::dump ( void   ) 

Dump the state of an object.

Definition at line 67 of file Thread_Manager.cpp.

References ACE_BEGIN_DUMP, ACE_DEBUG, ACE_END_DUMP, ACE_GUARD, ACE_TEXT, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), grp_id_, LM_DEBUG, ACE_Double_Linked_List_Iterator_Base< T >::next(), and thr_list_.

00068 {
00069 #if defined (ACE_HAS_DUMP)
00070   ACE_TRACE ("ACE_Thread_Manager::dump");
00071   // Cast away const-ness of this in order to use its non-const lock_.
00072   ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon,
00073                      ((ACE_Thread_Manager *) this)->lock_));
00074 
00075   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00076 
00077   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ngrp_id_ = %d"), this->grp_id_));
00078   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncurrent_count_ = %d"), this->thr_list_.size ()));
00079 
00080   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
00081        !iter.done ();
00082        iter.advance ())
00083     iter.next ()->dump ();
00084 
00085   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00086 #endif /* 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.

Parameters:
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 1533 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Thread::exit(), find_thread(), ACE_Thread_Exit::instance(), ACE_Thread_Descriptor::terminate(), and ACE_OS::thr_self().

Referenced by ACE_Thread_Control::exit().

01534 {
01535   ACE_TRACE ("ACE_Thread_Manager::exit");
01536 #if defined (ACE_WIN32)
01537   // Remove detached thread handle.
01538 
01539   if (do_thread_exit)
01540     {
01541 #if 0
01542       // @@ This callback is now taken care of by TSS_Cleanup.  Do we
01543       //    need it anymore?
01544 
01545       // On Win32, if we really wants to exit from a thread, we must
01546       // first  clean up the thread specific storage.  By doing so,
01547       // ACE_Thread_Manager::exit will be called again with
01548       // do_thr_exit = 0 and cleaning up the ACE_Cleanup_Info (but not
01549       // exiting the thread.)  After the following call returns, we
01550       // are safe to exit this thread.
01551       delete ACE_Thread_Exit::instance ();
01552 #endif /* 0 */
01553       ACE_Thread::exit (status);
01554     }
01555 #endif /* ACE_WIN32 */
01556 
01557   // Just hold onto the guard while finding this thread's id and
01558   {
01559     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
01560 
01561     // Find the thread id, but don't use the cache.  It might have been
01562     // deleted already.
01563     ACE_thread_t const id = ACE_OS::thr_self ();
01564     ACE_Thread_Descriptor* td = this->find_thread (id);
01565     if (td != 0)
01566      {
01567        // @@ We call Thread_Descriptor terminate this realize the cleanup
01568        // process itself.
01569        td->terminate();
01570      }
01571   }
01572 
01573   if (do_thread_exit)
01574     {
01575       ACE_Thread::exit (status);
01576       // On reasonable systems <ACE_Thread::exit> should not return.
01577       // However, due to horrible semantics with Win32 thread-specific
01578       // storage this call can return (don't ask...).
01579     }
01580 
01581   return 0;
01582 }

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 824 of file Thread_Manager.cpp.

References ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and ACE_OS::thr_cmp().

00825 {
00826   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
00827        !iter.done ();
00828        iter.advance ())
00829     if (ACE_OS::thr_cmp (iter.next ()->thr_handle_, h_id))
00830       return iter.next ();
00831 
00832   return 0;
00833 }

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 1832 of file Thread_Manager.cpp.

References ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and task().

Referenced by num_tasks_in_group(), and task_list().

01833 {
01834   ACE_TRACE ("ACE_Thread_Manager::find_task");
01835 
01836   size_t i = 0;
01837 
01838   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01839        !iter.done ();
01840        iter.advance ())
01841     {
01842       if (i >= slot)
01843         break;
01844 
01845       if (task == iter.next ()->task_)
01846         return iter.next ();
01847 
01848       ++i;
01849     }
01850 
01851   return 0;
01852 }

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 839 of file Thread_Manager.cpp.

References ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and ACE_OS::thr_equal().

Referenced by exit(), and thread_desc_self().

00840 {
00841   ACE_TRACE ("ACE_Thread_Manager::find_thread");
00842 
00843   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
00844        !iter.done ();
00845        iter.advance ())
00846     if (ACE_OS::thr_equal (iter.next ()->thr_id_, t_id))
00847       return iter.next ();
00848   return 0;
00849 }

int ACE_Thread_Manager::get_grp ( ACE_Task_Base task,
int &  grp_id 
)

Get group ids for a particular task.

Definition at line 2153 of file Thread_Manager.cpp.

References ACE_FIND, ACE_GUARD_RETURN, ACE_TRACE, and task().

02154 {
02155   ACE_TRACE ("ACE_Thread_Manager::get_grp");
02156   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02157 
02158   ACE_FIND (this->find_task (task), ptr);
02159   grp_id = ptr->grp_id_;
02160   return 0;
02161 }

int ACE_Thread_Manager::get_grp ( ACE_thread_t  ,
int &  grp_id 
)

Get group ids for a particular thread id.

Definition at line 1212 of file Thread_Manager.cpp.

References ACE_FIND, ACE_GUARD_RETURN, and ACE_TRACE.

01213 {
01214   ACE_TRACE ("ACE_Thread_Manager::get_grp");
01215   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01216 
01217   ACE_FIND (this->find_thread (t_id), ptr);
01218 
01219   if (ptr)
01220     grp_id = ptr->grp_id_;
01221   else
01222     return -1;
01223   return 0;
01224 }

ACE_Thread_Descriptor * ACE_Thread_Manager::hthread_descriptor ( ACE_hthread_t   )  [protected]

Return a pointer to the thread's Thread_Descriptor, 0 if fail.

Definition at line 333 of file Thread_Manager.cpp.

References ACE_FIND, ACE_GUARD_RETURN, and ACE_TRACE.

00334 {
00335   ACE_TRACE ("ACE_Thread_Manager::hthread_descriptor");
00336   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00337 
00338   ACE_FIND (this->find_hthread (thr_handle), ptr);
00339   return ptr;
00340 }

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 2111 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), and ACE_Double_Linked_List_Iterator_Base< T >::next().

02114 {
02115   ACE_TRACE ("ACE_Thread_Manager::hthread_grp_list");
02116   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02117 
02118   size_t hthread_count = 0;
02119 
02120   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02121        !iter.done ();
02122        iter.advance ())
02123     {
02124       if (hthread_count >= n)
02125         break;
02126 
02127       if (iter.next ()->grp_id_ == grp_id)
02128         {
02129           hthread_list[hthread_count] = iter.next ()->thr_handle_;
02130           hthread_count++;
02131         }
02132     }
02133 
02134   return hthread_count;
02135 }

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 2055 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and task().

02058 {
02059   ACE_TRACE ("ACE_Thread_Manager::hthread_list");
02060   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02061 
02062   size_t hthread_count = 0;
02063 
02064   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02065        !iter.done ();
02066        iter.advance ())
02067     {
02068       if (hthread_count >= n)
02069         break;
02070 
02071       if (iter.next ()->task_ == task)
02072         {
02073           hthread_list[hthread_count] = iter.next ()->thr_handle_;
02074           ++hthread_count;
02075         }
02076     }
02077 
02078   return hthread_count;
02079 }

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 1180 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and ACE_OS::thr_cmp().

01181 {
01182   ACE_TRACE ("ACE_Thread_Manager::hthread_within");
01183   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01184 
01185   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01186        !iter.done ();
01187        iter.advance ())
01188     if (ACE_OS::thr_cmp(iter.next ()->thr_handle_, handle))
01189       return 1;
01190 
01191   return 0;
01192 }

int ACE_Thread_Manager::insert_thr ( ACE_thread_t  t_id,
ACE_hthread_t  ,
int  grp_id = -1,
long  flags = 0 
) [protected]

Insert a thread in the table (checks for duplicates).

Definition at line 855 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_THR_SPAWNED, ACE_TRACE, and grp_id_.

Referenced by ACE_Thread_Control::ACE_Thread_Control(), and ACE_Thread_Control::insert().

00859 {
00860   ACE_TRACE ("ACE_Thread_Manager::insert_thr");
00861   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00862 
00863   // Check for duplicates and bail out if we're already registered...
00864   if (this->find_thread (t_id) != 0 )
00865     return -1;
00866 
00867   if (grp_id == -1)
00868     grp_id = this->grp_id_++;
00869 
00870   if (this->append_thr (t_id,
00871                         t_handle,
00872                         ACE_THR_SPAWNED,
00873                         grp_id,
00874                         0,
00875                         flags) == -1)
00876     return -1;
00877 
00878   return grp_id;
00879 }

ACE_Thread_Manager * ACE_Thread_Manager::instance ( ACE_Thread_Manager  )  [static]

Set pointer to a process-wide ACE_Thread_Manager and return existing pointer.

Definition at line 402 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, and ACE_TRACE.

00403 {
00404   ACE_TRACE ("ACE_Thread_Manager::instance");
00405   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00406                             *ACE_Static_Object_Lock::instance (), 0));
00407 
00408   ACE_Thread_Manager *t = ACE_Thread_Manager::thr_mgr_;
00409   // We can't safely delete it since we don't know who created it!
00410   ACE_Thread_Manager::delete_thr_mgr_ = false;
00411 
00412   ACE_Thread_Manager::thr_mgr_ = tm;
00413   return t;
00414 }

ACE_Thread_Manager * ACE_Thread_Manager::instance ( void   )  [static]

Get pointer to a process-wide ACE_Thread_Manager.

Definition at line 379 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_NEW_RETURN, and ACE_TRACE.

Referenced by ACE_Schedule_All_Threaded_Strategy< SVC_HANDLER >::ACE_Schedule_All_Threaded_Strategy(), and ACE_Task_Base::activate().

00380 {
00381   ACE_TRACE ("ACE_Thread_Manager::instance");
00382 
00383   if (ACE_Thread_Manager::thr_mgr_ == 0)
00384     {
00385       // Perform Double-Checked Locking Optimization.
00386       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00387                                 *ACE_Static_Object_Lock::instance (), 0));
00388 
00389       if (ACE_Thread_Manager::thr_mgr_ == 0)
00390         {
00391           ACE_NEW_RETURN (ACE_Thread_Manager::thr_mgr_,
00392                           ACE_Thread_Manager,
00393                           0);
00394           ACE_Thread_Manager::delete_thr_mgr_ = true;
00395         }
00396     }
00397 
00398   return ACE_Thread_Manager::thr_mgr_;
00399 }

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 1382 of file Thread_Manager.cpp.

References ACE_BIT_DISABLED, ACE_BIT_ENABLED, ACE_GUARD_RETURN, ACE_SET_BITS, ACE_THR_JOINING, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator< T >::advance_and_remove(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Thread::join(), ACE_Double_Linked_List_Iterator_Base< T >::next(), THR_DAEMON, THR_DETACHED, ACE_OS::thr_equal(), ACE_Thread_Descriptor_Base::thr_handle_, and THR_JOINABLE.

01383 {
01384   ACE_TRACE ("ACE_Thread_Manager::join");
01385 
01386   ACE_Thread_Descriptor_Base tdb;
01387   int found = 0;
01388 
01389   {
01390     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01391 
01392 #if !defined (ACE_HAS_VXTHREADS)
01393     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_);
01394          !biter.done ();
01395          biter.advance ())
01396       if (ACE_OS::thr_equal (biter.next ()->thr_id_, tid))
01397         {
01398           ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (0);
01399 # if defined (_AIX)
01400   // The AIX xlC compiler does not match the proper function here - it
01401   // confuses ACE_Thread::join(ACE_thread_t, ACE_thread_t *, void **=0) and
01402   // ACE_Thread::join(ACE_hthread_t, void **=0).  At least at 3.1.4.7 and .8.
01403   // The 2nd arg is ignored for pthreads anyway.
01404 
01405   // And, g++ on AIX needs the three-arg thr_join, also, to pick up the
01406   // proper version from the AIX libraries.
01407           if (ACE_Thread::join (tdb->thr_handle_,
01408                                 &tdb->thr_handle_,
01409                                 status) == -1)
01410 # else  /* ! _AIX */
01411           if (ACE_Thread::join (tdb->thr_handle_, status) == -1)
01412 # endif /* ! _AIX */
01413             return -1;
01414 
01415           delete tdb;
01416           return 0;
01417           // return immediately if we've found the thread we want to join.
01418         }
01419 #endif /* !ACE_HAS_VXTHREADS */
01420 
01421     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01422          !iter.done ();
01423          iter.advance ())
01424       // If threads are created as THR_DETACHED or THR_DAEMON, we
01425       // can't help much.
01426       if (ACE_OS::thr_equal (iter.next ()->thr_id_,tid) &&
01427           (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON)
01428            || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE)))
01429         {
01430           tdb = *iter.next ();
01431           ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01432           found = 1;
01433           break;
01434         }
01435 
01436     if (found == 0)
01437       return -1;
01438     // Didn't find the thread we want or the thread is not joinable.
01439   }
01440 
01441 # if defined (_AIX)
01442   // The AIX xlC compiler does not match the proper function here - it
01443   // confuses ACE_Thread::join(ACE_thread_t, ACE_thread_t *, void **=0) and
01444   // ACE_Thread::join(ACE_hthread_t, void **=0).  At least at 3.1.4.7 and .8.
01445   // The 2nd arg is ignored for pthreads anyway.
01446 
01447   // And, g++ on AIX needs the three-arg thr_join, also, to pick up the
01448   // proper version from the AIX libraries.
01449   if (ACE_Thread::join (tdb.thr_handle_, &tdb.thr_handle_, status) == -1)
01450 # else  /* ! _AIX */
01451   if (ACE_Thread::join (tdb.thr_handle_, status) == -1)
01452 # endif /* ! _AIX */
01453     return -1;
01454 
01455   return 0;
01456 }

int ACE_Thread_Manager::join_thr ( ACE_Thread_Descriptor td,
int  = 0 
) [protected]

Join the thread described in td.

Definition at line 962 of file Thread_Manager.cpp.

References ACE_TRACE, ACE_Thread::join(), and ACE_Thread_Descriptor_Base::thr_handle_.

00963 {
00964   ACE_TRACE ("ACE_Thread_Manager::join_thr");
00965   int const result = ACE_Thread::join (td->thr_handle_);
00966   if (result != 0)
00967     {
00968       // Since the thread are being joined, we should
00969       // let it remove itself from the list.
00970 
00971       //      this->remove_thr (td);
00972       errno = result;
00973       return -1;
00974     }
00975 
00976   return 0;
00977 }

int ACE_Thread_Manager::kill ( ACE_thread_t  ,
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 1100 of file Thread_Manager.cpp.

References ACE_EXECUTE_OP, and ACE_TRACE.

01101 {
01102   ACE_TRACE ("ACE_Thread_Manager::kill");
01103   ACE_EXECUTE_OP (this->kill_thr, signum);
01104 }

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 1367 of file Thread_Manager.cpp.

References ACE_TRACE, apply_all(), and kill_thr().

01368 {
01369   ACE_TRACE ("ACE_Thread_Manager::kill_all");
01370   return this->apply_all (&ACE_Thread_Manager::kill_thr, sig);
01371 }

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 1300 of file Thread_Manager.cpp.

References ACE_TRACE, apply_grp(), and kill_thr().

01301 {
01302   ACE_TRACE ("ACE_Thread_Manager::kill_grp");
01303   return this->apply_grp (grp_id,
01304                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr), signum);
01305 }

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 1809 of file Thread_Manager.cpp.

References ACE_TRACE, apply_task(), kill_thr(), and task().

01810 {
01811   ACE_TRACE ("ACE_Thread_Manager::kill_task");
01812   return this->apply_task (task,
01813                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr));
01814 }

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 1030 of file Thread_Manager.cpp.

References ACE_TRACE, ENOTSUP, ACE_Unbounded_Queue< T >::enqueue_tail(), ACE_Thread::kill(), ACE_Thread_Descriptor_Base::thr_id_, and thr_to_be_removed_.

Referenced by kill_all(), kill_grp(), and kill_task().

01031 {
01032   ACE_TRACE ("ACE_Thread_Manager::kill_thr");
01033 
01034   ACE_thread_t tid = td->thr_id_;
01035 
01036   int const result = ACE_Thread::kill (tid, signum);
01037 
01038   if (result != 0)
01039     {
01040       // Only remove a thread from us when there is a "real" error.
01041       if (errno != ENOTSUP)
01042         this->thr_to_be_removed_.enqueue_tail (td);
01043 
01044       return -1;
01045     }
01046 
01047     return 0;
01048 }

int ACE_Thread_Manager::num_tasks_in_group ( int  grp_id  ) 

Returns the number of ACE_Task_Base in a group.

Definition at line 1857 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), find_task(), and ACE_Double_Linked_List_Iterator_Base< T >::next().

01858 {
01859   ACE_TRACE ("ACE_Thread_Manager::num_tasks_in_group");
01860   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01861 
01862   int tasks_count = 0;
01863   size_t i = 0;
01864 
01865   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01866        !iter.done ();
01867        iter.advance ())
01868     {
01869       if (iter.next ()->grp_id_ == grp_id
01870           && this->find_task (iter.next ()->task_, i) == 0
01871           && iter.next ()->task_ != 0)
01872         ++tasks_count;
01873 
01874       ++i;
01875     }
01876   return tasks_count;
01877 }

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 1882 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and task().

01883 {
01884   ACE_TRACE ("ACE_Thread_Manager::num_threads_in_task");
01885   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01886 
01887   int threads_count = 0;
01888 
01889   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01890        !iter.done ();
01891        iter.advance ())
01892     if (iter.next ()->task_ == task)
01893       ++threads_count;
01894 
01895   return threads_count;
01896 }

ACE_INLINE int ACE_Thread_Manager::open ( size_t  size = 0  ) 

No-op. Currently unused.

Definition at line 237 of file Thread_Manager.inl.

00238 {
00239   // Currently no-op.
00240   return 0;
00241 }

ACE_INLINE 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 290 of file Thread_Manager.inl.

References ACE_NEW_RETURN, and terminated_thr_list_.

Referenced by ACE_Thread_Descriptor::terminate().

00291 {
00292 #if defined (ACE_HAS_VXTHREADS)
00293   ACE_UNUSED_ARG (td);
00294 #else  /* ! ACE_HAS_VXTHREADS */
00295   ACE_Thread_Descriptor_Base *tdb = 0;
00296   ACE_NEW_RETURN (tdb, ACE_Thread_Descriptor_Base (*td), -1);
00297   this->terminated_thr_list_.insert_tail (tdb);
00298 #endif /* !ACE_HAS_VXTHREADS */
00299   return 0;
00300 }

void ACE_Thread_Manager::remove_thr ( ACE_Thread_Descriptor td,
int  close_handler 
) [protected]

Remove thread from the table.

Definition at line 910 of file Thread_Manager.cpp.

References ACE_TRACE, ACE_Locked_Free_List< T, ACE_LOCK >::add(), ACE_Thread_Descriptor_Base::thr_handle_, thr_list_, thread_desc_freelist_, and ACE_Thread_Descriptor::tm_.

Referenced by remove_thr_all(), and ACE_Thread_Descriptor::terminate().

00912 {
00913   ACE_TRACE ("ACE_Thread_Manager::remove_thr");
00914 
00915   td->tm_ = 0;
00916   this->thr_list_.remove (td);
00917 
00918 #if defined (ACE_WIN32)
00919   if (close_handler != 0)
00920     ::CloseHandle (td->thr_handle_);
00921 #else
00922   ACE_UNUSED_ARG (close_handler);
00923 #endif /* ACE_WIN32 */
00924 
00925   this->thread_desc_freelist_.add (td);
00926 
00927 #if defined (ACE_HAS_THREADS)
00928   // Tell all waiters when there are no more threads left in the pool.
00929   if (this->thr_list_.size () == 0)
00930     this->zero_cond_.broadcast ();
00931 #endif /* ACE_HAS_THREADS */
00932 }

void ACE_Thread_Manager::remove_thr_all ( void   )  [protected]

Remove all threads from the table.

Definition at line 937 of file Thread_Manager.cpp.

References remove_thr().

Referenced by close(), and wait().

00938 {
00939   ACE_Thread_Descriptor *td = 0;
00940 
00941   while ((td = this->thr_list_.delete_head ()) != 0)
00942     {
00943       this->remove_thr (td, 1);
00944     }
00945 }

int ACE_Thread_Manager::resume ( ACE_thread_t   ) 

Resume a single thread.

Definition at line 1082 of file Thread_Manager.cpp.

References ACE_EXECUTE_OP, and ACE_TRACE.

01083 {
01084   ACE_TRACE ("ACE_Thread_Manager::resume");
01085   ACE_EXECUTE_OP (this->resume_thr, 0);
01086 }

int ACE_Thread_Manager::resume_all ( void   ) 

Resume all stopped threads.

Definition at line 1353 of file Thread_Manager.cpp.

References ACE_TRACE, apply_all(), and resume_thr().

Referenced by ACE_Schedule_All_Threaded_Strategy< SVC_HANDLER >::resume().

01354 {
01355   ACE_TRACE ("ACE_Thread_Manager::resume_all");
01356   return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01357 }

int ACE_Thread_Manager::resume_grp ( int  grp_id  ) 

Resume a group of threads.

Definition at line 1290 of file Thread_Manager.cpp.

References ACE_TRACE, apply_grp(), and resume_thr().

01291 {
01292   ACE_TRACE ("ACE_Thread_Manager::resume_grp");
01293   return this->apply_grp (grp_id,
01294                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01295 }

int ACE_Thread_Manager::resume_task ( ACE_Task_Base task  ) 

Resume all threads in an ACE_Task.

Definition at line 1799 of file Thread_Manager.cpp.

References ACE_TRACE, apply_task(), resume_thr(), and task().

Referenced by ACE_Task_Base::resume().

01800 {
01801   ACE_TRACE ("ACE_Thread_Manager::resume_task");
01802   return this->apply_task (task,
01803                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01804 }

int ACE_Thread_Manager::resume_thr ( ACE_Thread_Descriptor td,
int  = 0 
) [protected]

Resume the thread described in td.

Definition at line 997 of file Thread_Manager.cpp.

References ACE_CLR_BITS, ACE_THR_SUSPENDED, ACE_TRACE, ENOTSUP, ACE_Unbounded_Queue< T >::enqueue_tail(), ACE_Thread::resume(), ACE_Thread_Descriptor_Base::thr_handle_, ACE_Thread_Descriptor_Base::thr_state_, and thr_to_be_removed_.

Referenced by resume_all(), resume_grp(), and resume_task().

00998 {
00999   ACE_TRACE ("ACE_Thread_Manager::resume_thr");
01000 
01001   int const result = ACE_Thread::resume (td->thr_handle_);
01002   if (result == -1) {
01003     if (errno != ENOTSUP)
01004       this->thr_to_be_removed_.enqueue_tail (td);
01005     return -1;
01006   }
01007   else {
01008     ACE_CLR_BITS (td->thr_state_, ACE_THR_SUSPENDED);
01009     return 0;
01010   }
01011 }

void ACE_Thread_Manager::run_thread_exit_hooks ( int  i  )  [protected]

Run the registered hooks when the thread exits.

Definition at line 884 of file Thread_Manager.cpp.

References ACE_TRACE, ACE_Cleanup_Info::cleanup_hook_, ACE_Thread_Descriptor::cleanup_info_, ACE_Cleanup_Info::object_, ACE_Cleanup_Info::param_, and thread_desc_self().

00885 {
00886 #if 0 // currently unused!
00887   ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks");
00888 
00889   // @@ Currently, we have just one hook.  This should clearly be
00890   // generalized to support an arbitrary number of hooks.
00891 
00892   ACE_Thread_Descriptor *td = this->thread_desc_self ();
00893   if (td != 0 && td->cleanup_info.cleanup_hook_ != 0)
00894     {
00895       (*td->cleanup_info_.cleanup_hook_)
00896         (td->cleanup_info_.object_,
00897          td->cleanup_info_.param_);
00898 
00899       td->cleanup_info_.cleanup_hook_ = 0;
00900     }
00901   ACE_UNUSED_ARG (i);
00902 #else
00903   ACE_UNUSED_ARG (i);
00904 #endif /* 0 */
00905 }

int ACE_Thread_Manager::set_grp ( ACE_Task_Base task,
int  grp_id 
)

Set group ids for a particular task.

Definition at line 2138 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and task().

02139 {
02140   ACE_TRACE ("ACE_Thread_Manager::set_grp");
02141   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02142 
02143   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02144        !iter.done ();
02145        iter.advance ())
02146     if (iter.next ()->task_ == task)
02147       iter.next ()->grp_id_ = grp_id;
02148 
02149   return 0;
02150 }

int ACE_Thread_Manager::set_grp ( ACE_thread_t  ,
int  grp_id 
)

Set group ids for a particular thread id.

Definition at line 1229 of file Thread_Manager.cpp.

References ACE_FIND, ACE_GUARD_RETURN, and ACE_TRACE.

01230 {
01231   ACE_TRACE ("ACE_Thread_Manager::set_grp");
01232   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01233 
01234   ACE_FIND (this->find_thread (t_id), ptr);
01235   if (ptr)
01236     ptr->grp_id_ = grp_id;
01237   else
01238     return -1;
01239   return 0;
01240 }

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.

Referenced by ACE_Thread_Exit::instance().

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.

Parameters:
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.
See also:
ACE_OS::thr_create() for descriptions of the possible flags values and their interactions.
Parameters:
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.
Return values:
-1 on failure; errno contains an error value.
The group id of the spawned thread.

Definition at line 660 of file Thread_Manager.cpp.

References ACE_CLR_BITS, ACE_DEFAULT_THREAD_PRIORITY, ACE_GUARD_RETURN, ACE_TRACE, grp_id_, and THR_INHERIT_SCHED.

Referenced by ACE_Event_Handler::register_stdin_handler().

00670 {
00671   ACE_TRACE ("ACE_Thread_Manager::spawn");
00672 
00673   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00674 
00675   if (grp_id == -1)
00676     grp_id = this->grp_id_++; // Increment the group id.
00677 
00678   if (priority != ACE_DEFAULT_THREAD_PRIORITY)
00679     ACE_CLR_BITS (flags, THR_INHERIT_SCHED);
00680 
00681   if (this->spawn_i (func,
00682                      args,
00683                      flags,
00684                      t_id,
00685                      t_handle,
00686                      priority,
00687                      grp_id,
00688                      stack,
00689                      stack_size,
00690                      0,
00691                      thr_name) == -1)
00692     return -1;
00693 
00694   return grp_id;
00695 }

int ACE_Thread_Manager::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 
) [protected]

Create a new thread (must be called with locks held).

Definition at line 544 of file Thread_Manager.cpp.

References ACE_ASSERT, ACE_BIT_DISABLED, ACE_NEW_RETURN, ACE_THR_SPAWNED, ACE_THREAD_ADAPTER_NAME, ACE_TRACE, append_thr(), ACE_Auto_Basic_Ptr< X >::release(), ACE_Thread::spawn(), task(), and THR_DAEMON.

00555 {
00556   // First, threads created by Thread Manager should not be daemon threads.
00557   // Using assertion is probably a bit too strong.  However, it helps
00558   // finding this kind of error as early as possible.  Perhaps we can replace
00559   // assertion by returning error.
00560   ACE_ASSERT (ACE_BIT_DISABLED (flags, THR_DAEMON));
00561 
00562   // Create a new thread running <func>.  *Must* be called with the
00563   // <lock_> held...
00564   // Get a "new" Thread Descriptor from the freelist.
00565   auto_ptr<ACE_Thread_Descriptor> new_thr_desc (this->thread_desc_freelist_.remove ());
00566 
00567   // Reset thread descriptor status
00568   new_thr_desc->reset (this);
00569 
00570   ACE_Thread_Adapter *thread_args = 0;
00571 # if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
00572   ACE_NEW_RETURN (thread_args,
00573                   ACE_Thread_Adapter (func,
00574                                       args,
00575                                       (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME,
00576                                       this,
00577                                       new_thr_desc.get (),
00578                                       ACE_OS_Object_Manager::seh_except_selector(),
00579                                       ACE_OS_Object_Manager::seh_except_handler()),
00580                   -1);
00581 # else
00582   ACE_NEW_RETURN (thread_args,
00583                   ACE_Thread_Adapter (func,
00584                                       args,
00585                                       (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME,
00586                                       this,
00587                                       new_thr_desc.get ()),
00588                   -1);
00589 # endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
00590   auto_ptr <ACE_Base_Thread_Adapter> auto_thread_args (static_cast<ACE_Base_Thread_Adapter *> (thread_args));
00591 
00592   ACE_TRACE ("ACE_Thread_Manager::spawn_i");
00593   ACE_hthread_t thr_handle;
00594 
00595   ACE_thread_t thr_id;
00596   if (t_id == 0)
00597     t_id = &thr_id;
00598 
00599   // Acquire the <sync_> lock to block the spawned thread from
00600   // removing this Thread Descriptor before it gets put into our
00601   // thread table.
00602   new_thr_desc->sync_->acquire ();
00603 
00604   int const result = ACE_Thread::spawn (func,
00605                                         args,
00606                                         flags,
00607                                         t_id,
00608                                         &thr_handle,
00609                                         priority,
00610                                         stack,
00611                                         stack_size,
00612                                         thread_args,
00613                                         thr_name);
00614 
00615   if (result != 0)
00616     {
00617       // _Don't_ clobber errno here!  result is either 0 or -1, and
00618       // ACE_OS::thr_create () already set errno!  D. Levine 28 Mar 1997
00619       // errno = result;
00620       ACE_Errno_Guard guard (errno);     // Lock release may smash errno
00621       new_thr_desc->sync_->release ();
00622       return -1;
00623     }
00624   auto_thread_args.release ();
00625 
00626 #if defined (ACE_HAS_WTHREADS)
00627   // Have to duplicate handle if client asks for it.
00628   // @@ How are thread handles implemented on AIX?  Do they
00629   // also need to be duplicated?
00630   if (t_handle != 0)
00631 # if defined (ACE_HAS_WINCE)
00632     *t_handle = thr_handle;
00633 # else  /* ! ACE_HAS_WINCE */
00634   (void) ::DuplicateHandle (::GetCurrentProcess (),
00635                             thr_handle,
00636                             ::GetCurrentProcess (),
00637                             t_handle,
00638                             0,
00639                             TRUE,
00640                             DUPLICATE_SAME_ACCESS);
00641 # endif /* ! ACE_HAS_WINCE */
00642 #else  /* ! ACE_HAS_WTHREADS */
00643   if (t_handle != 0)
00644     *t_handle = thr_handle;
00645 #endif /* ! ACE_HAS_WTHREADS */
00646 
00647   // append_thr also put the <new_thr_desc> into Thread_Manager's
00648   // double-linked list.  Only after this point, can we manipulate
00649   // double-linked list from a spawned thread's context.
00650   return this->append_thr (*t_id,
00651                            thr_handle,
00652                            ACE_THR_SPAWNED,
00653                            grp_id,
00654                            task,
00655                            flags,
00656                            new_thr_desc.release ());
00657 }

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.

Parameters:
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.
See also:
ACE_OS::thr_create() for descriptions of the possible flags values and their interactions.
Parameters:
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().

Return values:
-1 on failure; errno contains an error value.
The group id of the threads.

Definition at line 742 of file Thread_Manager.cpp.

References ACE_DEFAULT_THREAD_STACKSIZE, ACE_GUARD_RETURN, ACE_TRACE, grp_id_, and task().

00754 {
00755   ACE_TRACE ("ACE_Thread_Manager::spawn_n");
00756   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00757 
00758   if (grp_id == -1)
00759     grp_id = this->grp_id_++; // Increment the group id.
00760 
00761   for (size_t i = 0; i < n; i++)
00762     {
00763       // @@ What should happen if this fails?! e.g., should we try to
00764       // cancel the other threads that we've already spawned or what?
00765       if (this->spawn_i (func,
00766                          args,
00767                          flags,
00768                          thread_ids == 0 ? 0 : &thread_ids[i],
00769                          thread_handles == 0 ? 0 : &thread_handles[i],
00770                          priority,
00771                          grp_id,
00772                          stack == 0 ? 0 : stack[i],
00773                          stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i],
00774                          task,
00775                          thr_name == 0 ? 0 : &thr_name [i]) == -1)
00776         return -1;
00777     }
00778 
00779   return grp_id;
00780 }

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.

Parameters:
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.
See also:
ACE_OS::thr_create() for descriptions of the possible flags values and their interactions.
Parameters:
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().

Return values:
-1 on failure; errno contains an error value.
The group id of the threads.

Definition at line 700 of file Thread_Manager.cpp.

References ACE_DEFAULT_THREAD_STACKSIZE, ACE_GUARD_RETURN, ACE_TRACE, grp_id_, and task().

Referenced by ACE_Task_Base::activate().

00711 {
00712   ACE_TRACE ("ACE_Thread_Manager::spawn_n");
00713   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00714 
00715   if (grp_id == -1)
00716     grp_id = this->grp_id_++; // Increment the group id.
00717 
00718   for (size_t i = 0; i < n; i++)
00719     {
00720       // @@ What should happen if this fails?! e.g., should we try to
00721       // cancel the other threads that we've already spawned or what?
00722       if (this->spawn_i (func,
00723                          args,
00724                          flags,
00725                          0,
00726                          thread_handles == 0 ? 0 : &thread_handles[i],
00727                          priority,
00728                          grp_id,
00729                          stack == 0 ? 0 : stack[i],
00730                          stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i],
00731                          task,
00732                          thr_name == 0 ? 0 : &thr_name [i]) == -1)
00733         return -1;
00734     }
00735 
00736   return grp_id;
00737 }

int ACE_Thread_Manager::suspend ( ACE_thread_t   ) 

Suspend a single thread.

Definition at line 1073 of file Thread_Manager.cpp.

References ACE_EXECUTE_OP, and ACE_TRACE.

01074 {
01075   ACE_TRACE ("ACE_Thread_Manager::suspend");
01076   ACE_EXECUTE_OP (this->suspend_thr, 0);
01077 }

int ACE_Thread_Manager::suspend_all ( void   ) 

Suspend all threads.

Definition at line 1360 of file Thread_Manager.cpp.

References ACE_TRACE, apply_all(), and suspend_thr().

Referenced by ACE_Schedule_All_Threaded_Strategy< SVC_HANDLER >::suspend().

01361 {
01362   ACE_TRACE ("ACE_Thread_Manager::suspend_all");
01363   return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01364 }

int ACE_Thread_Manager::suspend_grp ( int  grp_id  ) 

Suspend a group of threads.

Definition at line 1280 of file Thread_Manager.cpp.

References ACE_TRACE, apply_grp(), and suspend_thr().

01281 {
01282   ACE_TRACE ("ACE_Thread_Manager::suspend_grp");
01283   return this->apply_grp (grp_id,
01284                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01285 }

int ACE_Thread_Manager::suspend_task ( ACE_Task_Base task  ) 

Suspend all threads in an ACE_Task.

Definition at line 1790 of file Thread_Manager.cpp.

References ACE_TRACE, apply_task(), suspend_thr(), and task().

Referenced by ACE_Task_Base::suspend().

01791 {
01792   ACE_TRACE ("ACE_Thread_Manager::suspend_task");
01793   return this->apply_task (task,
01794                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01795 }

int ACE_Thread_Manager::suspend_thr ( ACE_Thread_Descriptor td,
int  = 0 
) [protected]

Suspend the thread described in td.

Definition at line 980 of file Thread_Manager.cpp.

References ACE_SET_BITS, ACE_THR_SUSPENDED, ACE_TRACE, ENOTSUP, ACE_Unbounded_Queue< T >::enqueue_tail(), ACE_Thread::suspend(), ACE_Thread_Descriptor_Base::thr_handle_, ACE_Thread_Descriptor_Base::thr_state_, and thr_to_be_removed_.

Referenced by suspend_all(), suspend_grp(), and suspend_task().

00981 {
00982   ACE_TRACE ("ACE_Thread_Manager::suspend_thr");
00983 
00984   int const result = ACE_Thread::suspend (td->thr_handle_);
00985   if (result == -1) {
00986     if (errno != ENOTSUP)
00987       this->thr_to_be_removed_.enqueue_tail (td);
00988     return -1;
00989   }
00990   else {
00991     ACE_SET_BITS (td->thr_state_, ACE_THR_SUSPENDED);
00992     return 0;
00993   }
00994 }

ACE_INLINE 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 224 of file Thread_Manager.inl.

References ACE_TRACE, ACE_Thread_Descriptor_Base::task(), and thread_desc_self().

Referenced by append_thr(), apply_task(), cancel_task(), find_task(), get_grp(), hthread_list(), kill_task(), num_threads_in_task(), resume_task(), set_grp(), spawn_i(), spawn_n(), suspend_task(), thread_list(), and wait_task().

00225 {
00226   ACE_TRACE ("ACE_Thread_Manager::task");
00227 
00228   ACE_Thread_Descriptor *td = this->thread_desc_self () ;
00229 
00230   if (td == 0)
00231     return 0;
00232   else
00233     return td->task ();
00234 }

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.

Parameters:
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 entries.
n The maximum number of ACE_Task_Base pointers to write in
  • task_list.
Return values:
If successful, the number of pointers returned, which will be no greater than
  • n. Returns -1 on error.
Note:
This method has no way to indicate if there are more than
  • n ACE_Task_Base pointers available. Therefore, it may be wise to guess a larger value of
  • n than one thinks in cases where the exact number of tasks is not known.
See also:
count_threads()

Definition at line 1901 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and task_list().

01903 {
01904   ACE_TRACE ("ACE_Thread_Manager::task_all_list");
01905   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01906 
01907   size_t task_list_count = 0;
01908 
01909   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01910        !iter.done ();
01911        iter.advance ())
01912     {
01913       if (task_list_count >= n)
01914         break;
01915 
01916       ACE_Task_Base *task_p = iter.next ()->task_;
01917       if (0 != task_p)
01918         {
01919           // This thread has a task pointer; see if it's already in the
01920           // list. Don't add duplicates.
01921           size_t i = 0;
01922           for (; i < task_list_count; ++i)
01923             if (task_list[i] == task_p)
01924               break;
01925           if (i == task_list_count)        // No match - add this one
01926             task_list[task_list_count++] = task_p;
01927         }
01928     }
01929 
01930   return task_list_count;
01931 }

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.

Parameters:
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 entries.
n The maximum number of ACE_Task_Base pointers to write in
  • task_list.
Return values:
If successful, the number of pointers returned, which will be no greater than
  • n. Returns -1 on error.
Note:
This method has no way to indicate if there are more than
  • n ACE_Task_Base pointers available. Therefore, it may be wise to guess a larger value of
  • n than one thinks in cases where the exact number of tasks is not known.
See also:
num_tasks_in_group(), task_all_list()

Definition at line 1992 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), find_task(), and ACE_Double_Linked_List_Iterator_Base< T >::next().

Referenced by task_all_list().

01995 {
01996   ACE_TRACE ("ACE_Thread_Manager::task_list");
01997   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01998 
01999   ACE_Task_Base **task_list_iterator = task_list;
02000   size_t task_list_count = 0;
02001   size_t i = 0;
02002 
02003   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02004        !iter.done ();
02005        iter.advance ())
02006     {
02007       if (task_list_count >= n)
02008         break;
02009 
02010       if (iter.next ()->grp_id_ == grp_id
02011           && this->find_task (iter.next ()->task_, i) == 0)
02012         {
02013           task_list_iterator[task_list_count] = iter.next ()->task_;
02014           ++task_list_count;
02015         }
02016 
02017       ++i;
02018     }
02019 
02020   return task_list_count;
02021 }

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 1171 of file Thread_Manager.cpp.

References ACE_THR_CANCELLED, ACE_TRACE, and check_state().

01172 {
01173   ACE_TRACE ("ACE_Thread_Manager::testcancel");
01174   return this->check_state (ACE_THR_CANCELLED, t_id);
01175 }

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 1162 of file Thread_Manager.cpp.

References ACE_THR_SUSPENDED, ACE_TRACE, and check_state().

01163 {
01164   ACE_TRACE ("ACE_Thread_Manager::testresume");
01165   return this->check_state (ACE_THR_SUSPENDED, t_id, 0);
01166 }

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 1153 of file Thread_Manager.cpp.

References ACE_THR_SUSPENDED, ACE_TRACE, and check_state().

01154 {
01155   ACE_TRACE ("ACE_Thread_Manager::testsuspend");
01156   return this->check_state (ACE_THR_SUSPENDED, t_id);
01157 }

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 1144 of file Thread_Manager.cpp.

References ACE_THR_TERMINATED, ACE_TRACE, and check_state().

01145 {
01146   ACE_TRACE ("ACE_Thread_Manager::testterminate");
01147   return this->check_state (ACE_THR_TERMINATED, t_id);
01148 }

ACE_INLINE 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 217 of file Thread_Manager.inl.

References ACE_TRACE, and ACE_Thread::self().

00218 {
00219   ACE_TRACE ("ACE_Thread_Manager::thr_self");
00220   return ACE_Thread::self ();
00221 }

int ACE_Thread_Manager::thr_self ( ACE_hthread_t  ) 

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 345 of file Thread_Manager.cpp.

References ACE_TRACE, ACE_Thread_Descriptor::self(), and thread_desc_self().

00346 {
00347   ACE_TRACE ("ACE_Thread_Manager::thr_self");
00348 
00349   ACE_Thread_Descriptor *desc =
00350     this->thread_desc_self ();
00351 
00352   if (desc == 0)
00353     return -1;
00354   else
00355     desc->self (self);
00356 
00357   return 0;
00358 }

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 1960 of file Thread_Manager.cpp.

References ACE_FIND, ACE_GUARD_RETURN, ACE_LOG_MSG, ACE_TRACE, ACE_OS::thr_equal(), ACE_OS::thr_self(), and ACE_Thread_Descriptor_Base::thr_state_.

Referenced by check_state().

01962 {
01963   ACE_TRACE ("ACE_Thread_Manager::thr_state");
01964   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01965 
01966   int const self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ());
01967 
01968   // If we're checking the state of our thread, try to get the cached
01969   // value out of TSS to avoid lookup.
01970   if (self_check)
01971     {
01972       ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc ();
01973       if (desc == 0)
01974         return 0;               // Always return false.
01975       state = desc->thr_state_;
01976     }
01977   else
01978     {
01979       // Not calling from self, have to look it up from the list.
01980       ACE_FIND (this->find_thread (id), ptr);
01981       if (ptr == 0)
01982         return 0;
01983       state = ptr->thr_state_;
01984     }
01985 
01986   return 1;
01987 }

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 1936 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), and ACE_Double_Linked_List_Iterator_Base< T >::next().

01938 {
01939   ACE_TRACE ("ACE_Thread_Manager::thread_all_list");
01940   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01941 
01942   size_t thread_count = 0;
01943 
01944   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01945        !iter.done ();
01946        iter.advance ())
01947     {
01948       if (thread_count >= n)
01949         break;
01950 
01951       thread_list[thread_count] = iter.next ()->thr_id_;
01952       ++thread_count;
01953     }
01954 
01955   return thread_count;
01956 }

ACE_INLINE 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 187 of file Thread_Manager.inl.

References ACE_LOG_MSG, find_thread(), and ACE_OS::thr_self().

Referenced by at_exit(), run_thread_exit_hooks(), task(), and thr_self().

00188 {
00189   // This method must be called with lock held.
00190 
00191   // Try to get it from cache.
00192   ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc ();
00193 
00194 #if 1
00195   //  ACE_ASSERT (desc != 0);
00196   // Thread descriptor should always get cached.
00197 #else
00198   if (desc == 0)
00199     {
00200       ACE_thread_t id = ACE_OS::thr_self ();
00201 
00202       desc = this->find_thread (id);
00203 
00204       // Thread descriptor adapter might not have been put into the
00205       // list yet.
00206       if (desc != 0)
00207         // Update the TSS cache.
00208         ACE_LOG_MSG->thr_desc (desc);
00209     }
00210 #endif
00211   return desc;
00212 }

ACE_Thread_Descriptor * ACE_Thread_Manager::thread_descriptor ( ACE_thread_t   )  [protected]

Return a pointer to the thread's Thread_Descriptor, 0 if fail.

Definition at line 323 of file Thread_Manager.cpp.

References ACE_FIND, ACE_GUARD_RETURN, and ACE_TRACE.

00324 {
00325   ACE_TRACE ("ACE_Thread_Manager::thread_descriptor");
00326   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
00327 
00328   ACE_FIND (this->find_thread (thr_id), ptr);
00329   return ptr;
00330 }

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 2082 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), and ACE_Double_Linked_List_Iterator_Base< T >::next().

02085 {
02086   ACE_TRACE ("ACE_Thread_Manager::thread_grp_list");
02087   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02088 
02089   size_t thread_count = 0;
02090 
02091   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02092        !iter.done ();
02093        iter.advance ())
02094     {
02095       if (thread_count >= n)
02096         break;
02097 
02098       if (iter.next ()->grp_id_ == grp_id)
02099         {
02100           thread_list[thread_count] = iter.next ()->thr_id_;
02101           thread_count++;
02102         }
02103     }
02104 
02105   return thread_count;
02106 }

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 2026 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and task().

02029 {
02030   ACE_TRACE ("ACE_Thread_Manager::thread_list");
02031   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02032 
02033   size_t thread_count = 0;
02034 
02035   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02036        !iter.done ();
02037        iter.advance ())
02038     {
02039       if (thread_count >= n)
02040         break;
02041 
02042       if (iter.next ()->task_ == task)
02043         {
02044           thread_list[thread_count] = iter.next ()->thr_id_;
02045           ++thread_count;
02046         }
02047     }
02048 
02049   return thread_count;
02050 }

int ACE_Thread_Manager::thread_within ( ACE_thread_t  tid  ) 

Definition at line 1195 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Double_Linked_List_Iterator_Base< T >::next(), and ACE_OS::thr_equal().

01196 {
01197   ACE_TRACE ("ACE_Thread_Manager::thread_within");
01198   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01199 
01200   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01201        !iter.done ();
01202        iter.advance ())
01203     if (ACE_OS::thr_equal (iter.next ()->thr_id_, tid))
01204       return 1;
01205 
01206   return 0;
01207 }

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.

Parameters:
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.
Returns:
0 on success * and -1 on failure.
Note:
If this function is called while the 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 1587 of file Thread_Manager.cpp.

References ACE_ASSERT, ACE_BIT_DISABLED, ACE_BIT_ENABLED, ACE_GUARD_RETURN, ACE_SET_BITS, ACE_THR_JOINING, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List< T >::delete_head(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Unbounded_Queue< T >::enqueue_tail(), ACE_OS_Thread_Descriptor::flags_, ACE_OS::gettimeofday(), ACE_Double_Linked_List< T >::insert_tail(), ACE_Thread::join(), ACE_Double_Linked_List_Iterator_Base< T >::next(), remove_thr_all(), ACE_Object_Manager::shutting_down(), THR_DAEMON, THR_DETACHED, ACE_Thread_Descriptor_Base::thr_handle_, THR_JOINABLE, and thr_to_be_removed_.

Referenced by close().

01590 {
01591   ACE_TRACE ("ACE_Thread_Manager::wait");
01592 
01593   ACE_Time_Value local_timeout;
01594   // Check to see if we're using absolute time or not.
01595   if (use_absolute_time == false && timeout != 0)
01596     {
01597       local_timeout = *timeout;
01598       local_timeout += ACE_OS::gettimeofday ();
01599       timeout = &local_timeout;
01600     }
01601 
01602 #if !defined (ACE_HAS_VXTHREADS)
01603   ACE_Double_Linked_List<ACE_Thread_Descriptor_Base> term_thr_list_copy;
01604 #endif /* ACE_HAS_VXTHREADS */
01605 
01606 #if defined (ACE_HAS_THREADS)
01607   {
01608     // Just hold onto the guard while waiting.
01609     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01610 
01611     if (ACE_Object_Manager::shutting_down () != 1)
01612       {
01613         // Program is not shutting down.  Perform a normal wait on threads.
01614         if (abandon_detached_threads != 0)
01615           {
01616             ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01617             for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor>
01618                    iter (this->thr_list_);
01619                  !iter.done ();
01620                  iter.advance ())
01621               if (ACE_BIT_ENABLED (iter.next ()->flags_,
01622                                    THR_DETACHED | THR_DAEMON)
01623                   && ACE_BIT_DISABLED (iter.next ()->flags_, THR_JOINABLE))
01624                 {
01625                   this->thr_to_be_removed_.enqueue_tail (iter.next ());
01626                   ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01627                 }
01628 
01629             if (! this->thr_to_be_removed_.is_empty ())
01630               {
01631                 ACE_Thread_Descriptor *td = 0;
01632                 while (this->thr_to_be_removed_.dequeue_head (td) != -1)
01633                   this->remove_thr (td, 1);
01634               }
01635           }
01636 
01637         while (this->thr_list_.size () > 0)
01638           if (this->zero_cond_.wait (timeout) == -1)
01639             return -1;
01640       }
01641     else
01642         // Program is shutting down, no chance to wait on threads.
01643         // Therefore, we'll just remove threads from the list.
01644         this->remove_thr_all ();
01645 
01646 #if !defined (ACE_HAS_VXTHREADS)
01647   ACE_Thread_Descriptor_Base* item = 0;
01648   while ((item = this->terminated_thr_list_.delete_head ()) != 0)
01649     {
01650       term_thr_list_copy.insert_tail (item);
01651     }
01652 #endif /* ACE_HAS_VXTHREADS */
01653     // Release the guard, giving other threads a chance to run.
01654   }
01655 
01656 #if !defined (ACE_HAS_VXTHREADS)
01657     // @@ VxWorks doesn't support thr_join (yet.)  We are working
01658     // on our implementation.   Chorus'es thr_join seems broken.
01659     ACE_Thread_Descriptor_Base *item = 0;
01660 
01661     while ((item = term_thr_list_copy.delete_head ()) != 0)
01662       {
01663         if (ACE_BIT_DISABLED (item->flags_, THR_DETACHED | THR_DAEMON)
01664             || ACE_BIT_ENABLED (item->flags_, THR_JOINABLE))
01665           // Detached handles shouldn't reached here.
01666           (void) ACE_Thread::join (item->thr_handle_);
01667 
01668         delete item;
01669       }
01670 
01671 #endif /* !ACE_HAS_VXTHREADS */
01672 #else
01673   ACE_UNUSED_ARG (timeout);
01674   ACE_UNUSED_ARG (abandon_detached_threads);
01675 #endif /* ACE_HAS_THREADS */
01676 
01677   return 0;
01678 }

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 1461 of file Thread_Manager.cpp.

References ACE_BIT_DISABLED, ACE_BIT_ENABLED, ACE_GUARD_RETURN, ACE_NEW_RETURN, ACE_SET_BITS, ACE_THR_JOINING, ACE_TRACE, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator< T >::advance_and_remove(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Thread::join(), ACE_Double_Linked_List_Iterator_Base< T >::next(), terminated_thr_list_, THR_DAEMON, THR_DETACHED, and THR_JOINABLE.

01462 {
01463   ACE_TRACE ("ACE_Thread_Manager::wait_grp");
01464 
01465   int copy_count = 0;
01466   ACE_Thread_Descriptor_Base *copy_table = 0;
01467 
01468   // We have to make sure that while we wait for these threads to
01469   // exit, we do not have the lock.  Therefore we make a copy of all
01470   // interesting entries and let go of the lock.
01471   {
01472     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01473 
01474 #if !defined (ACE_HAS_VXTHREADS)
01475     ACE_NEW_RETURN (copy_table,
01476                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()
01477                                                + this->terminated_thr_list_.size ()],
01478                     -1);
01479 #else
01480     ACE_NEW_RETURN (copy_table,
01481                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()],
01482                     -1);
01483 #endif /* !ACE_HAS_VXTHREADS */
01484 
01485     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01486          !iter.done ();
01487          iter.advance ())
01488       // If threads are created as THR_DETACHED or THR_DAEMON, we
01489       // can't help much.
01490       if (iter.next ()->grp_id_ == grp_id &&
01491           (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON)
01492            || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE)))
01493         {
01494           ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01495           copy_table[copy_count++] = *iter.next ();
01496         }
01497 
01498 #if !defined (ACE_HAS_VXTHREADS)
01499     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_);
01500          !biter.done ();
01501          biter.advance ())
01502       // If threads are created as THR_DETACHED or THR_DAEMON, we
01503       // can't help much.
01504       if (biter.next ()->grp_id_ == grp_id)
01505         {
01506           ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (0);
01507           copy_table[copy_count++] = *tdb;
01508           delete tdb;
01509         }
01510 #endif /* !ACE_HAS_VXTHREADS */
01511   }
01512 
01513   // Now actually join() with all the threads in this group.
01514   int result = 0;
01515 
01516   for (int i = 0;
01517        i < copy_count && result != -1;
01518        i++)
01519     {
01520       if (ACE_Thread::join (copy_table[i].thr_handle_) == -1)
01521         result = -1;
01522     }
01523 
01524   delete [] copy_table;
01525 
01526   return result;
01527 }

ACE_INLINE int ACE_Thread_Manager::wait_on_exit ( void   ) 

Definition at line 284 of file Thread_Manager.inl.

References automatic_wait_.

00285 {
00286   return this->automatic_wait_;
00287 }

ACE_INLINE 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 278 of file Thread_Manager.inl.

References automatic_wait_.

00279 {
00280   this->automatic_wait_ = do_wait;
00281 }

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.

Parameters:
task The ACE_Task_Base object whose threads are to waited for.
Return values:
0 Success.
-1 Failure (consult errno for further information).

Definition at line 1718 of file Thread_Manager.cpp.

References ACE_BIT_DISABLED, ACE_BIT_ENABLED, ACE_GUARD_RETURN, ACE_NEW_RETURN, ACE_SET_BITS, ACE_THR_JOINING, ACE_Double_Linked_List_Iterator< T >::advance(), ACE_Double_Linked_List_Iterator< T >::advance_and_remove(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Thread::join(), ACE_Double_Linked_List_Iterator_Base< T >::next(), task(), terminated_thr_list_, THR_DAEMON, THR_DETACHED, and THR_JOINABLE.

01719 {
01720   int copy_count = 0;
01721   ACE_Thread_Descriptor_Base *copy_table = 0;
01722 
01723   // We have to make sure that while we wait for these threads to
01724   // exit, we do not have the lock.  Therefore we make a copy of all
01725   // interesting entries and let go of the lock.
01726   {
01727     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01728 
01729 #if !defined (ACE_HAS_VXTHREADS)
01730     ACE_NEW_RETURN (copy_table,
01731                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()
01732                                                 + this->terminated_thr_list_.size ()],
01733                     -1);
01734 #else
01735     ACE_NEW_RETURN (copy_table,
01736                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()],
01737                     -1);
01738 #endif /* !ACE_HAS_VXTHREADS */
01739 
01740     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01741          !iter.done ();
01742          iter.advance ())
01743       // If threads are created as THR_DETACHED or THR_DAEMON, we
01744       // can't wait on them here.
01745       if (iter.next ()->task_ == task &&
01746           (ACE_BIT_DISABLED (iter.next ()->flags_,
01747                              THR_DETACHED | THR_DAEMON)
01748            || ACE_BIT_ENABLED (iter.next ()->flags_,
01749                                THR_JOINABLE)))
01750         {
01751           ACE_SET_BITS (iter.next ()->thr_state_,
01752                         ACE_THR_JOINING);
01753           copy_table[copy_count++] = *iter.next ();
01754         }
01755 
01756 #if !defined (ACE_HAS_VXTHREADS)
01757     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> titer (this->terminated_thr_list_);
01758          !titer.done ();
01759          titer.advance ())
01760       // If threads are created as THR_DETACHED or THR_DAEMON, we can't help much here.
01761       if (titer.next ()->task_ == task)
01762         {
01763           ACE_Thread_Descriptor_Base *tdb =
01764             titer.advance_and_remove (0);
01765           copy_table[copy_count++] = *tdb;
01766           delete tdb;
01767         }
01768 #endif /* !ACE_HAS_VXTHREADS */
01769   }
01770 
01771   // Now to do the actual work
01772   int result = 0;
01773 
01774   for (int i = 0;
01775        i < copy_count && result != -1;
01776        i++)
01777     {
01778       if (ACE_Thread::join (copy_table[i].thr_handle_) == -1)
01779         result = -1;
01780     }
01781 
01782   delete [] copy_table;
01783 
01784   return result;
01785 }


Friends And Related Function Documentation

friend class ACE_Thread_Control [friend]

Definition at line 383 of file Thread_Manager.h.

friend class ACE_Thread_Descriptor [friend]

Definition at line 387 of file Thread_Manager.h.

friend class ACE_Thread_Exit [friend]

Definition at line 386 of file Thread_Manager.h.


Member Data Documentation

ACE_Thread_Manager::ACE_ALLOC_HOOK_DECLARE

Declare the dynamic allocation hooks.

Definition at line 1079 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 1225 of file Thread_Manager.h.

Referenced by wait_on_exit().

bool ACE_Thread_Manager::delete_thr_mgr_ = false [static, private]

Must delete the thr_mgr_ if true.

Definition at line 1244 of file Thread_Manager.h.

int ACE_Thread_Manager::grp_id_ [protected]

Keeps track of the next group id to assign.

Definition at line 1221 of file Thread_Manager.h.

Referenced by dump(), insert_thr(), spawn(), and spawn_n().

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 1214 of file Thread_Manager.h.

Referenced by register_as_terminated(), wait_grp(), and wait_task().

ACE_Double_Linked_List<ACE_Thread_Descriptor> ACE_Thread_Manager::thr_list_ [protected]

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 1210 of file Thread_Manager.h.

Referenced by append_thr(), count_threads(), dump(), and remove_thr().

ACE_Thread_Manager * ACE_Thread_Manager::thr_mgr_ = 0 [static, private]

Pointer to a process-wide ACE_Thread_Manager.

Definition at line 1241 of file Thread_Manager.h.

ACE_Unbounded_Queue<ACE_Thread_Descriptor*> ACE_Thread_Manager::thr_to_be_removed_ [protected]

Collect pointers to thread descriptors of threads to be removed later.

Definition at line 1218 of file Thread_Manager.h.

Referenced by apply_all(), apply_grp(), apply_task(), kill_thr(), resume_thr(), suspend_thr(), and wait().

ACE_Locked_Free_List<ACE_Thread_Descriptor, ACE_SYNCH_MUTEX> ACE_Thread_Manager::thread_desc_freelist_ [protected]

Definition at line 1236 of file Thread_Manager.h.

Referenced by remove_thr().


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:35:46 2010 for ACE by  doxygen 1.4.7