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

enum  {
  ACE_THR_IDLE = 0x00000000, ACE_THR_SPAWNED = 0x00000001, ACE_THR_RUNNING = 0x00000002, ACE_THR_SUSPENDED = 0x00000004,
  ACE_THR_CANCELLED = 0x00000008, ACE_THR_TERMINATED = 0x00000010, ACE_THR_JOINING = 0x10000000
}
typedef int(ACE_Thread_Manager::* ACE_THR_MEMBER_FUNC )(ACE_Thread_Descriptor *, int)

Public Member Functions

 ACE_Thread_Manager (size_t preaolloc=ACE_DEFAULT_THREAD_MANAGER_PREALLOC, size_t lwm=ACE_DEFAULT_THREAD_MANAGER_LWM, size_t inc=ACE_DEFAULT_THREAD_MANAGER_INC, size_t hwm=ACE_DEFAULT_THREAD_MANAGER_HWM)
 Initialization and termination methods.
 ~ACE_Thread_Manager (void)
int open (size_t size=0)
 No-op. Currently unused.
int close (void)
int spawn (ACE_THR_FUNC func, void *arg=0, long flags=THR_NEW_LWP|THR_JOINABLE|THR_INHERIT_SCHED, ACE_thread_t *t_id=0, ACE_hthread_t *t_handle=0, long priority=ACE_DEFAULT_THREAD_PRIORITY, int grp_id=-1, void *stack=0, size_t stack_size=ACE_DEFAULT_THREAD_STACKSIZE, const char **thr_name=0)
int spawn_n (size_t n, ACE_THR_FUNC func, void *arg=0, long flags=THR_NEW_LWP|THR_JOINABLE|THR_INHERIT_SCHED, long priority=ACE_DEFAULT_THREAD_PRIORITY, int grp_id=-1, ACE_Task_Base *task=0, ACE_hthread_t thread_handles[]=0, void *stack[]=0, size_t stack_size[]=0, const char *thr_name[]=0)
int spawn_n (ACE_thread_t thread_ids[], size_t n, ACE_THR_FUNC func, void *arg, long flags, long priority=ACE_DEFAULT_THREAD_PRIORITY, int grp_id=-1, void *stack[]=0, size_t stack_size[]=0, ACE_hthread_t thread_handles[]=0, ACE_Task_Base *task=0, const char *thr_name[]=0)
ACE_THR_FUNC_RETURN exit (ACE_THR_FUNC_RETURN status=0, bool do_thread_exit=true)
int wait (const ACE_Time_Value *timeout=0, bool abandon_detached_threads=false, bool use_absolute_time=true)
int join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status=0)
 Join a thread specified by tid. Do not wait on a detached thread.
int wait_grp (int grp_id)
int thr_self (ACE_hthread_t &)
ACE_thread_t thr_self (void)
ACE_Task_Basetask (void)
int kill_all (int signum)
int kill (ACE_thread_t, int signum)
int kill_grp (int grp_id, int signum)
int cancel_all (int async_cancel=0)
int cancel (ACE_thread_t, int async_cancel=0)
int cancel_grp (int grp_id, int async_cancel=0)
int testcancel (ACE_thread_t t_id)
int testterminate (ACE_thread_t t_id)
int set_grp (ACE_thread_t, int grp_id)
 Set group ids for a particular thread id.
int get_grp (ACE_thread_t, int &grp_id)
 Get group ids for a particular thread id.
int hthread_within (ACE_hthread_t handle)
int thread_within (ACE_thread_t tid)
int num_tasks_in_group (int grp_id)
 Returns the number of ACE_Task_Base in a group.
int num_threads_in_task (ACE_Task_Base *task)
 Returns the number of threads in an ACE_Task_Base.
ssize_t task_list (int grp_id, ACE_Task_Base *task_list[], size_t n)
ssize_t thread_list (ACE_Task_Base *task, ACE_thread_t thread_list[], size_t n)
ssize_t hthread_list (ACE_Task_Base *task, ACE_hthread_t hthread_list[], size_t n)
ssize_t thread_grp_list (int grp_id, ACE_thread_t thread_list[], size_t n)
ssize_t hthread_grp_list (int grp_id, ACE_hthread_t hthread_list[], size_t n)
ssize_t task_all_list (ACE_Task_Base *task_list[], size_t n)
ssize_t thread_all_list (ACE_thread_t thread_list[], size_t n)
int set_grp (ACE_Task_Base *task, int grp_id)
 Set group ids for a particular task.
int get_grp (ACE_Task_Base *task, int &grp_id)
 Get group ids for a particular task.
size_t count_threads (void) const
int thr_state (ACE_thread_t id, ACE_UINT32 &state)
int at_exit (ACE_At_Thread_Exit *cleanup)
int at_exit (ACE_At_Thread_Exit &cleanup)
int at_exit (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param)
void wait_on_exit (int dowait)
int wait_on_exit (void)
void dump (void)
 Dump the state of an object.
Suspend and resume methods

Suspend/resume is not supported on all platforms. For example, Pthreads does not support these functions.



int suspend_all (void)
 Suspend all threads.
int suspend (ACE_thread_t)
 Suspend a single thread.
int suspend_grp (int grp_id)
 Suspend a group of threads.
int testsuspend (ACE_thread_t t_id)
int resume_all (void)
 Resume all stopped threads.
int resume (ACE_thread_t)
 Resume a single thread.
int resume_grp (int grp_id)
 Resume a group of threads.
int testresume (ACE_thread_t t_id)
Task-related operations



int wait_task (ACE_Task_Base *task)
int suspend_task (ACE_Task_Base *task)
int resume_task (ACE_Task_Base *task)
int kill_task (ACE_Task_Base *task, int signum)
int cancel_task (ACE_Task_Base *task, int async_cancel=0)

Static Public Member Functions

static ACE_Thread_Managerinstance (void)
 Get pointer to a process-wide ACE_Thread_Manager.
static ACE_Thread_Managerinstance (ACE_Thread_Manager *)
static void close_singleton (void)
 Delete the dynamically allocated Singleton.

Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.

Protected Member Functions

ACE_Thread_Descriptorthread_desc_self (void)
ACE_Thread_Descriptorthread_descriptor (ACE_thread_t)
ACE_Thread_Descriptorhthread_descriptor (ACE_hthread_t)
int spawn_i (ACE_THR_FUNC func, void *arg, long flags, ACE_thread_t *=0, ACE_hthread_t *t_handle=0, long priority=ACE_DEFAULT_THREAD_PRIORITY, int grp_id=-1, void *stack=0, size_t stack_size=0, ACE_Task_Base *task=0, const char **thr_name=0)
 Create a new thread (must be called with locks held).
void run_thread_exit_hooks (int i)
 Run the registered hooks when the thread exits.
ACE_Thread_Descriptorfind_thread (ACE_thread_t t_id)
ACE_Thread_Descriptorfind_hthread (ACE_hthread_t h_id)
ACE_Thread_Descriptorfind_task (ACE_Task_Base *task, size_t slot=0)
int insert_thr (ACE_thread_t t_id, ACE_hthread_t, int grp_id=-1, long flags=0)
 Insert a thread in the table (checks for duplicates).
