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)
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 *=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)
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)
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)
ACE_THR_FUNC_RETURN exit (ACE_THR_FUNC_RETURN status=0, int do_thread_exit=1)
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 . 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 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)
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 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)
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.


Static Public Member Functions

ACE_Thread_Managerinstance (void)
 Get pointer to a process-wide ACE_Thread_Manager.

ACE_Thread_Managerinstance (ACE_Thread_Manager *)
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)
 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, int=0)
 Apply to all members of the table that match the .

int apply_grp (int grp_id, ACE_THR_MEMBER_FUNC func, int arg=0)
 Apply to all members of the table that match the .

int apply_all (ACE_THR_MEMBER_FUNC, int=0)
 Apply to all members of the table.

int join_thr (ACE_Thread_Descriptor *td, int=0)
 Join the thread described in .

int resume_thr (ACE_Thread_Descriptor *td, int=0)
 Resume the thread described in .

int suspend_thr (ACE_Thread_Descriptor *td, int=0)
 Suspend the thread described in .

int kill_thr (ACE_Thread_Descriptor *td, int signum)
 Send signal signum to the thread described in .

int cancel_thr (ACE_Thread_Descriptor *td, int async_cancel=0)
 Set the cancellation flag for the thread described in .

int register_as_terminated (ACE_Thread_Descriptor *td)
 Register a thread as terminated and put it into the .


Static Protected Member Functions

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_Thread_Mutex lock_
 Serialize access to the .

ACE_Condition_Thread_Mutex zero_cond_
 Keep track of when there are no more threads.

ACE_Locked_Free_List< ACE_Thread_Descriptor,
ACE_SYNCH_MUTEX > 
thread_desc_freelist_

Static Private Member Functions

 ACE_TSS_TYPE (ACE_Thread_Exit)*thr_exit_
 Global ACE_TSS (ACE_Thread_Exit) object ptr.


Static Private Attributes

ACE_Thread_Managerthr_mgr_ = 0
 Pointer to a process-wide ACE_Thread_Manager.

int delete_thr_mgr_ = 0
 Must delete the if non-0.


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 function 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 live beyond the scope of , you are sure to have resource leaks in your program. Remember to wait on threads before exiting 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.

Referenced by apply_all(), apply_grp(), apply_task(), cancel_all(), cancel_grp(), cancel_task(), kill_grp(), kill_task(), resume_all(), resume_grp(), resume_task(), suspend_all(), suspend_grp(), and suspend_task().


Member Enumeration Documentation

anonymous enum
 

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

Enumeration values:
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_FREE_LIST_WITH_POOL, and 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

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

References ACE_hthread_t, ACE_NEW_RETURN, ACE_SET_BITS, ACE_TRACE, ACE_OS_Thread_Descriptor::flags_, ACE_Thread_Descriptor_Base::grp_id_, ACE_Thread_Descriptor::sync_, 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 insert_thr(), and spawn_i().

00807 {
00808   ACE_TRACE ("ACE_Thread_Manager::append_thr");
00809   ACE_Thread_Descriptor *thr_desc = 0;
00810 
00811   if (td == 0)
00812     {
00813       ACE_NEW_RETURN (thr_desc,
00814                       ACE_Thread_Descriptor,
00815                       -1);
00816       thr_desc->tm_ = this;
00817       // Setup the Thread_Manager.
00818     }
00819   else
00820     thr_desc = td;
00821 
00822   thr_desc->thr_id_ = t_id;
00823   thr_desc->thr_handle_ = t_handle;
00824   thr_desc->grp_id_ = grp_id;
00825   thr_desc->task_ = task;
00826   thr_desc->flags_ = flags;
00827 
00828   this->thr_list_.insert_head (thr_desc);
00829   ACE_SET_BITS (thr_desc->thr_state_, thr_state);
00830   thr_desc->sync_->release ();
00831 
00832   return 0;
00833 }

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

Apply to all members of the table.

Definition at line 1354 of file Thread_Manager.cpp.

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

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

01355 {
01356   ACE_TRACE ("ACE_Thread_Manager::apply_all");
01357   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01358   ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01359 
01360   int result = 0;
01361 
01362   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01363        !iter.done ();
01364        iter.advance ())
01365     if ((this->*func)(iter.next (), arg) == -1)
01366       result = -1;
01367 
01368   // Must remove threads after we have traversed the thr_list_ to
01369   // prevent clobber thr_list_'s integrity.
01370 
01371   if (! this->thr_to_be_removed_.is_empty ())
01372     {
01373       // Save/restore errno.
01374       ACE_Errno_Guard error (errno);
01375 
01376       for (ACE_Thread_Descriptor *td;
01377            this->thr_to_be_removed_.dequeue_head (td) != -1;
01378            )
01379         this->remove_thr (td, 1);
01380     }
01381 
01382   return result;
01383 }

int ACE_Thread_Manager::apply_grp int  grp_id,
ACE_THR_MEMBER_FUNC  func,
int  arg = 0
[protected]
 

Apply to all members of the table that match the .

Definition at line 1280 of file Thread_Manager.cpp.

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

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

01283 {
01284   ACE_TRACE ("ACE_Thread_Manager::apply_grp");
01285   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01286   ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01287 
01288   int result = 0;
01289 
01290   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01291        !iter.done ();
01292        iter.advance ())
01293     if (iter.next ()->grp_id_ == grp_id)
01294       if ((this->*func) (iter.next (), arg) == -1)
01295         result = -1;
01296 
01297   // Must remove threads after we have traversed the thr_list_ to
01298   // prevent clobber thr_list_'s integrity.
01299 
01300   if (! this->thr_to_be_removed_.is_empty ())
01301     {
01302       // Save/restore errno.
01303       ACE_Errno_Guard error (errno);
01304 
01305       for (ACE_Thread_Descriptor *td;
01306            this->thr_to_be_removed_.dequeue_head (td) != -1;
01307            )
01308         this->remove_thr (td, 1);
01309     }
01310 
01311   return result;
01312 }

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

Apply to all members of the table that match the .

Definition at line 1745 of file Thread_Manager.cpp.

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

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

01748 {
01749   ACE_TRACE ("ACE_Thread_Manager::apply_task");
01750   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01751   ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01752 
01753   int result = 0;
01754 
01755   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01756        !iter.done ();
01757        iter.advance ())
01758     if (iter.next ()->task_ == task
01759         && (this->*func) (iter.next (), arg) == -1)
01760       result = -1;
01761 
01762   // Must remove threads after we have traversed the thr_list_ to
01763   // prevent clobber thr_list_'s integrity.
01764 
01765   if (! this->thr_to_be_removed_.is_empty ())
01766     {
01767       // Save/restore errno.
01768       ACE_Errno_Guard error (errno);
01769 
01770       for (ACE_Thread_Descriptor *td;
01771            this->thr_to_be_removed_.dequeue_head (td) != -1;
01772            )
01773         this->remove_thr (td, 1);
01774     }
01775 
01776   return result;
01777 }

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 == 0, the 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_CLEANUP_FUNC, 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 1126 of file Thread_Manager.cpp.

References ACE_EXECUTE_OP, and ACE_TRACE.

01127 {
01128   ACE_TRACE ("ACE_Thread_Manager::cancel");
01129   ACE_EXECUTE_OP (this->cancel_thr, async_cancel);
01130 }

int ACE_Thread_Manager::cancel_all int  async_cancel = 0  ) 
 

Cancel's all the threads.

Definition at line 1409 of file Thread_Manager.cpp.

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