int append_thr (ACE_thread_t t_id, ACE_hthread_t, ACE_UINT32, int grp_id, ACE_Task_Base *task=0, long flags=0, ACE_Thread_Descriptor *td=0)
void remove_thr (ACE_Thread_Descriptor *td, int close_handler)
 Remove thread from the table.
void remove_thr_all (void)
 Remove all threads from the table.
int check_state (ACE_UINT32 state, ACE_thread_t thread, int enable=1)
int apply_task (ACE_Task_Base *task, ACE_THR_MEMBER_FUNC func, int=0)
 Apply func to all members of the table that match the task.
int apply_grp (int grp_id, ACE_THR_MEMBER_FUNC func, int arg=0)
 Apply func to all members of the table that match the grp_id.
int apply_all (ACE_THR_MEMBER_FUNC, int=0)
 Apply func to all members of the table.
int join_thr (ACE_Thread_Descriptor *td, int=0)
 Join the thread described in td.
int resume_thr (ACE_Thread_Descriptor *td, int=0)
 Resume the thread described in td.
int suspend_thr (ACE_Thread_Descriptor *td, int=0)
 Suspend the thread described in td.
int kill_thr (ACE_Thread_Descriptor *td, int signum)
 Send signal signum to the thread described in td.
int cancel_thr (ACE_Thread_Descriptor *td, int async_cancel=0)
 Set the cancellation flag for the thread described in td.
int register_as_terminated (ACE_Thread_Descriptor *td)
 Register a thread as terminated and put it into the <terminated_thr_list_>.

Static Protected Member Functions

static int set_thr_exit (ACE_TSS_TYPE(ACE_Thread_Exit)*ptr)
 Setting the static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_ pointer.

Protected Attributes

ACE_Double_Linked_List
< ACE_Thread_Descriptor
thr_list_
ACE_Double_Linked_List
< ACE_Thread_Descriptor_Base
terminated_thr_list_
 Collect terminated but not yet joined thread entries.
ACE_Unbounded_Queue
< ACE_Thread_Descriptor * > 
thr_to_be_removed_
 Collect pointers to thread descriptors of threads to be removed later.
int grp_id_
 Keeps track of the next group id to assign.
int automatic_wait_
ACE_Locked_Free_List
< ACE_Thread_Descriptor,
ACE_SYNCH_MUTEX > 
thread_desc_freelist_

Static Private Member Functions

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

Static Private Attributes

static ACE_Thread_Managerthr_mgr_ = 0
 Pointer to a process-wide ACE_Thread_Manager.
static bool delete_thr_mgr_ = false
 Must delete the thr_mgr_ if true.

Friends

class ACE_Thread_Control
class ACE_Thread_Exit
class ACE_Thread_Descriptor

Detailed Description

Manages a pool of threads.

This class allows operations on groups of threads atomically. The default behavior of thread manager is to wait on all threads under it's management when it gets destructed. Therefore, remember to remove a thread from thread manager if you don't want it to wait for the thread. There are also functions to disable this default wait-on-exit behavior. However, if your program depends on turning this off to run correctly, you are probably doing something wrong. Rule of thumb, use ACE_Thread to manage your daemon threads. Notice that if there're threads which live beyond the scope of main(), you are sure to have resource leaks in your program. Remember to wait on threads before exiting your main program if that could happen in your programs.

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


Member Enumeration Documentation

anonymous enum

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

Enumerator:
ACE_THR_IDLE 

Uninitialized.

ACE_THR_SPAWNED 

Created but not yet running.

ACE_THR_RUNNING 

Thread is active (naturally, we don't know if it's actually running* because we aren't the scheduler...).

ACE_THR_SUSPENDED 

Thread is suspended.

ACE_THR_CANCELLED 

Thread has been cancelled (which is an indiction that it needs to terminate...).

ACE_THR_TERMINATED 

Thread has shutdown, but the slot in the thread manager hasn't been reclaimed yet.

ACE_THR_JOINING 

Join operation has been invoked on the thread by thread manager.

Definition at line 398 of file Thread_Manager.h.

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


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

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

ACE_Thread_Manager::~ACE_Thread_Manager ( void   ) 

Definition at line 456 of file Thread_Manager.cpp.

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


Member Function Documentation

static ACE_Thread_Manager::ACE_TSS_TYPE ( ACE_Thread_Exit   )  [static, private]

Global ACE_TSS (ACE_Thread_Exit) object ptr.

int ACE_Thread_Manager::append_thr ( ACE_thread_t  t_id,
ACE_hthread_t  t_handle,
ACE_UINT32  thr_state,
int  grp_id,
ACE_Task_Base task = 0,
long  flags = 0,
ACE_Thread_Descriptor td = 0 
) [protected]

Append a thread in the table (adds at the end, growing the table if necessary).

Definition at line 785 of file Thread_Manager.cpp.

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

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

Apply func to all members of the table.

Definition at line 1343 of file Thread_Manager.cpp.

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

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

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

Definition at line 1263 of file Thread_Manager.cpp.

01266 {
01267   ACE_TRACE ("ACE_Thread_Manager::apply_grp");
01268   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01269   ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01270 
01271   int result = 0;
01272 
01273   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01274        !iter.done ();
01275        iter.advance ())
01276     {
01277       if (iter.next ()->grp_id_ == grp_id)
01278         {
01279           if ((this->*func) (iter.next (), arg) == -1)
01280             {
01281               result = -1;
01282             }
01283         }
01284     }
01285 
01286   // Must remove threads after we have traversed the thr_list_ to
01287   // prevent clobber thr_list_'s integrity.
01288 
01289   if (! this->thr_to_be_removed_.is_empty ())
01290     {
01291       // Save/restore errno.
01292       ACE_Errno_Guard error (errno);
01293 
01294       for (ACE_Thread_Descriptor *td;
01295            this->thr_to_be_removed_.dequeue_head (td) != -1;
01296            )
01297         this->remove_thr (td, 1);
01298     }
01299 
01300   return result;
01301 }

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

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

Definition at line 1697 of file Thread_Manager.cpp.

01700 {
01701   ACE_TRACE ("ACE_Thread_Manager::apply_task");
01702   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01703   ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
01704 
01705   int result = 0;
01706 
01707   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01708        !iter.done ();
01709        iter.advance ())
01710     if (iter.next ()->task_ == task
01711         && (this->*func) (iter.next (), arg) == -1)
01712       result = -1;
01713 
01714   // Must remove threads after we have traversed the thr_list_ to
01715   // prevent clobber thr_list_'s integrity.
01716 
01717   if (! this->thr_to_be_removed_.is_empty ())
01718     {
01719       // Save/restore errno.
01720       ACE_Errno_Guard error (errno);
01721 
01722       for (ACE_Thread_Descriptor *td = 0;
01723            this->thr_to_be_removed_.dequeue_head (td) != -1;
01724            )
01725         this->remove_thr (td, 1);
01726     }
01727 
01728   return result;
01729 }

int ACE_Thread_Manager::at_exit ( void *  object,
ACE_CLEANUP_FUNC  cleanup_hook,
void *  param 
)
Deprecated:
This function is deprecated. Please use the previous two at_exit method. Notice that you should avoid mixing this method with the previous two at_exit methods.

Register an object (or array) for cleanup at thread termination. "cleanup_hook" points to a (global, or static member) function that is called for the object or array when it to be destroyed. It may perform any necessary cleanup specific for that object or its class. "param" is passed as the second parameter to the "cleanup_hook" function; the first parameter is the object (or array) to be destroyed. "cleanup_hook", for example, may delete the object (or array). If <cleanup_hook> == 0, the <object> will _NOT_ get cleanup at thread exit. You can use this to cancel the previously added at_exit.

Definition at line 263 of file Thread_Manager.inl.

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

int ACE_Thread_Manager::at_exit ( ACE_At_Thread_Exit cleanup  ) 

Register an At_Thread_Exit hook and the ownership is retained for the caller. Normally used when the at_exit hook is created in stack.

Definition at line 253 of file Thread_Manager.inl.

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

int ACE_Thread_Manager::at_exit ( ACE_At_Thread_Exit cleanup  ) 

Register an At_Thread_Exit hook and the ownership is acquire by Thread_Descriptor, this is the usual case when the AT is dynamically allocated.

Definition at line 243 of file Thread_Manager.inl.

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

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

Cancel a single thread.

Definition at line 1101 of file Thread_Manager.cpp.

01102 {
01103   ACE_TRACE ("ACE_Thread_Manager::cancel");
01104   ACE_EXECUTE_OP (this->cancel_thr, async_cancel);
01105 }

int ACE_Thread_Manager::cancel_all ( int  async_cancel = 0  ) 

Cancel's all the threads.

Definition at line 1402 of file Thread_Manager.cpp.

01403 {
01404   ACE_TRACE ("ACE_Thread_Manager::cancel_all");
01405   return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01406                           async_cancel);
01407 }

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

Cancel a group of threads.

Definition at line 1334 of file Thread_Manager.cpp.

01335 {
01336   ACE_TRACE ("ACE_Thread_Manager::cancel_grp");
01337   return this->apply_grp (grp_id,
01338                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01339                           async_cancel);
01340 }

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

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

Definition at line 1837 of file Thread_Manager.cpp.

01839 {
01840   ACE_TRACE ("ACE_Thread_Manager::cancel_task");
01841   return this->apply_task (task,
01842                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
01843                            async_cancel);
01844 }

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

Set the cancellation flag for the thread described in td.

Definition at line 1024 of file Thread_Manager.cpp.

01025 {
01026   ACE_TRACE ("ACE_Thread_Manager::cancel_thr");
01027   // Must set the state first and then try to cancel the thread.
01028   ACE_SET_BITS (td->thr_state_, ACE_THR_CANCELLED);
01029 
01030   if (async_cancel != 0)
01031     // Note that this call only does something relevant if the OS
01032     // platform supports asynchronous thread cancellation.  Otherwise,
01033     // it's a no-op.
01034     return ACE_Thread::cancel (td->thr_id_);
01035 
01036   return 0;
01037 }

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

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

Definition at line 1117 of file Thread_Manager.cpp.

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

int ACE_Thread_Manager::close ( void   ) 

Release all resources. By default, this method will wait until all threads exit. However, when called from close_singleton(), most global resources are destroyed and thus, close() does not try to wait; it simply cleans up internal thread records (the thread descriptor list).

Definition at line 439 of file Thread_Manager.cpp.

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

void ACE_Thread_Manager::close_singleton ( void   )  [static]

Delete the dynamically allocated Singleton.

Definition at line 416 of file Thread_Manager.cpp.

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

size_t ACE_Thread_Manager::count_threads ( void   )  const

Return a count of the current number of threads active in the <Thread_Manager>.

Definition at line 300 of file Thread_Manager.inl.

00301 {
00302   return this->thr_list_.size ();
00303 }

void ACE_Thread_Manager::dump ( void   ) 

Dump the state of an object.

Definition at line 65 of file Thread_Manager.cpp.

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

ACE_THR_FUNC_RETURN ACE_Thread_Manager::exit ( ACE_THR_FUNC_RETURN  status = 0,
bool  do_thread_exit = true 
)

Called to clean up when a thread exits.

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

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

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

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

Definition at line 823 of file Thread_Manager.cpp.

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

ACE_Thread_Descriptor * ACE_Thread_Manager::find_task ( ACE_Task_Base task,
size_t  slot = 0 
) [protected]

Locate the thread descriptor address of the list occupied by task. Returns 0 if task is not in the table doesn't contain task.

Definition at line 1851 of file Thread_Manager.cpp.

01852 {
01853   ACE_TRACE ("ACE_Thread_Manager::find_task");
01854 
01855   size_t i = 0;
01856 
01857   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01858        !iter.done ();
01859        iter.advance ())
01860     {
01861       if (i >= slot)
01862         break;
01863 
01864       if (task == iter.next ()->task_)
01865         return iter.next ();
01866 
01867       ++i;
01868     }
01869 
01870   return 0;
01871 }

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

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

Definition at line 842 of file Thread_Manager.cpp.

00843 {
00844   ACE_TRACE ("ACE_Thread_Manager::find_thread");
00845 
00846   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
00847        !iter.done ();
00848        iter.advance ())
00849     {
00850       if (ACE_OS::thr_equal (iter.next ()->thr_id_, t_id))
00851         {
00852           return iter.next ();
00853         }
00854     }
00855   return 0;
00856 }

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

Get group ids for a particular task.

Definition at line 2213 of file Thread_Manager.cpp.

02214 {
02215   ACE_TRACE ("ACE_Thread_Manager::get_grp");
02216   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02217 
02218   ACE_FIND (this->find_task (task), ptr);
02219   grp_id = ptr->grp_id_;
02220   return 0;
02221 }

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

Get group ids for a particular thread id.

Definition at line 1230 of file Thread_Manager.cpp.

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

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

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

Definition at line 332 of file Thread_Manager.cpp.

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

ssize_t ACE_Thread_Manager::hthread_grp_list ( int  grp_id,
ACE_hthread_t  hthread_list[],
size_t  n 
)

Returns in hthread_list a list of up to n thread handles in a group grp_id. The caller must allocate memory for hthread_list.

Definition at line 2165 of file Thread_Manager.cpp.

02168 {
02169   ACE_TRACE ("ACE_Thread_Manager::hthread_grp_list");
02170   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02171 
02172   size_t hthread_count = 0;
02173 
02174   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02175        !iter.done ();
02176        iter.advance ())
02177     {
02178       if (hthread_count >= n)
02179         {
02180           break;
02181         }
02182 
02183       if (iter.next ()->grp_id_ == grp_id)
02184         {
02185           hthread_list[hthread_count] = iter.next ()->thr_handle_;
02186           hthread_count++;
02187         }
02188     }
02189 
02190   return ACE_Utils::truncate_cast<ssize_t> (hthread_count);
02191 }

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