01410 {
01411   ACE_TRACE ("ACE_Thread_Manager::cancel_all");
01412   return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01413                           async_cancel);
01414 }

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

Cancel a group of threads.

Definition at line 1345 of file Thread_Manager.cpp.

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

01346 {
01347   ACE_TRACE ("ACE_Thread_Manager::cancel_grp");
01348   return this->apply_grp (grp_id,
01349                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01350                           async_cancel);
01351 }

int ACE_Thread_Manager::cancel_task ACE_Task_Base task,
int  async_cancel = 0
 

Cancel all threads in an ACE_Task. If is non-0, then asynchronously cancel these threads if the OS platform supports cancellation. Otherwise, perform a "cooperative" cancellation.

Definition at line 1888 of file Thread_Manager.cpp.

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

01890 {
01891   ACE_TRACE ("ACE_Thread_Manager::cancel_task");
01892   return this->apply_task (task,
01893                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01894                            async_cancel);
01895 }

int ACE_Thread_Manager::cancel_thr ACE_Thread_Descriptor td,
int  async_cancel = 0
[protected]
 

Set the cancellation flag for the thread described in .

Definition at line 1045 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().

01046 {
01047   ACE_TRACE ("ACE_Thread_Manager::cancel_thr");
01048   // Must set the state first and then try to cancel the thread.
01049   ACE_SET_BITS (td->thr_state_, ACE_THR_CANCELLED);
01050 
01051   if (async_cancel != 0)
01052     // Note that this call only does something relevant if the OS
01053     // platform supports asynchronous thread cancellation.  Otherwise,
01054     // it's a no-op.
01055     return ACE_Thread::cancel (td->thr_id_);
01056 
01057   return 0;
01058 }

int ACE_Thread_Manager::check_state ACE_UINT32  state,
ACE_thread_t  thread,
int  enable = 1
[protected]
 

Efficiently check whether is in a particular . This call updates the TSS cache if possible to speed up subsequent searches.

Definition at line 1142 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(), thr_state(), and ACE_Thread_Descriptor_Base::thr_state_.

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

01145 {
01146   ACE_TRACE ("ACE_Thread_Manager::check_state");
01147   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01148 
01149   ACE_UINT32 thr_state;
01150 
01151   int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ());
01152 
01153   // If we're checking the state of our thread, try to get the cached
01154   // value out of TSS to avoid lookup.
01155   if (self_check)
01156     {
01157       ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc ();
01158       if (desc == 0)
01159         return 0;               // Always return false.
01160       thr_state = desc->thr_state_;
01161     }
01162   else
01163     {
01164       // Not calling from self, have to look it up from the list.
01165       ACE_FIND (this->find_thread (id), ptr);
01166       if (ptr == 0)
01167         return 0;
01168       thr_state = ptr->thr_state_;
01169     }
01170   if (enable)
01171     return ACE_BIT_ENABLED (thr_state, state);
01172 
01173   return ACE_BIT_DISABLED (thr_state, state);
01174 }

int ACE_Thread_Manager::close void   ) 
 

Release all resources. By default, this method will wait till all threads exit. However, when called from , most global resources are destroyed and thus, we don't try to wait but just clean up the thread descriptor list.

Definition at line 440 of file Thread_Manager.cpp.

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

Referenced by close_singleton(), and ~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, ACE_Thread_Exit::cleanup(), close(), delete_thr_mgr_, and thr_mgr_.

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_ = 0;
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 .

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,
int  do_thread_exit = 1
 

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

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

Referenced by ACE_Thread_Control::exit().

01587 {
01588   ACE_TRACE ("ACE_Thread_Manager::exit");
01589 #if defined (ACE_WIN32)
01590   // Remove detached thread handle.
01591 
01592   if (do_thr_exit)
01593     {
01594 #if 0
01595       // @@ This callback is now taken care of by TSS_Cleanup.  Do we
01596       //    need it anymore?
01597 
01598       // On Win32, if we really wants to exit from a thread, we must
01599       // first  clean up the thread specific storage.  By doing so,
01600       // ACE_Thread_Manager::exit will be called again with
01601       // do_thr_exit = 0 and cleaning up the ACE_Cleanup_Info (but not
01602       // exiting the thread.)  After the following call returns, we
01603       // are safe to exit this thread.
01604       delete ACE_Thread_Exit::instance ();
01605 #endif /* 0 */
01606       ACE_Thread::exit (status);
01607     }
01608 #endif /* ACE_WIN32 */
01609 
01610   // Just hold onto the guard while finding this thread's id and
01611   {
01612     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
01613 
01614     // Find the thread id, but don't use the cache.  It might have been
01615     // deleted already.
01616 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
01617     ACE_hthread_t id;
01618     ACE_OS::thr_self (id);
01619     ACE_Thread_Descriptor* td = this->find_hthread (id);
01620 #else  /* ! ACE_VXWORKS */
01621     ACE_thread_t id = ACE_OS::thr_self ();
01622     ACE_Thread_Descriptor* td = this->find_thread (id);
01623 #endif /* ! ACE_VXWORKS */
01624     if (td != 0)
01625      {
01626        // @@ We call Thread_Descriptor terminate this realize the cleanup
01627        // process itself.
01628        td->terminate();
01629      }
01630   }
01631 
01632   if (do_thr_exit)
01633     {
01634       ACE_Thread::exit (status);
01635       // On reasonable systems <ACE_Thread::exit> should not return.
01636       // However, due to horrible semantics with Win32 thread-specific
01637       // storage this call can return (don't ask...).
01638     }
01639 
01640   return 0;
01641 }

ACE_Thread_Descriptor * ACE_Thread_Manager::find_hthread ACE_hthread_t  h_id  )  [protected]
 

Locate the index of the table slot occupied by . Returns -1 if is not in the table doesn't contain .

Definition at line 838 of file Thread_Manager.cpp.

References ACE_hthread_t, 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().

Referenced by exit(), and insert_thr().

00839 {
00840   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
00841        !iter.done ();
00842        iter.advance ())
00843     if (ACE_OS::thr_cmp (iter.next ()->thr_handle_, h_id))
00844       return iter.next ();
00845 
00846   return 0;
00847 }

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 . Returns 0 if is not in the table doesn't contain .

Definition at line 1902 of file Thread_Manager.cpp.

References 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().

Referenced by num_tasks_in_group(), and task_list().

01903 {
01904   ACE_TRACE ("ACE_Thread_Manager::find_task");
01905 
01906   size_t i = 0;
01907 
01908   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01909        !iter.done ();
01910        iter.advance ())
01911     {
01912       if (i >= slot)
01913         break;
01914 
01915       if (task == iter.next ()->task_)
01916         return iter.next ();
01917 
01918       i++;
01919     }
01920 
01921   return 0;
01922 }

ACE_Thread_Descriptor * ACE_Thread_Manager::find_thread ACE_thread_t  t_id  )  [protected]
 

Locate the index of the table slot occupied by . Returns -1 if is not in the table doesn't contain .

Definition at line 853 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(), insert_thr(), and thread_desc_self().

00854 {
00855   ACE_TRACE ("ACE_Thread_Manager::find_thread");
00856 
00857   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
00858        !iter.done ();
00859        iter.advance ())
00860     if (ACE_OS::thr_equal (iter.next ()->thr_id_, t_id))
00861       return iter.next ();
00862   return 0;
00863 }

int ACE_Thread_Manager::get_grp ACE_Task_Base task,
int &  grp_id
 

Get group ids for a particular task.

Definition at line 2223 of file Thread_Manager.cpp.

References ACE_FIND, ACE_GUARD_RETURN, and ACE_TRACE.