Returns in hthread_list a list of up to n thread handles in an ACE_Task_Base. The caller must allocate memory for hthread_list. In case of an error, -1 is returned. If no requested values are found, 0 is returned, otherwise correct number of retrieved values are returned.

Definition at line 2105 of file Thread_Manager.cpp.

02108 {
02109   ACE_TRACE ("ACE_Thread_Manager::hthread_list");
02110   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02111 
02112   size_t hthread_count = 0;
02113 
02114   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02115        !iter.done ();
02116        iter.advance ())
02117     {
02118       if (hthread_count >= n)
02119         {
02120           break;
02121         }
02122 
02123       if (iter.next ()->task_ == task)
02124         {
02125           hthread_list[hthread_count] = iter.next ()->thr_handle_;
02126           ++hthread_count;
02127         }
02128     }
02129 
02130   return ACE_Utils::truncate_cast<ssize_t> (hthread_count);
02131 }

int ACE_Thread_Manager::hthread_within ( ACE_hthread_t  handle  ) 

Check if the thread is managed by the thread manager. Return true if the thread is found, false otherwise.

Definition at line 1190 of file Thread_Manager.cpp.

01191 {
01192   ACE_TRACE ("ACE_Thread_Manager::hthread_within");
01193   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01194 
01195   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01196        !iter.done ();
01197        iter.advance ())
01198     {
01199       if (ACE_OS::thr_cmp(iter.next ()->thr_handle_, handle))
01200         {
01201           return 1;
01202         }
01203     }
01204 
01205   return 0;
01206 }

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

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

Definition at line 862 of file Thread_Manager.cpp.

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

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

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

Definition at line 401 of file Thread_Manager.cpp.

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

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

Get pointer to a process-wide ACE_Thread_Manager.

Definition at line 378 of file Thread_Manager.cpp.

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

int ACE_Thread_Manager::join ( ACE_thread_t  tid,
ACE_THR_FUNC_RETURN *  status = 0 
)

Join a thread specified by tid. Do not wait on a detached thread.

Definition at line 1410 of file Thread_Manager.cpp.

01411 {
01412   ACE_TRACE ("ACE_Thread_Manager::join");
01413 
01414   bool found = false;
01415   ACE_Thread_Descriptor_Base tdb;
01416 
01417   {
01418     ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01419 
01420 #if !defined (ACE_HAS_VXTHREADS)
01421     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_);
01422          !biter.done ();
01423          biter.advance ())
01424       {
01425         if (ACE_OS::thr_equal (biter.next ()->thr_id_, tid))
01426           {
01427             ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (false);
01428             if (ACE_Thread::join (tdb->thr_handle_, status) == -1)
01429               {
01430                 return -1;
01431               }
01432             delete tdb;
01433 
01434             // return immediately if we've found the thread we want to join.
01435             return 0;
01436           }
01437       }
01438 #endif /* !ACE_HAS_VXTHREADS */
01439 
01440     for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01441          !iter.done ();
01442          iter.advance ())
01443       {
01444         // If threads are created as THR_DETACHED or THR_DAEMON, we
01445         // can't help much.
01446         if (ACE_OS::thr_equal (iter.next ()->thr_id_,tid) &&
01447             (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON)
01448              || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE)))
01449           {
01450             tdb = *iter.next ();
01451             ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
01452             found = 1;
01453             break;
01454           }
01455       }
01456 
01457     if (!found)
01458       return -1;
01459     // Didn't find the thread we want or the thread is not joinable.
01460   }
01461 
01462   if (ACE_Thread::join (tdb.thr_handle_, status) == -1)
01463     return -1;
01464 
01465   return 0;
01466 }

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

Join the thread described in td.

Definition at line 972 of file Thread_Manager.cpp.

00973 {
00974   ACE_TRACE ("ACE_Thread_Manager::join_thr");
00975   int const result = ACE_Thread::join (td->thr_handle_);
00976   if (result != 0)
00977     {
00978       // Since the thread are being joined, we should
00979       // let it remove itself from the list.
00980 
00981       //      this->remove_thr (td);
00982       errno = result;
00983       return -1;
00984     }
00985 
00986   return 0;
00987 }

int ACE_Thread_Manager::kill ( ACE_thread_t  t_id,
int  signum 
)

Send the signum to a single thread. Not supported on platforms that do not have advanced signal support, such as Win32.

Definition at line 1110 of file Thread_Manager.cpp.

01111 {
01112   ACE_TRACE ("ACE_Thread_Manager::kill");
01113   ACE_EXECUTE_OP (this->kill_thr, signum);
01114 }

int ACE_Thread_Manager::kill_all ( int  signum  ) 

Send signum to all stopped threads. Not supported on platforms that do not have advanced signal support, such as Win32.

Definition at line 1395 of file Thread_Manager.cpp.

01396 {
01397   ACE_TRACE ("ACE_Thread_Manager::kill_all");
01398   return this->apply_all (&ACE_Thread_Manager::kill_thr, sig);
01399 }

int ACE_Thread_Manager::kill_grp ( int  grp_id,
int  signum 
)

Send signum to a group of threads, not supported on platforms that do not have advanced signal support, such as Win32.

Definition at line 1324 of file Thread_Manager.cpp.

01325 {
01326   ACE_TRACE ("ACE_Thread_Manager::kill_grp");
01327   return this->apply_grp (grp_id,
01328                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr), signum);
01329 }

int ACE_Thread_Manager::kill_task ( ACE_Task_Base task,
int  signum 
)

Send a signal signum to all threads in an ACE_Task.

Definition at line 1828 of file Thread_Manager.cpp.

01829 {
01830   ACE_TRACE ("ACE_Thread_Manager::kill_task");
01831   return this->apply_task (task,
01832                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr));
01833 }

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

Send signal signum to the thread described in td.

Definition at line 1040 of file Thread_Manager.cpp.

01041 {
01042   ACE_TRACE ("ACE_Thread_Manager::kill_thr");
01043 
01044   ACE_thread_t tid = td->thr_id_;
01045 
01046   int const result = ACE_Thread::kill (tid, signum);
01047 
01048   if (result != 0)
01049     {
01050       // Only remove a thread from us when there is a "real" error.
01051       if (errno != ENOTSUP)
01052         this->thr_to_be_removed_.enqueue_tail (td);
01053 
01054       return -1;
01055     }
01056 
01057     return 0;
01058 }

int ACE_Thread_Manager::num_tasks_in_group ( int  grp_id  ) 

Returns the number of ACE_Task_Base in a group.

Definition at line 1876 of file Thread_Manager.cpp.

01877 {
01878   ACE_TRACE ("ACE_Thread_Manager::num_tasks_in_group");
01879   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01880 
01881   int tasks_count = 0;
01882   size_t i = 0;
01883 
01884   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01885        !iter.done ();
01886        iter.advance ())
01887     {
01888       if (iter.next ()->grp_id_ == grp_id
01889           && this->find_task (iter.next ()->task_, i) == 0
01890           && iter.next ()->task_ != 0)
01891         {
01892           ++tasks_count;
01893         }
01894 
01895       ++i;
01896     }
01897   return tasks_count;
01898 }

int ACE_Thread_Manager::num_threads_in_task ( ACE_Task_Base task  ) 

Returns the number of threads in an ACE_Task_Base.

Definition at line 1903 of file Thread_Manager.cpp.

01904 {
01905   ACE_TRACE ("ACE_Thread_Manager::num_threads_in_task");
01906   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01907 
01908   int threads_count = 0;
01909 
01910   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01911        !iter.done ();
01912        iter.advance ())
01913     {
01914       if (iter.next ()->task_ == task)
01915         {
01916           ++threads_count;
01917         }
01918     }
01919 
01920   return threads_count;
01921 }

int ACE_Thread_Manager::open ( size_t  size = 0  ) 

No-op. Currently unused.

Definition at line 236 of file Thread_Manager.inl.

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

int ACE_Thread_Manager::register_as_terminated ( ACE_Thread_Descriptor td  )  [protected]

Register a thread as terminated and put it into the <terminated_thr_list_>.

Definition at line 287 of file Thread_Manager.inl.

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

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

Remove thread from the table.

Definition at line 920 of file Thread_Manager.cpp.

00922 {
00923   ACE_TRACE ("ACE_Thread_Manager::remove_thr");
00924 
00925   td->tm_ = 0;
00926   this->thr_list_.remove (td);
00927 
00928 #if defined (ACE_WIN32)
00929   if (close_handler != 0)
00930     ::CloseHandle (td->thr_handle_);
00931 #else
00932   ACE_UNUSED_ARG (close_handler);
00933 #endif /* ACE_WIN32 */
00934 
00935   this->thread_desc_freelist_.add (td);
00936 
00937 #if defined (ACE_HAS_THREADS)
00938   // Tell all waiters when there are no more threads left in the pool.
00939   if (this->thr_list_.size () == 0)
00940     this->zero_cond_.broadcast ();
00941 #endif /* ACE_HAS_THREADS */
00942 }

void ACE_Thread_Manager::remove_thr_all ( void   )  [protected]

Remove all threads from the table.

Definition at line 947 of file Thread_Manager.cpp.

00948 {
00949   ACE_Thread_Descriptor *td = 0;
00950 
00951   while ((td = this->thr_list_.delete_head ()) != 0)
00952     {
00953       this->remove_thr (td, 1);
00954     }
00955 }

int ACE_Thread_Manager::resume ( ACE_thread_t  t_id  ) 

Resume a single thread.

Definition at line 1092 of file Thread_Manager.cpp.

01093 {
01094   ACE_TRACE ("ACE_Thread_Manager::resume");
01095   ACE_EXECUTE_OP (this->resume_thr, 0);
01096 }

int ACE_Thread_Manager::resume_all ( void   ) 

Resume all stopped threads.

Definition at line 1381 of file Thread_Manager.cpp.

01382 {
01383   ACE_TRACE ("ACE_Thread_Manager::resume_all");
01384   return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01385 }

int ACE_Thread_Manager::resume_grp ( int  grp_id  ) 

Resume a group of threads.

Definition at line 1314 of file Thread_Manager.cpp.