02224 {
02225   ACE_TRACE ("ACE_Thread_Manager::get_grp");
02226   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02227 
02228   ACE_FIND (this->find_task (task), ptr);
02229   grp_id = ptr->grp_id_;
02230   return 0;
02231 }

int ACE_Thread_Manager::get_grp ACE_thread_t  ,
int &  grp_id
 

Get group ids for a particular thread id.

Definition at line 1247 of file Thread_Manager.cpp.

References ACE_FIND, ACE_GUARD_RETURN, and ACE_TRACE.

01248 {
01249   ACE_TRACE ("ACE_Thread_Manager::get_grp");
01250   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01251 
01252   ACE_FIND (this->find_thread (t_id), ptr);
01253 
01254   if (ptr)
01255     grp_id = ptr->grp_id_;
01256   else
01257     return -1;
01258   return 0;
01259 }

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, ACE_hthread_t, 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 a list of up to n thread handles in a group . The caller must allocate memory for .

Definition at line 2181 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_hthread_t, 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().

02184 {
02185   ACE_TRACE ("ACE_Thread_Manager::hthread_grp_list");
02186   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02187 
02188   size_t hthread_count = 0;
02189 
02190   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02191        !iter.done ();
02192        iter.advance ())
02193     {
02194       if (hthread_count >= n)
02195         break;
02196 
02197       if (iter.next ()->grp_id_ == grp_id)
02198         {
02199           hthread_list[hthread_count] = iter.next ()->thr_handle_;
02200           hthread_count++;
02201         }
02202     }
02203 
02204   return hthread_count;
02205 }

ssize_t ACE_Thread_Manager::hthread_list ACE_Task_Base task,
ACE_hthread_t  hthread_list[],
size_t  n
 

Returns in a list of up to n thread handles in an ACE_Task_Base. The caller must allocate memory for . 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 2125 of file Thread_Manager.cpp.

References ACE_GUARD_RETURN, ACE_hthread_t, 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().

02128 {
02129   ACE_TRACE ("ACE_Thread_Manager::hthread_list");
02130   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02131 
02132   size_t hthread_count = 0;
02133 
02134   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02135        !iter.done ();
02136        iter.advance ())
02137     {
02138       if (hthread_count >= n)
02139         break;
02140 
02141       if (iter.next ()->task_ == task)
02142         {
02143           hthread_list[hthread_count] = iter.next ()->thr_handle_;
02144           hthread_count++;
02145         }
02146     }
02147 
02148   return hthread_count;
02149 }

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

References ACE_GUARD_RETURN, ACE_hthread_t, 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().

01216 {
01217   ACE_TRACE ("ACE_Thread_Manager::hthread_within");
01218   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01219 
01220   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01221        !iter.done ();
01222        iter.advance ())
01223     if (ACE_OS::thr_cmp(iter.next ()->thr_handle_, handle))
01224       return 1;
01225 
01226   return 0;
01227 }

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

References ACE_GUARD_RETURN, ACE_hthread_t, ACE_THR_SPAWNED, ACE_TRACE, append_thr(), find_hthread(), and find_thread().

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

00873 {
00874   ACE_TRACE ("ACE_Thread_Manager::insert_thr");
00875   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00876 
00877   // Check for duplicates and bail out if we're already registered...
00878 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
00879   if (this->find_hthread (t_handle) != 0 )
00880     return -1;
00881 #else  /* ! ACE_VXWORKS */
00882   if (this->find_thread (t_id) != 0 )
00883     return -1;
00884 #endif /* ! ACE_VXWORKS */
00885 
00886   if (grp_id == -1)
00887     grp_id = this->grp_id_++;
00888 
00889   if (this->append_thr (t_id,
00890                         t_handle,
00891                         ACE_THR_SPAWNED,
00892                         grp_id,
00893                         0,
00894                         flags) == -1)
00895     return -1;
00896 
00897   return grp_id;
00898 }

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, ACE_TRACE, delete_thr_mgr_, and thr_mgr_.

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_ = 0;
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, ACE_TRACE, delete_thr_mgr_, and thr_mgr_.

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_ = 1;
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 . Do not wait on a detached thread.

Definition at line 1417 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(), ACE_OS::thr_equal(), and ACE_Thread_Descriptor_Base::thr_handle_.

01418 {
01419   ACE_TRACE ("ACE_Thread_Manager::join");
01420 
01421   ACE_Thread_Descriptor_Base tdb;
01422   int found = 0;
01423 
01424   {
01425     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01426 
01427 #if !defined (ACE_VXWORKS)
01428     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_);
01429          !biter.done ();
01430          biter.advance ())
01431       if (ACE_OS::thr_equal (biter.next ()->thr_id_, tid))
01432         {
01433           ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (0);
01434 # if defined (_AIX)
01435   // The AIX xlC compiler does not match the proper function here - it
01436   // confuses ACE_Thread::join(ACE_thread_t, ACE_thread_t *, void **=0) and
01437   // ACE_Thread::join(ACE_hthread_t, void **=0).  At least at 3.1.4.7 and .8.
01438   // The 2nd arg is ignored for pthreads anyway.
01439 
01440   // And, g++ on AIX needs the three-arg thr_join, also, to pick up the
01441   // proper version from the AIX libraries.
01442           if (ACE_Thread::join (tdb->thr_handle_,
01443                                 &tdb->thr_handle_,
01444                                 status) == -1)
01445 # else  /* ! _AIX */
01446           if (ACE_Thread::join (tdb->thr_handle_, status) == -1)
01447 # endif /* ! _AIX */
01448             return -1;
01449 
01450 # if defined (ACE_HAS_PTHREADS_DRAFT4)  &&  defined (ACE_LACKS_SETDETACH)
01451           // Must explicitly detach threads.  Threads without THR_DETACHED
01452           // were detached in ACE_OS::thr_create ().
01453           ::pthread_detach (&tdb->thr_handle_);
01454 # endif /* ACE_HAS_PTHREADS_DRAFT4 && ACE_LACKS_SETDETACH */
01455 
01456           delete tdb;
01457           return 0;
01458           // return immediately if we've found the thread we want to join.
01459         }
01460 #endif /* !ACE_VXWORKS */
01461 
01462     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01463          !iter.done ();
01464          iter.advance ())
01465       // If threads are created as THR_DETACHED or THR_DAEMON, we
01466       // can't help much.
01467       if (ACE_OS::thr_equal (iter.next ()->thr_id_,tid) &&
01468           (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON)
01469            || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE)))
01470         {
01471           tdb = *iter.next ();
01472           ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01473           found = 1;
01474           break;
01475         }
01476 
01477     if (found == 0)
01478       return -1;
01479     // Didn't find the thread we want or the thread is not joinable.
01480   }
01481 
01482 # if defined (_AIX)
01483   // The AIX xlC compiler does not match the proper function here - it
01484   // confuses ACE_Thread::join(ACE_thread_t, ACE_thread_t *, void **=0) and
01485   // ACE_Thread::join(ACE_hthread_t, void **=0).  At least at 3.1.4.7 and .8.
01486   // The 2nd arg is ignored for pthreads anyway.
01487 
01488   // And, g++ on AIX needs the three-arg thr_join, also, to pick up the
01489   // proper version from the AIX libraries.
01490   if (ACE_Thread::join (tdb.thr_handle_, &tdb.thr_handle_, status) == -1)
01491 # else  /* ! _AIX */
01492   if (ACE_Thread::join (tdb.thr_handle_, status) == -1)
01493 # endif /* ! _AIX */
01494     return -1;
01495 
01496 # if defined (ACE_HAS_PTHREADS_DRAFT4)  &&  defined (ACE_LACKS_SETDETACH)
01497   // Must explicitly detach threads.  Threads without THR_DETACHED
01498   // were detached in ACE_OS::thr_create ().
01499 
01500   ::pthread_detach (&tdb.thr_handle_);
01501 # endif /* ACE_HAS_PTHREADS_DRAFT4 && ACE_LACKS_SETDETACH */
01502   return 0;
01503 }

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