01315 {
01316   ACE_TRACE ("ACE_Thread_Manager::resume_grp");
01317   return this->apply_grp (grp_id,
01318                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01319 }

int ACE_Thread_Manager::resume_task ( ACE_Task_Base task  ) 

Resume all threads in an ACE_Task.

Definition at line 1818 of file Thread_Manager.cpp.

01819 {
01820   ACE_TRACE ("ACE_Thread_Manager::resume_task");
01821   return this->apply_task (task,
01822                            ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
01823 }

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

Resume the thread described in td.

Definition at line 1007 of file Thread_Manager.cpp.

01008 {
01009   ACE_TRACE ("ACE_Thread_Manager::resume_thr");
01010 
01011   int const result = ACE_Thread::resume (td->thr_handle_);
01012   if (result == -1) {
01013     if (errno != ENOTSUP)
01014       this->thr_to_be_removed_.enqueue_tail (td);
01015     return -1;
01016   }
01017   else {
01018     ACE_CLR_BITS (td->thr_state_, ACE_THR_SUSPENDED);
01019     return 0;
01020   }
01021 }

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

Run the registered hooks when the thread exits.

Definition at line 891 of file Thread_Manager.cpp.

00892 {
00893 #if 0 // currently unused!
00894   ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks");
00895 
00896   // @@ Currently, we have just one hook.  This should clearly be
00897   // generalized to support an arbitrary number of hooks.
00898 
00899   ACE_Thread_Descriptor *td = this->thread_desc_self ();
00900   for (ACE_Cleanup_Info_Node *iter = td->cleanup_info_->pop_front ();
00901        iter != 0;
00902        iter = cleanup_info_->pop_front ())
00903     {
00904       if (iter->cleanup_hook () != 0)
00905         {
00906           (*iter->cleanup_hook ()) (iter->object (), iter->param ());
00907         }
00908       delete iter;
00909     }
00910 
00911   ACE_UNUSED_ARG (i);
00912 #else
00913   ACE_UNUSED_ARG (i);
00914 #endif /* 0 */
00915 }

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

Set group ids for a particular task.

Definition at line 2194 of file Thread_Manager.cpp.

02195 {
02196   ACE_TRACE ("ACE_Thread_Manager::set_grp");
02197   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02198 
02199   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02200        !iter.done ();
02201        iter.advance ())
02202     {
02203       if (iter.next ()->task_ == task)
02204         {
02205           iter.next ()->grp_id_ = grp_id;
02206         }
02207     }
02208 
02209   return 0;
02210 }

int ACE_Thread_Manager::set_grp ( ACE_thread_t  t_id,
int  grp_id 
)

Set group ids for a particular thread id.

Definition at line 1247 of file Thread_Manager.cpp.

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

static int ACE_Thread_Manager::set_thr_exit ( ACE_TSS_TYPE(ACE_Thread_Exit)*  ptr  )  [static, protected]

Setting the static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_ pointer.

int ACE_Thread_Manager::spawn ( ACE_THR_FUNC  func,
void *  arg = 0,
long  flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED,
ACE_thread_t t_id = 0,
ACE_hthread_t t_handle = 0,
long  priority = ACE_DEFAULT_THREAD_PRIORITY,
int  grp_id = -1,
void *  stack = 0,
size_t  stack_size = ACE_DEFAULT_THREAD_STACKSIZE,
const char **  thr_name = 0 
)

Create a new thread, which executes func with argument arg.

Parameters:
func The function that is called in the spawned thread.
arg The value passed to each spawned thread's func.
flags Flags to control attributes of the spawned threads.
See also:
ACE_OS::thr_create() for descriptions of the possible flags values and their interactions.
Parameters:
t_id Pointer to a location to receive the spawned thread's ID. If 0, the ID is not returned.
t_handle Pointer to a location to receive the spawned thread's thread handle. If 0, the handle is not returned.
priority The priority at which the thread is spawned.
grp_id The thread group that the spawned thread is added to. If -1 is specified, a new thread group is created for the spawned thread.
stack Pointers to the base of a pre-allocated stack space for the thread's stack. If 0, the platform allocates stack space for the thread. If a stack is specified, it is recommended that stack_size also be supplied to specify the size of the stack. Not all platforms support pre-allocated stacks. If stack is specified for a platform which does not allow pre-allocated stack space this parameter is ignored.
stack_size Indicate how large the thread's stack should be, in bytes. If a pre-allocated stack pointer is passed in stack, stack_size indicates the size of that stack area. If no pre-allocated stack is passed, the stack size specified is passed to the operating system to request that it allocate a stack of the specified size.
thr_name Pointer to a name to assign to the spawned thread. This is only meaningful for platforms that have a capacity to name threads (e.g., VxWorks and some varieties of Pthreads). This argument is ignored if specified as 0 and on platforms that do not have the capability to name threads.
Return values:
-1 on failure; errno contains an error value.
The group id of the spawned thread.

Definition at line 659 of file Thread_Manager.cpp.

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

int ACE_Thread_Manager::spawn_i ( ACE_THR_FUNC  func,
void *  arg,
long  flags,
ACE_thread_t t_id = 0,
ACE_hthread_t t_handle = 0,
long  priority = ACE_DEFAULT_THREAD_PRIORITY,
int  grp_id = -1,
void *  stack = 0,
size_t  stack_size = 0,
ACE_Task_Base task = 0,
const char **  thr_name = 0 
) [protected]

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

Definition at line 543 of file Thread_Manager.cpp.

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

int ACE_Thread_Manager::spawn_n ( ACE_thread_t  thread_ids[],
size_t  n,
ACE_THR_FUNC  func,
void *  arg,
long  flags,
long  priority = ACE_DEFAULT_THREAD_PRIORITY,
int  grp_id = -1,
void *  stack[] = 0,
size_t  stack_size[] = 0,
ACE_hthread_t  thread_handles[] = 0,
ACE_Task_Base task = 0,
const char *  thr_name[] = 0 
)

Spawn a specified number of threads, all of which execute func with argument arg.

Parameters:
thread_ids An array to receive the thread IDs of successfully spawned buffer. If 0, the thread IDs are not returned. If specified, the array must be at least n entries.
n The number of threads to spawn.
func The function that is called in the spawned thread.
arg The value passed to each spawned thread's func.
flags Flags to control attributes of the spawned threads.
See also:
ACE_OS::thr_create() for descriptions of the possible flags values and their interactions.
Parameters:
priority The priority at which the threads are spawned.
grp_id The thread group that the spawned threads are added to. If -1 is specified, a new thread group is created for the spawned threads.
stack An array of n pointers to pre-allocated stack space for each thread's stack. If specified as 0, the platform allocates stack space for each thread. If a stack is specified, it is recommended that a stack_size element also be supplied that specifies the size of the stack. Not all platforms support pre-allocated stacks. If stack is specified for a platform which does not allow pre-allocated stack space this parameter is ignored.
stack_size An array of n values which indicate how large each thread's stack should be, in bytes. If pre-allocated stacks are passed in stacks, these sizes are for those stacks. If no pre-allocated stacks are passed, the stack sizes are specified to the operating system to request that it allocate stacks of the specified sizes. If an array entry is 0, the platform defaults are used for the corresponding thread. If a 0 array pointer is specified, platform defaults are used for all thread stack sizes.
thread_handles An array of n entries which will receive the thread handles of the spawned threads.
task The ACE_Task that the spawned threads are associated with. If 0, the threads are not associated with an ACE_Task. This argument is usually assigned by the ACE_Task_Base::activate() method to associate the spawned threads with the spawning ACE_Task object.
thr_name An array of names to assign to the spawned threads. This is only meaningful for platforms that have a capacity to name threads (e.g., VxWorks and some varieties of Pthreads). This argument is ignored if specified as 0 and on platforms that do not have the capability to name threads.

ACE_Thread_Manager can manipulate threads in groups based on grp_id or task using functions such as kill_grp() or cancel_task().

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

Definition at line 741 of file Thread_Manager.cpp.

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

int ACE_Thread_Manager::spawn_n ( size_t  n,
ACE_THR_FUNC  func,
void *  arg = 0,
long  flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED,
long  priority = ACE_DEFAULT_THREAD_PRIORITY,
int  grp_id = -1,
ACE_Task_Base task = 0,
ACE_hthread_t  thread_handles[] = 0,
void *  stack[] = 0,
size_t  stack_size[] = 0,
const char *  thr_name[] = 0 
)

Spawn a specified number of threads, all of which execute func with argument arg.

Parameters:
n The number of threads to spawn.
func The function that is called in the spawned thread.
arg The value passed to each spawned thread's func.
flags Flags to control attributes of the spawned threads.
See also:
ACE_OS::thr_create() for descriptions of the possible flags values and their interactions.
Parameters:
priority The priority at which the threads are spawned.
grp_id The thread group that the spawned threads are added to. If -1 is specified, a new thread group is created for the spawned threads.
task The ACE_Task that the spawned threads are associated with. If 0, the threads are not associated with an ACE_Task. This argument is usually assigned by the ACE_Task_Base::activate() method to associate the spawned threads with the spawning ACE_Task object.
thread_handles An array of n entries which will receive the thread handles of the spawned threads.
stack An array of n pointers to pre-allocated stack space for each thread's stack. If specified as 0, the platform allocates stack space for each thread. If a stack is specified, it is recommended that a stack_size element also be supplied that specifies the size of the stack. Not all platforms support pre-allocated stacks. If stack is specified for a platform which does not allow pre-allocated stack space this parameter is ignored.
stack_size An array of n values which indicate how large each thread's stack should be, in bytes. If pre-allocated stacks are passed in stacks, these sizes are for those stacks. If no pre-allocated stacks are passed, the stack sizes are specified to the operating system to request that it allocate stacks of the specified sizes. If an array entry is 0, the platform defaults are used for the corresponding thread. If a 0 array pointer is specified, platform defaults are used for all thread stack sizes.
thr_name An array of names to assign to the spawned threads. This is only meaningful for platforms that have a capacity to name threads (e.g., VxWorks and some varieties of Pthreads). This argument is ignored if specified as 0 and on platforms that do not have the capability to name threads.

ACE_Thread_Manager can manipulate threads in groups based on grp_id or task using functions such as kill_grp() or cancel_task().

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

Definition at line 699 of file Thread_Manager.cpp.

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

int ACE_Thread_Manager::suspend ( ACE_thread_t  t_id  ) 

Suspend a single thread.

Definition at line 1083 of file Thread_Manager.cpp.

01084 {
01085   ACE_TRACE ("ACE_Thread_Manager::suspend");
01086   ACE_EXECUTE_OP (this->suspend_thr, 0);
01087 }

int ACE_Thread_Manager::suspend_all ( void   ) 

Suspend all threads.

Definition at line 1388 of file Thread_Manager.cpp.

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

int ACE_Thread_Manager::suspend_grp ( int  grp_id  ) 

Suspend a group of threads.

Definition at line 1304 of file Thread_Manager.cpp.

01305 {
01306   ACE_TRACE ("ACE_Thread_Manager::suspend_grp");
01307   return this->apply_grp (grp_id,
01308                           ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
01309 }

int ACE_Thread_Manager::suspend_task ( ACE_Task_Base task  ) 

Suspend all threads in an ACE_Task.

Definition at line 1809 of file Thread_Manager.cpp.

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

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

Suspend the thread described in td.

Definition at line 990 of file Thread_Manager.cpp.

00991 {
00992   ACE_TRACE ("ACE_Thread_Manager::suspend_thr");
00993 
00994   int const result = ACE_Thread::suspend (td->thr_handle_);
00995   if (result == -1) {
00996     if (errno != ENOTSUP)
00997       this->thr_to_be_removed_.enqueue_tail (td);
00998     return -1;
00999   }
01000   else {
01001     ACE_SET_BITS (td->thr_state_, ACE_THR_SUSPENDED);
01002     return 0;
01003   }
01004 }

ACE_Task_Base * ACE_Thread_Manager::task ( void   ) 

Returns a pointer to the current ACE_Task_Base we're executing in if this thread is indeed running in an ACE_Task_Base, else return 0.

Definition at line 223 of file Thread_Manager.inl.

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

ssize_t ACE_Thread_Manager::task_all_list ( ACE_Task_Base task_list[],
size_t  n 
)

Returns a list of ACE_Task_Base pointers corresponding to the tasks that have active threads managed by this instance.

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

01928 {
01929   ACE_TRACE ("ACE_Thread_Manager::task_all_list");
01930   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01931 
01932   size_t task_list_count = 0;
01933 
01934   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01935        !iter.done ();
01936        iter.advance ())
01937     {
01938       if (task_list_count >= n)
01939         {
01940           break;
01941         }
01942 
01943       ACE_Task_Base *task_p = iter.next ()->task_;
01944 
01945       if (0 != task_p)
01946         {
01947           // This thread has a task pointer; see if it's already in the
01948           // list. Don't add duplicates.
01949           size_t i = 0;
01950 
01951           for (; i < task_list_count; ++i)
01952             {
01953               if (task_list[i] == task_p)
01954                 {
01955                   break;
01956                 }
01957             }
01958 
01959           if (i == task_list_count)        // No match - add this one
01960             {
01961               task_list[task_list_count++] = task_p;
01962             }
01963         }
01964     }
01965 
01966   return ACE_Utils::truncate_cast<ssize_t> (task_list_count);
01967 }

ssize_t ACE_Thread_Manager::task_list ( int  grp_id,
ACE_Task_Base task_list[],
size_t  n 
)

Returns a list of ACE_Task_Base pointers corresponding to the tasks that have active threads in a specified thread group.

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

02041 {
02042   ACE_TRACE ("ACE_Thread_Manager::task_list");
02043   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02044 
02045   ACE_Task_Base **task_list_iterator = task_list;
02046   size_t task_list_count = 0;
02047   size_t i = 0;
02048 
02049   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02050        !iter.done ();
02051        iter.advance ())
02052     {
02053       if (task_list_count >= n)
02054         {
02055           break;
02056         }
02057 
02058       if (iter.next ()->grp_id_ == grp_id
02059           && this->find_task (iter.next ()->task_, i) == 0)
02060         {
02061           task_list_iterator[task_list_count] = iter.next ()->task_;
02062           ++task_list_count;
02063         }
02064 
02065       ++i;
02066     }
02067 
02068   return ACE_Utils::truncate_cast<ssize_t> (task_list_count);
02069 }

int ACE_Thread_Manager::testcancel ( ACE_thread_t  t_id  ) 

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

Definition at line 1181 of file Thread_Manager.cpp.

01182 {
01183   ACE_TRACE ("ACE_Thread_Manager::testcancel");
01184   return this->check_state (ACE_THR_CANCELLED, t_id);
01185 }

int ACE_Thread_Manager::testresume ( ACE_thread_t  t_id  ) 

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

Definition at line 1172 of file Thread_Manager.cpp.

01173 {
01174   ACE_TRACE ("ACE_Thread_Manager::testresume");
01175   return this->check_state (ACE_THR_SUSPENDED, t_id, 0);
01176 }

int ACE_Thread_Manager::testsuspend ( ACE_thread_t  t_id  ) 

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

Definition at line 1163 of file Thread_Manager.cpp.

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

int ACE_Thread_Manager::testterminate ( ACE_thread_t  t_id  ) 

True if t_id has terminated (i.e., is no longer running), but the slot in the thread manager hasn't been reclaimed yet, else false. Always return false if t_id is not managed by the Thread_Manager.

Definition at line 1154 of file Thread_Manager.cpp.

01155 {
01156   ACE_TRACE ("ACE_Thread_Manager::testterminate");
01157   return this->check_state (ACE_THR_TERMINATED, t_id);
01158 }

ACE_thread_t ACE_Thread_Manager::thr_self ( void   ) 

Return the unique ID of the calling thread. Same as calling ACE_Thread::self().

Definition at line 216 of file Thread_Manager.inl.

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

int ACE_Thread_Manager::thr_self ( ACE_hthread_t self  ) 

Return the "real" handle to the calling thread, caching it if necessary in TSS to speed up subsequent lookups. This is necessary since on some platforms (e.g., Windows) we can't get this handle via direct method calls. Notice that you should *not* close the handle passed back from this method. It is used internally by Thread Manager. On the other hand, you *have to* use this internal thread handle when working on Thread_Manager. Return -1 if fail.

Definition at line 344 of file Thread_Manager.cpp.

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

int ACE_Thread_Manager::thr_state ( ACE_thread_t  id,
ACE_UINT32 &  state 
)

Get the state of the thread. Returns false if the thread is not managed by this thread manager.

Definition at line 1998 of file Thread_Manager.cpp.

02000 {
02001   ACE_TRACE ("ACE_Thread_Manager::thr_state");
02002   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02003 
02004   int const self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ());
02005 
02006   // If we're checking the state of our thread, try to get the cached
02007   // value out of TSS to avoid lookup.
02008   if (self_check)
02009     {
02010       ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc ();
02011 
02012       if (desc == 0)
02013         {
02014           return 0;               // Always return false.
02015         }
02016 
02017       state = desc->thr_state_;
02018     }
02019   else
02020     {
02021       // Not calling from self, have to look it up from the list.
02022       ACE_FIND (this->find_thread (id), ptr);
02023 
02024       if (ptr == 0)
02025         {
02026           return 0;
02027         }
02028 
02029       state = ptr->thr_state_;
02030     }
02031 
02032   return 1;
02033 }

ssize_t ACE_Thread_Manager::thread_all_list ( ACE_thread_t  thread_list[],
size_t  n 
)

Returns in thread_list a list of up to n thread ids. The caller must allocate the memory for thread_list. In case of an error, -1 is returned. If no requested values are found, 0 is returned, otherwise correct number of retrieved values are returned.

Definition at line 1972 of file Thread_Manager.cpp.