Join the thread described in .

Definition at line 993 of file Thread_Manager.cpp.

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

00994 {
00995   ACE_TRACE ("ACE_Thread_Manager::join_thr");
00996   int const result = ACE_Thread::join (td->thr_handle_);
00997   if (result != 0)
00998     {
00999       // Since the thread are being joined, we should
01000       // let it remove itself from the list.
01001 
01002       //      this->remove_thr (td);
01003       errno = result;
01004       return -1;
01005     }
01006 
01007   return 0;
01008 }

int ACE_Thread_Manager::kill ACE_thread_t  ,
int  signum
 

Definition at line 1135 of file Thread_Manager.cpp.

References ACE_EXECUTE_OP, and ACE_TRACE.

01136 {
01137   ACE_TRACE ("ACE_Thread_Manager::kill");
01138   ACE_EXECUTE_OP (this->kill_thr, signum);
01139 }

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. Send the signum to a single thread. Not supported on platforms that do not have advanced signal support, such as Win32. Send signum to a group of threads, not supported on platforms that do not have advanced signal support, such as Win32.

Definition at line 1402 of file Thread_Manager.cpp.

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

01403 {
01404   ACE_TRACE ("ACE_Thread_Manager::kill_all");
01405   return this->apply_all (&ACE_Thread_Manager::kill_thr, sig);
01406 }

int ACE_Thread_Manager::kill_grp int  grp_id,
int  signum
 

Definition at line 1335 of file Thread_Manager.cpp.

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

01336 {
01337   ACE_TRACE ("ACE_Thread_Manager::kill_grp");
01338   return this->apply_grp (grp_id,
01339                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr), signum);
01340 }

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

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

01880 {
01881   ACE_TRACE ("ACE_Thread_Manager::kill_task");
01882   return this->apply_task (task,
01883                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr));
01884 }

int ACE_Thread_Manager::kill_thr ACE_Thread_Descriptor td,
int  signum
[protected]
 

Send signal signum to the thread described in .

Definition at line 1061 of file Thread_Manager.cpp.

References ACE_thread_t, ACE_TRACE, ENOTSUP, ACE_Unbounded_Queue< ACE_Thread_Descriptor * >::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().

01062 {
01063   ACE_TRACE ("ACE_Thread_Manager::kill_thr");
01064 
01065   ACE_thread_t tid = td->thr_id_;
01066 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
01067   // Skip over the ID-allocated marker, if present.
01068   tid += tid[0] == ACE_THR_ID_ALLOCATED  ?  1  :  0;
01069 #endif /* ACE_VXWORKS */
01070 
01071   int const result = ACE_Thread::kill (tid, signum);
01072 
01073   if (result != 0)
01074     {
01075       // Only remove a thread from us when there is a "real" error.
01076       if (errno != ENOTSUP)
01077         this->thr_to_be_removed_.enqueue_tail (td);
01078 
01079       return -1;
01080     }
01081 
01082     return 0;
01083 }

int ACE_Thread_Manager::num_tasks_in_group int  grp_id  ) 
 

Returns the number of ACE_Task_Base in a group.

Definition at line 1927 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().

01928 {
01929   ACE_TRACE ("ACE_Thread_Manager::num_tasks_in_group");
01930   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01931 
01932   int tasks_count = 0;
01933   size_t i = 0;
01934 
01935   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01936        !iter.done ();
01937        iter.advance ())
01938     {
01939       if (iter.next ()->grp_id_ == grp_id
01940           && this->find_task (iter.next ()->task_, i) == 0
01941           && iter.next ()->task_ != 0)
01942         tasks_count++;
01943 
01944       i++;
01945     }
01946   return tasks_count;
01947 }

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 1952 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().

01953 {
01954   ACE_TRACE ("ACE_Thread_Manager::num_threads_in_task");
01955   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01956 
01957   int threads_count = 0;
01958 
01959   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01960        !iter.done ();
01961        iter.advance ())
01962     if (iter.next ()->task_ == task)
01963       threads_count++;
01964 
01965   return threads_count;
01966 }

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 .

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_VXWORKS)
00293   ACE_UNUSED_ARG (td);
00294 #else  /* ! ACE_VXWORKS */
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_VXWORKS */
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 929 of file Thread_Manager.cpp.

References ACE_thread_t, ACE_TRACE, ACE_Locked_Free_List< ACE_Thread_Descriptor, ACE_SYNCH_MUTEX >::add(), ACE_Thread_Descriptor::self(), ACE_Thread_Descriptor_Base::thr_handle_, thr_list_, thread_desc_freelist_, ACE_Thread_Descriptor::tm_, and zero_cond_.

Referenced by apply_all(), apply_grp(), apply_task(), remove_thr_all(), ACE_Thread_Descriptor::terminate(), and wait().

00931 {
00932   ACE_TRACE ("ACE_Thread_Manager::remove_thr");
00933 
00934 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
00935   ACE_thread_t tid = td->self ();
00936 #endif /* ACE_VXWORKS */
00937 
00938   td->tm_ = 0;
00939   this->thr_list_.remove (td);
00940 
00941 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
00942   // Delete the thread ID, if the ACE_Thread_Manager allocated it.
00943   if (tid  &&  tid[0] == ACE_THR_ID_ALLOCATED)
00944     {
00945       delete [] tid;
00946     }
00947 #endif /* ACE_VXWORKS */
00948 
00949 #if defined (ACE_WIN32)
00950   if (close_handler != 0)
00951     ::CloseHandle (td->thr_handle_);
00952 #else
00953   ACE_UNUSED_ARG (close_handler);
00954 #endif /* ACE_WIN32 */
00955 
00956   this->thread_desc_freelist_.add (td);
00957 
00958 #if defined (ACE_HAS_THREADS)
00959   // Tell all waiters when there are no more threads left in the pool.
00960   if (this->thr_list_.size () == 0)
00961     this->zero_cond_.broadcast ();
00962 #endif /* ACE_HAS_THREADS */
00963 }

void ACE_Thread_Manager::remove_thr_all void   )  [protected]
 

Remove all threads from the table.

Definition at line 968 of file Thread_Manager.cpp.

References remove_thr(), and thr_list_.

Referenced by close(), and wait().

00969 {
00970   ACE_Thread_Descriptor *td = 0;
00971 
00972   while ((td = this->thr_list_.delete_head ()) != 0)
00973     {
00974       this->remove_thr (td, 1);
00975     }
00976 }

int ACE_Thread_Manager::resume ACE_thread_t   ) 
 

Resume a single thread.

Definition at line 1117 of file Thread_Manager.cpp.

References ACE_EXECUTE_OP, and ACE_TRACE.

01118 {
01119   ACE_TRACE ("ACE_Thread_Manager::resume");
01120   ACE_EXECUTE_OP (this->resume_thr, 0);
01121 }

int ACE_Thread_Manager::resume_all void   ) 
 

Resume all stopped threads.

Definition at line 1388 of file Thread_Manager.cpp.

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

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

01389 {
01390   ACE_TRACE ("ACE_Thread_Manager::resume_all");
01391   return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01392 }