01974 {
01975   ACE_TRACE ("ACE_Thread_Manager::thread_all_list");
01976   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
01977 
01978   size_t thread_count = 0;
01979 
01980   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01981        !iter.done ();
01982        iter.advance ())
01983     {
01984       if (thread_count >= n)
01985         {
01986           break;
01987         }
01988 
01989       thread_list[thread_count] = iter.next ()->thr_id_;
01990       ++thread_count;
01991     }
01992 
01993   return ACE_Utils::truncate_cast<ssize_t> (thread_count);
01994 }

ACE_Thread_Descriptor * ACE_Thread_Manager::thread_desc_self ( void   )  [protected]

Get a pointer to the calling thread's own thread_descriptor. This must be called from a spawn thread. This function will fetch the info from TSS.

Definition at line 186 of file Thread_Manager.inl.

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

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

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

Definition at line 322 of file Thread_Manager.cpp.

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

ssize_t ACE_Thread_Manager::thread_grp_list ( int  grp_id,
ACE_thread_t  thread_list[],
size_t  n 
)

Returns in thread_list a list of up to n thread ids in a group grp_id. The caller must allocate the memory for thread_list. In case of an error, -1 is returned. If no requested values are found, 0 is returned, otherwise correct number of retrieved values are returned.

Definition at line 2134 of file Thread_Manager.cpp.

02137 {
02138   ACE_TRACE ("ACE_Thread_Manager::thread_grp_list");
02139   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02140 
02141   size_t thread_count = 0;
02142 
02143   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02144        !iter.done ();
02145        iter.advance ())
02146     {
02147       if (thread_count >= n)
02148         {
02149           break;
02150         }
02151 
02152       if (iter.next ()->grp_id_ == grp_id)
02153         {
02154           thread_list[thread_count] = iter.next ()->thr_id_;
02155           thread_count++;
02156         }
02157     }
02158 
02159   return ACE_Utils::truncate_cast<ssize_t> (thread_count);
02160 }

ssize_t ACE_Thread_Manager::thread_list ( ACE_Task_Base task,
ACE_thread_t  thread_list[],
size_t  n 
)

Returns in thread_list a list of up to n thread ids in an ACE_Task_Base. The caller must allocate the memory for thread_list. In case of an error, -1 is returned. If no requested values are found, 0 is returned, otherwise correct number of retrieved values are returned.

Definition at line 2074 of file Thread_Manager.cpp.

02077 {
02078   ACE_TRACE ("ACE_Thread_Manager::thread_list");
02079   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
02080 
02081   size_t thread_count = 0;
02082 
02083   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
02084        !iter.done ();
02085        iter.advance ())
02086     {
02087       if (thread_count >= n)
02088         {
02089           break;
02090         }
02091 
02092       if (iter.next ()->task_ == task)
02093         {
02094           thread_list[thread_count] = iter.next ()->thr_id_;
02095           ++thread_count;
02096         }
02097     }
02098 
02099   return ACE_Utils::truncate_cast<ssize_t> (thread_count);
02100 }

int ACE_Thread_Manager::thread_within ( ACE_thread_t  tid  ) 

Definition at line 1209 of file Thread_Manager.cpp.

01210 {
01211   ACE_TRACE ("ACE_Thread_Manager::thread_within");
01212   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
01213 
01214   for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
01215        !iter.done ();
01216        iter.advance ())
01217     {
01218       if (ACE_OS::thr_equal (iter.next ()->thr_id_, tid))
01219         {
01220           return 1;
01221         }
01222     }
01223 
01224   return 0;
01225 }

int ACE_Thread_Manager::wait ( const ACE_Time_Value timeout = 0,
bool  abandon_detached_threads = false,
bool  use_absolute_time = true 
)

Block until there are no more threads running in this thread manager or timeout expires.

Parameters:
timeout is treated as "absolute" time by default, but this can be changed to "relative" time by setting the use_absolute_time to false.
abandon_detached_threads If true, wait() will first check thru its thread list for threads with THR_DETACHED or THR_DAEMON flags set and remove these threads. Notice that unlike other wait_*() methods, by default, wait() does wait on all thread spawned by this thread manager no matter the detached flags are set or not unless it is called with abandon_detached_threads flag set.
use_absolute_time If true then treat timeout as absolute time, else relative time.
Returns:
0 on success * and -1 on failure.
Note:
If this function is called while the ACE_Object_Manager is shutting down (as a result of program rundown via ACE::fini()), it will not wait for any threads to complete. If you must wait for threads spawned by this thread manager to complete and you are in a ACE rundown situation (such as your object is being destroyed by the ACE_Object_Manager) you can use wait_grp() instead.

Definition at line 1601 of file Thread_Manager.cpp.

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

int ACE_Thread_Manager::wait_grp ( int  grp_id  ) 

Block until there are no more threads running in a group. Returns 0 on success and -1 on failure. Notice that wait_grp will not wait on detached threads.

Definition at line 1471 of file Thread_Manager.cpp.

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

int ACE_Thread_Manager::wait_on_exit ( void   ) 

Definition at line 281 of file Thread_Manager.inl.

00282 {
00283   return this->automatic_wait_;
00284 }

void ACE_Thread_Manager::wait_on_exit ( int  dowait  ) 

Access function to determine whether the Thread_Manager will wait for its thread to exit or not when being closing down.

Definition at line 275 of file Thread_Manager.inl.

00276 {
00277   this->automatic_wait_ = do_wait;
00278 }

int ACE_Thread_Manager::wait_task ( ACE_Task_Base task  ) 

Block until there are no more threads running in a specified task. This method will not wait for either detached or daemon threads; the threads must have been spawned with the THR_JOINABLE flag. Upon successful completion, the threads have been joined, so further attempts to join with any of the waited-for threads will fail.

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

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


Friends And Related Function Documentation

friend class ACE_Thread_Control [friend]

Definition at line 386 of file Thread_Manager.h.

friend class ACE_Thread_Descriptor [friend]

Definition at line 390 of file Thread_Manager.h.

friend class ACE_Thread_Exit [friend]

Definition at line 389 of file Thread_Manager.h.


Member Data Documentation

Declare the dynamic allocation hooks.

Definition at line 1082 of file Thread_Manager.h.

Set if we want the Thread_Manager to wait on all threads before being closed, reset otherwise.

Definition at line 1228 of file Thread_Manager.h.

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

Must delete the thr_mgr_ if true.

Definition at line 1247 of file Thread_Manager.h.

int ACE_Thread_Manager::grp_id_ [protected]

Keeps track of the next group id to assign.

Definition at line 1224 of file Thread_Manager.h.

Collect terminated but not yet joined thread entries.

Definition at line 1217 of file Thread_Manager.h.

Keeping a list of thread descriptors within the thread manager. Double-linked list enables us to cache the entries in TSS and adding/removing thread descriptor entries without affecting other thread's descriptor entries.

Definition at line 1213 of file Thread_Manager.h.

Pointer to a process-wide ACE_Thread_Manager.

Definition at line 1244 of file Thread_Manager.h.

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

Definition at line 1221 of file Thread_Manager.h.

Definition at line 1239 of file Thread_Manager.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Sun Nov 22 23:16:51 2009 for ACE by  doxygen 1.6.1