int ACE_Thread_Manager::resume_grp int  grp_id  ) 
 

Resume a group of threads.

Definition at line 1325 of file Thread_Manager.cpp.

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

01326 {
01327   ACE_TRACE ("ACE_Thread_Manager::resume_grp");
01328   return this->apply_grp (grp_id,
01329                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01330 }

int ACE_Thread_Manager::resume_task ACE_Task_Base task  ) 
 

Resume all threads in an ACE_Task.

Definition at line 1869 of file Thread_Manager.cpp.

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

Referenced by ACE_Task_Base::resume().

01870 {
01871   ACE_TRACE ("ACE_Thread_Manager::resume_task");
01872   return this->apply_task (task,
01873                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01874 }

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

Resume the thread described in .

Definition at line 1028 of file Thread_Manager.cpp.

References ACE_CLR_BITS, ACE_THR_SUSPENDED, ACE_TRACE, ENOTSUP, ACE_Unbounded_Queue< ACE_Thread_Descriptor * >::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().

01029 {
01030   ACE_TRACE ("ACE_Thread_Manager::resume_thr");
01031 
01032   int const result = ACE_Thread::resume (td->thr_handle_);
01033   if (result == -1) {
01034     if (errno != ENOTSUP)
01035       this->thr_to_be_removed_.enqueue_tail (td);
01036     return -1;
01037   }
01038   else {
01039     ACE_CLR_BITS (td->thr_state_, ACE_THR_SUSPENDED);
01040     return 0;
01041   }
01042 }

void ACE_Thread_Manager::run_thread_exit_hooks int  i  )  [protected]
 

Run the registered hooks when the thread exits.

Definition at line 903 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().

00904 {
00905 #if 0 // currently unused!
00906   ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks");
00907 
00908   // @@ Currently, we have just one hook.  This should clearly be
00909   // generalized to support an arbitrary number of hooks.
00910 
00911   ACE_Thread_Descriptor *td = this->thread_desc_self ();
00912   if (td != 0 && td->cleanup_info.cleanup_hook_ != 0)
00913     {
00914       (*td->cleanup_info_.cleanup_hook_)
00915         (td->cleanup_info_.object_,
00916          td->cleanup_info_.param_);
00917 
00918       td->cleanup_info_.cleanup_hook_ = 0;
00919     }
00920   ACE_UNUSED_ARG (i);
00921 #else
00922   ACE_UNUSED_ARG (i);
00923 #endif /* 0 */
00924 }

int ACE_Thread_Manager::set_grp ACE_Task_Base task,
int  grp_id
 

Set group ids for a particular task.

Definition at line 2208 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().

02209 {
02210   ACE_TRACE ("ACE_Thread_Manager::set_grp");
02211   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02212 
02213   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02214        !iter.done ();
02215        iter.advance ())
02216     if (iter.next ()->task_ == task)
02217       iter.next ()->grp_id_ = grp_id;
02218 
02219   return 0;
02220 }

int ACE_Thread_Manager::set_grp ACE_thread_t  ,
int  grp_id
 

Set group ids for a particular thread id.

Definition at line 1264 of file Thread_Manager.cpp.

References ACE_FIND, ACE_GUARD_RETURN, and ACE_TRACE.

Referenced by ACE_Task_Base::grp_id().

01265 {
01266   ACE_TRACE ("ACE_Thread_Manager::set_grp");
01267   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01268 
01269   ACE_FIND (this->find_thread (t_id), ptr);
01270   if (ptr)
01271     ptr->grp_id_ = grp_id;
01272   else
01273     return -1;
01274   return 0;
01275 }

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 = 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
 

Create a new thread, which executes with argument . Returns: on success a unique group id that can be used to control other threads added to the same group. On failure, returns -1.

Definition at line 680 of file Thread_Manager.cpp.

References ACE_CLR_BITS, ACE_DEFAULT_THREAD_PRIORITY, ACE_GUARD_RETURN, ACE_hthread_t, ACE_TRACE, and spawn_i().

Referenced by ACE_Event_Handler::register_stdin_handler().

00689 {
00690   ACE_TRACE ("ACE_Thread_Manager::spawn");
00691 
00692   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00693 
00694   if (grp_id == -1)
00695     grp_id = this->grp_id_++; // Increment the group id.
00696 
00697   if (priority != ACE_DEFAULT_THREAD_PRIORITY)
00698     ACE_CLR_BITS (flags, THR_INHERIT_SCHED);
00699 
00700   if (this->spawn_i (func,
00701                      args,
00702                      flags,
00703                      t_id,
00704                      t_handle,
00705                      priority,
00706                      grp_id,
00707                      stack,
00708                      stack_size,
00709                      0) == -1)
00710     return -1;
00711 
00712   return grp_id;
00713 }

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
[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_hthread_t, ACE_NEW_RETURN, ACE_THR_SPAWNED, ACE_THREAD_ADAPTER_NAME, ACE_thread_t, ACE_TRACE, append_thr(), ACE_Auto_Basic_Ptr< X >::get(), ACE_Auto_Basic_Ptr< X >::release(), ACE_Auto_Basic_Ptr< X >::reset(), and ACE_Thread::spawn().

Referenced by spawn(), and spawn_n().

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

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
 

Spawn N new threads, which execute with argument . If != 0 the thread_ids of successfully spawned threads will be placed into the buffer (which must be the same size as n). If != 0 it is assumed to be an array of n pointers to the base of the stacks to use for the threads being spawned. If != 0 it is assumed to be an array of n values indicating how big each of the corresponding s are. If != 0 it is assumed to be an array of n thread_handles that will be assigned the values of the thread handles being spawned.

Threads in Thread_Manager can be manipulated in groups based on or using functions such as kill_grp() or cancel_task().

If is assigned, the newly spawned threads are added into the group. Otherwise, the Thread_Manager assigns these n threads with a grp_id. You should choose either assigning everytime, or let the Thread_Manager handles it for you consistently.

The argument is usually assigned by <ACE_Task_Base::activate>. It associates the newly spawned threads with an ACE_Task instance, which defaults to this.

Return values:
-1 on failure (errno will explain...), otherwise returns the group id of the threads.

Definition at line 758 of file Thread_Manager.cpp.

References ACE_DEFAULT_THREAD_STACKSIZE, ACE_GUARD_RETURN, ACE_hthread_t, ACE_TRACE, and spawn_i().

00769 {
00770   ACE_TRACE ("ACE_Thread_Manager::spawn_n");
00771   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00772 
00773   if (grp_id == -1)
00774     grp_id = this->grp_id_++; // Increment the group id.
00775 
00776   for (size_t i = 0; i < n; i++)
00777     {
00778       // @@ What should happen if this fails?! e.g., should we try to
00779       // cancel the other threads that we've already spawned or what?
00780       if (this->spawn_i (func,
00781                          args,
00782                          flags,
00783                          thread_ids == 0 ? 0 : &thread_ids[i],
00784                          thread_handles == 0 ? 0 : &thread_handles[i],
00785                          priority,
00786                          grp_id,
00787                          stack == 0 ? 0 : stack[i],
00788                          stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i],
00789                          task) == -1)
00790         return -1;
00791     }
00792 
00793   return grp_id;
00794 }

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
 

Spawn N new threads, which execute with argument . If != 0 the thread_ids of successfully spawned threads will be placed into the buffer (which must be the same size as n). If != 0 it is assumed to be an array of n pointers to the base of the stacks to use for the threads being spawned. If != 0 it is assumed to be an array of n values indicating how big each of the corresponding s are. If != 0 it is assumed to be an array of n thread_handles that will be assigned the values of the thread handles being spawned.

Threads in Thread_Manager can be manipulated in groups based on or using functions such as kill_grp() or cancel_task().

If is assigned, the newly spawned threads are added into the group. Otherwise, the Thread_Manager assigns these n threads with a grp_id. You should choose either assigning everytime, or let the Thread_Manager handles it for you consistently.

The argument is usually assigned by <ACE_Task_Base::activate>. It associates the newly spawned threads with an ACE_Task instance, which defaults to this.

Return values:
-1 on failure (errno will explain...), otherwise returns the group id of the threads.

Definition at line 718 of file Thread_Manager.cpp.

References ACE_DEFAULT_THREAD_STACKSIZE, ACE_GUARD_RETURN, ACE_hthread_t, ACE_TRACE, and spawn_i().

Referenced by ACE_Task_Base::activate().

00728 {
00729   ACE_TRACE ("ACE_Thread_Manager::spawn_n");
00730   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00731 
00732   if (grp_id == -1)
00733     grp_id = this->grp_id_++; // Increment the group id.
00734 
00735   for (size_t i = 0; i < n; i++)
00736     {
00737       // @@ What should happen if this fails?! e.g., should we try to
00738       // cancel the other threads that we've already spawned or what?
00739       if (this->spawn_i (func,
00740                          args,
00741                          flags,
00742                          0,
00743                          thread_handles == 0 ? 0 : &thread_handles[i],
00744                          priority,
00745                          grp_id,
00746                          stack == 0 ? 0 : stack[i],
00747                          stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i],
00748                          task) == -1)
00749         return -1;
00750     }
00751 
00752   return grp_id;
00753 }

int ACE_Thread_Manager::suspend ACE_thread_t   ) 
 

Suspend a single thread.

Definition at line 1108 of file Thread_Manager.cpp.

References ACE_EXECUTE_OP, and ACE_TRACE.

01109 {
01110   ACE_TRACE ("ACE_Thread_Manager::suspend");
01111   ACE_EXECUTE_OP (this->suspend_thr, 0);
01112 }

int ACE_Thread_Manager::suspend_all void   ) 
 

Suspend all threads.

Definition at line 1395 of file Thread_Manager.cpp.

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

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

01396 {
01397   ACE_TRACE ("ACE_Thread_Manager::suspend_all");
01398   return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01399 }

int ACE_Thread_Manager::suspend_grp int  grp_id  ) 
 

Suspend a group of threads.

Definition at line 1315 of file Thread_Manager.cpp.

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

01316 {
01317   ACE_TRACE ("ACE_Thread_Manager::suspend_grp");
01318   return this->apply_grp (grp_id,
01319                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01320 }

int ACE_Thread_Manager::suspend_task ACE_Task_Base task  ) 
 

Suspend all threads in an ACE_Task.

Definition at line 1860 of file Thread_Manager.cpp.

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

Referenced by ACE_Task_Base::suspend().

01861 {
01862   ACE_TRACE ("ACE_Thread_Manager::suspend_task");
01863   return this->apply_task (task,
01864                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01865 }

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

Suspend the thread described in .

Definition at line 1011 of file Thread_Manager.cpp.

References ACE_SET_BITS, ACE_THR_SUSPENDED, ACE_TRACE, ENOTSUP, ACE_Unbounded_Queue< ACE_Thread_Descriptor * >::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().

01012 {
01013   ACE_TRACE ("ACE_Thread_Manager::suspend_thr");
01014 
01015   int const result = ACE_Thread::suspend (td->thr_handle_);
01016   if (result == -1) {
01017     if (errno != ENOTSUP)
01018       this->thr_to_be_removed_.enqueue_tail (td);
01019     return -1;
01020   }
01021   else {
01022     ACE_SET_BITS (td->thr_state_, ACE_THR_SUSPENDED);
01023     return 0;
01024   }
01025 }

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().

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 1971 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().

01973 {
01974   ACE_TRACE ("ACE_Thread_Manager::task_all_list");
01975   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01976 
01977   size_t task_list_count = 0;
01978 
01979   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01980        !iter.done ();
01981        iter.advance ())
01982     {
01983       if (task_list_count >= n)
01984         break;
01985 
01986       ACE_Task_Base *task_p = iter.next ()->task_;
01987       if (0 != task_p)
01988         {
01989           // This thread has a task pointer; see if it's already in the
01990           // list. Don't add duplicates.
01991           size_t i = 0;
01992           for (; i < task_list_count; ++i)
01993             if (task_list[i] == task_p)
01994               break;
01995           if (i == task_list_count)        // No match - add this one
01996             task_list[task_list_count++] = task_p;
01997         }
01998     }
01999 
02000   return task_list_count;
02001 }

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 2062 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().

02065 {
02066   ACE_TRACE ("ACE_Thread_Manager::task_list");
02067   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02068 
02069   ACE_Task_Base **task_list_iterator = task_list;
02070   size_t task_list_count = 0;
02071   size_t i = 0;
02072 
02073   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02074        !iter.done ();
02075        iter.advance ())
02076     {
02077       if (task_list_count >= n)
02078         break;
02079 
02080       if (iter.next ()->grp_id_ == grp_id
02081           && this->find_task (iter.next ()->task_, i) == 0)
02082         {
02083           task_list_iterator[task_list_count] = iter.next ()->task_;
02084           task_list_count++;
02085         }
02086 
02087       i++;
02088     }
02089 
02090   return task_list_count;
02091 }

int ACE_Thread_Manager::testcancel ACE_thread_t  t_id  ) 
 

True if is cancelled, else false. Always return false if is not managed by the Thread_Manager.

Definition at line 1206 of file Thread_Manager.cpp.

References ACE_THR_CANCELLED, ACE_TRACE, and check_state().

01207 {
01208   ACE_TRACE ("ACE_Thread_Manager::testcancel");
01209   return this->check_state (ACE_THR_CANCELLED, t_id);
01210 }

int ACE_Thread_Manager::testresume ACE_thread_t  t_id  ) 
 

True if is active (i.e., resumed), else false. Always return false if is not managed by the Thread_Manager.

Definition at line 1197 of file Thread_Manager.cpp.

References ACE_THR_SUSPENDED, ACE_TRACE, and check_state().

01198 {
01199   ACE_TRACE ("ACE_Thread_Manager::testresume");
01200   return this->check_state (ACE_THR_SUSPENDED, t_id, 0);
01201 }

int ACE_Thread_Manager::testsuspend ACE_thread_t  t_id  ) 
 

True if is inactive (i.e., suspended), else false. Always return false if is not managed by the Thread_Manager.

Definition at line 1188 of file Thread_Manager.cpp.

References ACE_THR_SUSPENDED, ACE_TRACE, and check_state().

01189 {
01190   ACE_TRACE ("ACE_Thread_Manager::testsuspend");
01191   return this->check_state (ACE_THR_SUSPENDED, t_id);
01192 }

int ACE_Thread_Manager::testterminate ACE_thread_t  t_id  ) 
 

True if 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 is not managed by the Thread_Manager.

Definition at line 1179 of file Thread_Manager.cpp.

References ACE_THR_TERMINATED, ACE_TRACE, and check_state().

01180 {
01181   ACE_TRACE ("ACE_Thread_Manager::testterminate");
01182   return this->check_state (ACE_THR_TERMINATED, t_id);
01183 }

ACE_INLINE ACE_thread_t ACE_Thread_Manager::thr_self void   ) 
 

Return the unique ID of the thread. This is not strictly necessary (because a thread can always just call <ACE_Thread::self>). However, we put it here to be complete.

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., Win32) 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_hthread_t, 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 2030 of file Thread_Manager.cpp.

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

Referenced by check_state().

02032 {
02033   ACE_TRACE ("ACE_Thread_Manager::thr_state");
02034   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02035 
02036   int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ());
02037 
02038   // If we're checking the state of our thread, try to get the cached
02039   // value out of TSS to avoid lookup.
02040   if (self_check)
02041     {
02042       ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc ();
02043       if (desc == 0)
02044         return 0;               // Always return false.
02045       state = desc->thr_state_;
02046     }
02047   else
02048     {
02049       // Not calling from self, have to look it up from the list.
02050       ACE_FIND (this->find_thread (id), ptr);
02051       if (ptr == 0)
02052         return 0;
02053       state = ptr->thr_state_;
02054     }
02055 
02056   return 1;
02057 }

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 2006 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().

02008 {
02009   ACE_TRACE ("ACE_Thread_Manager::thread_all_list");
02010   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02011 
02012   size_t thread_count = 0;
02013 
02014   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02015        !iter.done ();
02016        iter.advance ())
02017     {
02018       if (thread_count >= n)
02019         break;
02020 
02021       thread_list[thread_count] = iter.next ()->thr_id_;
02022       thread_count ++;
02023     }
02024 
02025   return thread_count;
02026 }

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, ACE_thread_t, 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 . 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 2152 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().

02155 {
02156   ACE_TRACE ("ACE_Thread_Manager::thread_grp_list");
02157   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02158 
02159   size_t thread_count = 0;
02160 
02161   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02162        !iter.done ();
02163        iter.advance ())
02164     {
02165       if (thread_count >= n)
02166         break;
02167 
02168       if (iter.next ()->grp_id_ == grp_id)
02169         {
02170           thread_list[thread_count] = iter.next ()->thr_id_;
02171           thread_count++;
02172         }
02173     }
02174 
02175   return thread_count;
02176 }

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 2096 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().

02099 {
02100   ACE_TRACE ("ACE_Thread_Manager::thread_list");
02101   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02102 
02103   size_t thread_count = 0;
02104 
02105   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02106        !iter.done ();
02107        iter.advance ())
02108     {
02109       if (thread_count >= n)
02110         break;
02111 
02112       if (iter.next ()->task_ == task)
02113         {
02114           thread_list[thread_count] = iter.next ()->thr_id_;
02115           thread_count++;
02116         }
02117     }
02118 
02119   return thread_count;
02120 }

int ACE_Thread_Manager::thread_within ACE_thread_t  tid  ) 
 

Definition at line 1230 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().

01231 {
01232   ACE_TRACE ("ACE_Thread_Manager::thread_within");
01233   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01234 
01235   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01236        !iter.done ();
01237        iter.advance ())
01238     if (ACE_OS::thr_equal (iter.next ()->thr_id_, tid))
01239       return 1;
01240 
01241   return 0;
01242 }

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 0.
abandon_detached_threads If non-0, 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 non-0 then treat timeout as absolute time, else relative time.
Returns:
0 on success * and -1 on failure.
NOTE that 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 1646 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_Unbounded_Queue< ACE_Thread_Descriptor * >::dequeue_head(), ACE_Double_Linked_List_Iterator_Base< T >::done(), ACE_Unbounded_Queue< ACE_Thread_Descriptor * >::enqueue_tail(), ACE_OS_Thread_Descriptor::flags_, ACE_OS::gettimeofday(), ACE_Double_Linked_List< T >::insert_tail(), ACE_Unbounded_Queue< ACE_Thread_Descriptor * >::is_empty(), ACE_Thread::join(), ACE_Double_Linked_List_Iterator_Base< T >::next(), remove_thr(), remove_thr_all(), ACE_Object_Manager::shutting_down(), terminated_thr_list_, ACE_Thread_Descriptor_Base::thr_handle_, thr_list_, thr_to_be_removed_, and zero_cond_.

Referenced by close().

01649 {
01650   ACE_TRACE ("ACE_Thread_Manager::wait");
01651 
01652   ACE_Time_Value local_timeout;
01653   // Check to see if we're using absolute time or not.
01654   if (use_absolute_time == false && timeout != 0)
01655     {
01656       local_timeout = *timeout;
01657       local_timeout += ACE_OS::gettimeofday ();
01658       timeout = &local_timeout;
01659     }
01660 
01661 #if !defined (ACE_VXWORKS)
01662   ACE_Double_Linked_List<ACE_Thread_Descriptor_Base> term_thr_list_copy;
01663 #endif /* ACE_VXWORKS */
01664 
01665 #if defined (ACE_HAS_THREADS)
01666   {
01667     // Just hold onto the guard while waiting.
01668     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01669 
01670     if (ACE_Object_Manager::shutting_down () != 1)
01671       {
01672         // Program is not shutting down.  Perform a normal wait on threads.
01673         if (abandon_detached_threads != 0)
01674           {
01675             ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01676             for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor>
01677                    iter (this->thr_list_);
01678                  !iter.done ();
01679                  iter.advance ())
01680               if (ACE_BIT_ENABLED (iter.next ()->flags_,
01681                                    THR_DETACHED | THR_DAEMON)
01682                   && ACE_BIT_DISABLED (iter.next ()->flags_, THR_JOINABLE))
01683                 {
01684                   this->thr_to_be_removed_.enqueue_tail (iter.next ());
01685                   ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01686                 }
01687 
01688             if (! this->thr_to_be_removed_.is_empty ())
01689               {
01690                 ACE_Thread_Descriptor *td;
01691                 while (this->thr_to_be_removed_.dequeue_head (td) != -1)
01692                   this->remove_thr (td, 1);
01693               }
01694           }
01695 
01696         while (this->thr_list_.size () > 0)
01697           if (this->zero_cond_.wait (timeout) == -1)
01698             return -1;
01699       }
01700     else
01701         // Program is shutting down, no chance to wait on threads.
01702         // Therefore, we'll just remove threads from the list.
01703         this->remove_thr_all ();
01704 
01705 #if !defined (ACE_VXWORKS)
01706   ACE_Thread_Descriptor_Base* item = 0;
01707   while ((item = this->terminated_thr_list_.delete_head ()) != 0)
01708     {
01709       term_thr_list_copy.insert_tail (item);
01710     }
01711 #endif /* ACE_VXWORKS */
01712     // Release the guard, giving other threads a chance to run.
01713   }
01714 
01715 #if !defined (ACE_VXWORKS)
01716     // @@ VxWorks doesn't support thr_join (yet.)  We are working
01717     //on our implementation.   Chorus'es thr_join seems broken.
01718     ACE_Thread_Descriptor_Base *item = 0;
01719 
01720     while ((item = term_thr_list_copy.delete_head ()) != 0)
01721       {
01722         if (ACE_BIT_DISABLED (item->flags_, THR_DETACHED | THR_DAEMON)
01723             || ACE_BIT_ENABLED (item->flags_, THR_JOINABLE))
01724           // Detached handles shouldn't reached here.
01725           (void) ACE_Thread::join (item->thr_handle_);
01726 
01727 # if defined (ACE_HAS_PTHREADS_DRAFT4)  &&  defined (ACE_LACKS_SETDETACH)
01728         // Must explicitly detach threads.  Threads without
01729         // THR_DETACHED were detached in ACE_OS::thr_create ().
01730         ::pthread_detach (&item->thr_handle_);
01731 # endif /* ACE_HAS_PTHREADS_DRAFT4 && ACE_LACKS_SETDETACH */
01732         delete item;
01733       }
01734 
01735 #endif /* ! ACE_VXWORKS */
01736 #else
01737   ACE_UNUSED_ARG (timeout);
01738   ACE_UNUSED_ARG (abandon_detached_threads);
01739 #endif /* ACE_HAS_THREADS */
01740 
01741   return 0;
01742 }

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 1508 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_, and ACE_Thread_Descriptor_Base::thr_handle_.

Referenced by ACE_Proactor_Timer_Handler::~ACE_Proactor_Timer_Handler().

01509 {
01510   ACE_TRACE ("ACE_Thread_Manager::wait_grp");
01511 
01512   int copy_count = 0;
01513   ACE_Thread_Descriptor_Base *copy_table = 0;
01514 
01515   // We have to make sure that while we wait for these threads to
01516   // exit, we do not have the lock.  Therefore we make a copy of all
01517   // interesting entries and let go of the lock.
01518   {
01519     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01520 
01521 #if !defined (ACE_VXWORKS)
01522     ACE_NEW_RETURN (copy_table,
01523                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()
01524                                                + this->terminated_thr_list_.size ()],
01525                     -1);
01526 #else
01527     ACE_NEW_RETURN (copy_table,
01528                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()],
01529                     -1);
01530 #endif /* ACE_VXWORKS */
01531 
01532     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01533          !iter.done ();
01534          iter.advance ())
01535       // If threads are created as THR_DETACHED or THR_DAEMON, we
01536       // can't help much.
01537       if (iter.next ()->grp_id_ == grp_id &&
01538           (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON)
01539            || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE)))
01540         {
01541           ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01542           copy_table[copy_count++] = *iter.next ();
01543         }
01544 
01545 #if !defined (ACE_VXWORKS)
01546     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_);
01547          !biter.done ();
01548          biter.advance ())
01549       // If threads are created as THR_DETACHED or THR_DAEMON, we
01550       // can't help much.
01551       if (biter.next ()->grp_id_ == grp_id)
01552         {
01553           ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (0);
01554           copy_table[copy_count++] = *tdb;
01555           delete tdb;
01556         }
01557 #endif /* !ACE_VXWORKS */
01558   }
01559 
01560   // Now actually join() with all the threads in this group.
01561   int result = 0;
01562 
01563   for (int i = 0;
01564        i < copy_count && result != -1;
01565        i++)
01566     {
01567       if (ACE_Thread::join (copy_table[i].thr_handle_) == -1)
01568         result = -1;
01569 
01570 # if defined (ACE_HAS_PTHREADS_DRAFT4)  &&  defined (ACE_LACKS_SETDETACH)
01571       // Must explicitly detach threads.  Threads without THR_DETACHED
01572       // were detached in ACE_OS::thr_create ().
01573       ::pthread_detach (&copy_table[i].thr_handle_);
01574 # endif /* ACE_HAS_PTHREADS_DRAFT4 && ACE_LACKS_SETDETACH */
01575     }
01576 
01577   delete [] copy_table;
01578 
01579   return result;
01580 }

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 1782 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(), terminated_thr_list_, and ACE_Thread_Descriptor_Base::thr_handle_.

Referenced by ACE_Task_Base::wait().

01783 {
01784   int copy_count = 0;
01785   ACE_Thread_Descriptor_Base *copy_table = 0;
01786 
01787   // We have to make sure that while we wait for these threads to
01788   // exit, we do not have the lock.  Therefore we make a copy of all
01789   // interesting entries and let go of the lock.
01790   {
01791     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01792 
01793 #if !defined (ACE_VXWORKS)
01794     ACE_NEW_RETURN (copy_table,
01795                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()
01796                                                 + this->terminated_thr_list_.size ()],
01797                     -1);
01798 #else
01799     ACE_NEW_RETURN (copy_table,
01800                     ACE_Thread_Descriptor_Base [this->thr_list_.size ()],
01801                     -1);
01802 #endif /* ACE_VXWORKS */
01803 
01804     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01805          !iter.done ();
01806          iter.advance ())
01807       // If threads are created as THR_DETACHED or THR_DAEMON, we
01808       // can't wait on them here.
01809       if (iter.next ()->task_ == task &&
01810           (ACE_BIT_DISABLED (iter.next ()->flags_,
01811                              THR_DETACHED | THR_DAEMON)
01812            || ACE_BIT_ENABLED (iter.next ()->flags_,
01813                                THR_JOINABLE)))
01814         {
01815           ACE_SET_BITS (iter.next ()->thr_state_,
01816                         ACE_THR_JOINING);
01817           copy_table[copy_count++] = *iter.next ();
01818         }
01819 
01820 #if !defined (ACE_VXWORKS)
01821     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> titer (this->terminated_thr_list_);
01822          !titer.done ();
01823          titer.advance ())
01824       // If threads are created as THR_DETACHED or THR_DAEMON, we can't help much here.
01825       if (titer.next ()->task_ == task)
01826         {
01827           ACE_Thread_Descriptor_Base *tdb =
01828             titer.advance_and_remove (0);
01829           copy_table[copy_count++] = *tdb;
01830           delete tdb;
01831         }
01832 #endif /* ACE_VXWORKS */
01833   }
01834 
01835   // Now to do the actual work
01836   int result = 0;
01837 
01838   for (int i = 0;
01839        i < copy_count && result != -1;
01840        i++)
01841     {
01842       if (ACE_Thread::join (copy_table[i].thr_handle_) == -1)
01843         result = -1;
01844 
01845 # if defined (ACE_HAS_PTHREADS_DRAFT4)  &&  defined (ACE_LACKS_SETDETACH)
01846       // Must explicitly detach threads.  Threads without THR_DETACHED
01847       // were detached in ACE_OS::thr_create ().
01848       ::pthread_detach (&copy_table[i].thr_handle_);
01849 # endif /* ACE_HAS_PTHREADS_DRAFT4 && ACE_LACKS_SETDETACH */
01850     }
01851 
01852   delete [] copy_table;
01853 
01854   return result;
01855 }


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

Referenced by close(), and wait_on_exit().

int ACE_Thread_Manager::delete_thr_mgr_ = 0 [static, private]
 

Must delete the if non-0.

Definition at line 51 of file Thread_Manager.cpp.

Referenced by close_singleton(), and instance().

int ACE_Thread_Manager::grp_id_ [protected]
 

Keeps track of the next group id to assign.

Definition at line 1102 of file Thread_Manager.h.

Referenced by dump().

ACE_Thread_Mutex ACE_Thread_Manager::lock_ [protected]
 

Serialize access to the .

Definition at line 1111 of file Thread_Manager.h.

ACE_Double_Linked_List<ACE_Thread_Descriptor_Base> ACE_Thread_Manager::terminated_thr_list_ [protected]
 

Collect terminated but not yet joined thread entries.

Definition at line 1095 of file Thread_Manager.h.

Referenced by register_as_terminated(), wait(), 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 1091 of file Thread_Manager.h.

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

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

Pointer to a process-wide ACE_Thread_Manager.

Definition at line 47 of file Thread_Manager.cpp.

Referenced by close_singleton(), and instance().

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

Referenced by remove_thr().

ACE_Condition_Thread_Mutex ACE_Thread_Manager::zero_cond_ [protected]
 

Keep track of when there are no more threads.

Definition at line 1114 of file Thread_Manager.h.

Referenced by remove_thr(), and wait().


The documentation for this class was generated from the following files:
Generated on Sun Jan 27 12:58:40 2008 for ACE by doxygen 1.3.6