3 //=============================================================================
5 * @file Thread_Manager.h
7 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
9 //=============================================================================
11 #ifndef ACE_THREAD_MANAGER_H
12 #define ACE_THREAD_MANAGER_H
13 #include /**/ "ace/pre.h"
15 #include "ace/Thread.h"
16 #include "ace/Thread_Adapter.h"
17 #include "ace/Thread_Exit.h"
19 #if !defined (ACE_LACKS_PRAGMA_ONCE)
21 #endif /* ACE_LACKS_PRAGMA_ONCE */
23 #include "ace/Condition_Thread_Mutex.h"
24 #include "ace/Unbounded_Queue.h"
25 #include "ace/Containers.h"
26 #include "ace/Free_List.h"
27 #include "ace/Singleton.h"
28 #include "ace/Log_Category.h"
29 #include "ace/Synch_Traits.h"
30 #include "ace/Basic_Types.h"
32 // The following macros control how a Thread Manager manages a pool of
33 // Thread_Descriptor. Currently, the default behavior is not to
34 // preallocate any thread descriptor and never (well, almost never)
35 // free up any thread descriptor until the Thread Manager gets
36 // destructed. Which means, once your system is stable, you rarely
37 // need to pay the price of memory allocation. On a deterministic
38 // system, which means, the number of threads spawned can be
39 // determined before hand, you can either redefine the memory pool
40 // size macros to suit your need or constructed the Thread_Manager
41 // accordingly. That way, you don't pay the price of memory
42 // allocation when the system is really doing its job. OTOH, on
43 // system with resources constraint, you may want to lower the size of
44 // ACE_DEFAULT_THREAD_MANAGER_HWM to avoid unused memory hanging
47 #if !defined (ACE_DEFAULT_THREAD_MANAGER_PREALLOC)
48 # define ACE_DEFAULT_THREAD_MANAGER_PREALLOC 0
49 #endif /* ACE_DEFAULT_THREAD_MANAGER_PREALLOC */
51 #if !defined (ACE_DEFAULT_THREAD_MANAGER_LWM)
52 # define ACE_DEFAULT_THREAD_MANAGER_LWM 1
53 #endif /* ACE_DEFAULT_THREAD_MANAGER_LWM */
55 #if !defined (ACE_DEFAULT_THREAD_MANAGER_INC)
56 # define ACE_DEFAULT_THREAD_MANAGER_INC 1
57 #endif /* ACE_DEFAULT_THREAD_MANAGER_INC */
59 #if !defined (ACE_DEFAULT_THREAD_MANAGER_HWM)
60 # define ACE_DEFAULT_THREAD_MANAGER_HWM ACE_DEFAULT_FREE_LIST_HWM
61 // this is a big number
62 #endif /* ACE_DEFAULT_THREAD_MANAGER_HWM */
64 // This is the synchronization mechanism used to prevent a thread
65 // descriptor gets removed from the Thread_Manager before it gets
66 // stash into it. If you want to disable this feature (and risk of
67 // corrupting the freelist,) you define the lock as ACE_Null_Mutex.
68 // Usually, if you can be sure that your threads will run for an
69 // extended period of time, you can safely disable the lock.
71 #if !defined (ACE_DEFAULT_THREAD_MANAGER_LOCK)
72 # define ACE_DEFAULT_THREAD_MANAGER_LOCK ACE_SYNCH_MUTEX
73 #endif /* ACE_DEFAULT_THREAD_MANAGER_LOCK */
75 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
77 // Forward declarations.
79 class ACE_Thread_Manager
;
80 class ACE_Thread_Descriptor
;
83 * @class ACE_At_Thread_Exit
85 * @brief Contains a method to be applied when a thread is terminated.
87 class ACE_Export ACE_At_Thread_Exit
89 friend class ACE_Thread_Descriptor
;
90 friend class ACE_Thread_Manager
;
92 /// Default constructor
93 ACE_At_Thread_Exit (void);
96 virtual ~ACE_At_Thread_Exit (void);
98 /// At_Thread_Exit has the ownership?
99 bool is_owner (void) const;
101 /// Set the ownership of the At_Thread_Exit.
102 bool is_owner (bool owner
);
104 /// This At_Thread_Exit was applied?
105 bool was_applied (void) const;
107 /// Set applied state of At_Thread_Exit.
108 bool was_applied (bool applied
);
111 /// The next At_Thread_Exit hook in the list.
112 ACE_At_Thread_Exit
*next_
;
114 /// Do the apply if necessary
115 void do_apply (void);
117 /// The apply method.
118 virtual void apply (void) = 0;
120 /// The Thread_Descriptor where this at is registered.
121 ACE_Thread_Descriptor
* td_
;
123 /// The at was applied?
126 /// The at has the ownership of this?
130 class ACE_Export ACE_At_Thread_Exit_Func
: public ACE_At_Thread_Exit
134 ACE_At_Thread_Exit_Func (void *object
,
135 ACE_CLEANUP_FUNC func
,
138 virtual ~ACE_At_Thread_Exit_Func (void);
140 ACE_ALLOC_HOOK_DECLARE
;
143 /// The object to be cleanup
147 ACE_CLEANUP_FUNC func_
;
149 /// A param if required
157 * @class ACE_Thread_Descriptor_Base
159 * @brief Basic information for thread descriptors. These information
160 * gets extracted out because we need it after a thread is
165 class ACE_Export ACE_Thread_Descriptor_Base
: public ACE_OS_Thread_Descriptor
168 friend class ACE_Thread_Manager
;
169 friend class ACE_Double_Linked_List
<ACE_Thread_Descriptor_Base
>;
170 friend class ACE_Double_Linked_List_Iterator_Base
<ACE_Thread_Descriptor_Base
>;
171 friend class ACE_Double_Linked_List_Iterator
<ACE_Thread_Descriptor_Base
>;
172 friend class ACE_Double_Linked_List
<ACE_Thread_Descriptor
>;
173 friend class ACE_Double_Linked_List_Iterator_Base
<ACE_Thread_Descriptor
>;
174 friend class ACE_Double_Linked_List_Iterator
<ACE_Thread_Descriptor
>;
176 ACE_Thread_Descriptor_Base (void);
177 virtual ~ACE_Thread_Descriptor_Base (void);
179 // = We need the following operators to make Borland happy.
181 /// Equality operator.
182 bool operator== (const ACE_Thread_Descriptor_Base
&rhs
) const;
184 /// Inequality operator.
185 bool operator!= (const ACE_Thread_Descriptor_Base
&rhs
) const;
188 int grp_id (void) const;
190 /// Current state of the thread.
191 ACE_UINT32
state (void) const;
193 /// Return the pointer to an ACE_Task_Base or NULL if there's no
194 /// ACE_Task_Base associated with this thread.;
195 ACE_Task_Base
*task (void) const;
197 ACE_ALLOC_HOOK_DECLARE
;
200 /// Reset this base thread descriptor.
203 /// Unique thread ID.
204 ACE_thread_t thr_id_
;
206 /// Unique handle to thread (used by Win32 and AIX).
207 ACE_hthread_t thr_handle_
;
212 /// Current state of the thread.
213 ACE_UINT32 thr_state_
;
215 /// Pointer to an ACE_Task_Base or NULL if there's no
217 ACE_Task_Base
*task_
;
219 /// We need these pointers to maintain the double-linked list in a
221 ACE_Thread_Descriptor_Base
*next_
;
222 ACE_Thread_Descriptor_Base
*prev_
;
226 * @class ACE_Thread_Descriptor
228 * @brief Information for controlling threads that run under the control
229 * of the Thread_Manager.
231 class ACE_Export ACE_Thread_Descriptor
: public ACE_Thread_Descriptor_Base
233 friend class ACE_At_Thread_Exit
;
234 friend class ACE_Thread_Manager
;
235 friend class ACE_Double_Linked_List
<ACE_Thread_Descriptor
>;
236 friend class ACE_Double_Linked_List_Iterator
<ACE_Thread_Descriptor
>;
238 ACE_Thread_Descriptor (void);
240 // = Accessor methods.
241 /// Unique thread id.
242 ACE_thread_t
self (void) const;
244 /// Unique handle to thread (used by Win32 and AIX).
245 void self (ACE_hthread_t
&);
247 /// Dump the state of an object.
248 void dump (void) const;
251 * This cleanup function must be called only for ACE_TSS_cleanup.
252 * The ACE_TSS_cleanup delegate Log_Msg instance destruction when
253 * Log_Msg cleanup is called before terminate.
255 void log_msg_cleanup(ACE_Log_Msg
* log_msg
);
258 * Register an At_Thread_Exit hook and the ownership is acquire by
259 * Thread_Descriptor, this is the usual case when the AT is dynamically
262 int at_exit (ACE_At_Thread_Exit
* cleanup
);
264 /// Register an At_Thread_Exit hook and the ownership is retained for the
265 /// caller. Normally used when the at_exit hook is created in stack.
266 int at_exit (ACE_At_Thread_Exit
& cleanup
);
269 * Register an object (or array) for cleanup at thread termination.
270 * "cleanup_hook" points to a (global, or static member) function
271 * that is called for the object or array when it to be destroyed.
272 * It may perform any necessary cleanup specific for that object or
273 * its class. "param" is passed as the second parameter to the
274 * "cleanup_hook" function; the first parameter is the object (or
275 * array) to be destroyed. Returns 0 on success, non-zero on
276 * failure: -1 if virtual memory is exhausted or 1 if the object (or
277 * array) had already been registered.
279 int at_exit (void *object
,
280 ACE_CLEANUP_FUNC cleanup_hook
,
283 /// Do nothing destructor to keep some compilers happy
284 ~ACE_Thread_Descriptor (void);
287 * Do nothing but to acquire the thread descriptor's lock and
288 * release. This will first check if the thread is registered or
289 * not. If it is already registered, there's no need to reacquire
290 * the lock again. This is used mainly to get newly spawned thread
291 * in synch with thread manager and prevent it from accessing its
292 * thread descriptor before it gets fully built. This function is
293 * only called from ACE_Log_Msg::thr_desc.
295 void acquire_release (void);
300 * Set/get the @c next_ pointer. These are required by the
303 void set_next (ACE_Thread_Descriptor
*td
);
304 ACE_Thread_Descriptor
*get_next (void) const;
307 /// Run the AT_Thread_Exit hooks.
308 void do_at_exit (void);
310 /// Terminate realize the cleanup process to thread termination
311 void terminate (void);
314 /// Reset this thread descriptor.
315 void reset (ACE_Thread_Manager
*tm
);
317 /// Pop an At_Thread_Exit from at thread termination list, apply the at
318 /// if apply is true.
319 void at_pop (int apply
= 1);
321 /// Push an At_Thread_Exit to at thread termination list and set the
323 void at_push (ACE_At_Thread_Exit
* cleanup
,
324 bool is_owner
= false);
327 /// Thread_Descriptor is the ownership of ACE_Log_Msg if log_msg_!=0
328 /// This can occur because ACE_TSS_cleanup was executed before terminate.
329 ACE_Log_Msg
*log_msg_
;
331 /// The AT_Thread_Exit list
332 ACE_At_Thread_Exit
*at_exit_list_
;
335 /// Currently not used
337 * Stores the cleanup info for a thread.
338 * @note This should be generalized to be a stack of ACE_Cleanup_Info's.
340 ACE_Cleanup_Info_Node_List cleanup_info_
;
343 /// Pointer to an ACE_Thread_Manager or NULL if there's no
344 /// ACE_Thread_Manager
345 ACE_Thread_Manager
* tm_
;
347 /// Registration lock to prevent premature removal of thread descriptor.
348 ACE_DEFAULT_THREAD_MANAGER_LOCK
*sync_
;
350 /// Keep track of termination status.
354 // Forward declaration.
355 class ACE_Thread_Control
;
357 // This typedef should be (and used to be) inside the
358 // ACE_Thread_Manager declaration. But, it caused compilation
359 // problems on g++/VxWorks/i960 with -g. Note that
360 // ACE_Thread_Manager::THR_FUNC is only used internally in
361 // ACE_Thread_Manager, so it's not useful for anyone else.
362 // It also caused problems on IRIX5 with g++.
363 #if defined (__GNUG__)
364 typedef int (ACE_Thread_Manager::*ACE_THR_MEMBER_FUNC
)(ACE_Thread_Descriptor
*, int);
365 #endif /* __GNUG__ */
368 * @class ACE_Thread_Manager
370 * @brief Manages a pool of threads.
372 * This class allows operations on groups of threads atomically.
373 * The default behavior of thread manager is to wait on
374 * all threads under it's management when it gets destructed.
375 * Therefore, remember to remove a thread from thread manager if
376 * you don't want it to wait for the thread. There are also
377 * functions to disable this default wait-on-exit behavior.
378 * However, if your program depends on turning this off to run
379 * correctly, you are probably doing something wrong. Rule of
380 * thumb, use ACE_Thread to manage your daemon threads.
381 * Notice that if there're threads which live beyond the scope of
382 * main(), you are sure to have resource leaks in your program.
383 * Remember to wait on threads before exiting your main program if that
384 * could happen in your programs.
386 class ACE_Export ACE_Thread_Manager
389 friend class ACE_Thread_Control
;
391 // Allow ACE_Thread_Exit to register the global TSS instance object.
392 friend class ACE_Thread_Exit
;
393 friend class ACE_Thread_Descriptor
;
395 #if !defined (__GNUG__)
396 typedef int (ACE_Thread_Manager::*ACE_THR_MEMBER_FUNC
)(ACE_Thread_Descriptor
*, int);
397 #endif /* !__GNUG__ */
399 /// These are the various states a thread managed by the
400 /// ACE_Thread_Manager can be in.
404 ACE_THR_IDLE
= 0x00000000,
406 /// Created but not yet running.
407 ACE_THR_SPAWNED
= 0x00000001,
409 /// Thread is active (naturally, we don't know if it's actually
410 /// *running* because we aren't the scheduler...).
411 ACE_THR_RUNNING
= 0x00000002,
413 /// Thread is suspended.
414 ACE_THR_SUSPENDED
= 0x00000004,
416 /// Thread has been cancelled (which is an indiction that it needs to
418 ACE_THR_CANCELLED
= 0x00000008,
420 /// Thread has shutdown, but the slot in the thread manager hasn't
421 /// been reclaimed yet.
422 ACE_THR_TERMINATED
= 0x00000010,
424 /// Join operation has been invoked on the thread by thread manager.
425 ACE_THR_JOINING
= 0x10000000
429 * @brief Initialization and termination methods.
431 * Internally, ACE_Thread_Manager keeps a freelist for caching
432 * resources it uses to keep track of managed threads (not the
433 * threads themselves.) @a prealloc, @a lwm, @a inc, @hwm
434 * determine the initial size, the low water mark, increment step,
435 * and high water mark of the freelist.
439 ACE_Thread_Manager (size_t preaolloc
= ACE_DEFAULT_THREAD_MANAGER_PREALLOC
,
440 size_t lwm
= ACE_DEFAULT_THREAD_MANAGER_LWM
,
441 size_t inc
= ACE_DEFAULT_THREAD_MANAGER_INC
,
442 size_t hwm
= ACE_DEFAULT_THREAD_MANAGER_HWM
);
443 ACE_Thread_Manager (const ACE_Condition_Attributes
&attributes
,
444 size_t preaolloc
= ACE_DEFAULT_THREAD_MANAGER_PREALLOC
,
445 size_t lwm
= ACE_DEFAULT_THREAD_MANAGER_LWM
,
446 size_t inc
= ACE_DEFAULT_THREAD_MANAGER_INC
,
447 size_t hwm
= ACE_DEFAULT_THREAD_MANAGER_HWM
);
448 ~ACE_Thread_Manager (void);
450 #if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
451 /// Get pointer to a process-wide ACE_Thread_Manager.
452 static ACE_Thread_Manager
*instance (void);
454 /// Set pointer to a process-wide ACE_Thread_Manager and return
455 /// existing pointer.
456 static ACE_Thread_Manager
*instance (ACE_Thread_Manager
*);
458 /// Delete the dynamically allocated Singleton
459 static void close_singleton (void);
460 #endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */
462 /// No-op. Currently unused.
463 int open (size_t size
= 0);
466 * Release all resources.
467 * By default, this method will wait until all threads exit.
468 * However, when called from close_singleton(), most global resources
469 * are destroyed and thus, close() does not try to wait; it simply cleans
470 * up internal thread records (the thread descriptor list).
475 * Create a new thread, which executes @a func with argument @a arg.
477 * @param func The function that is called in the spawned thread.
479 * @param arg The value passed to each spawned thread's @a func.
481 * @param flags Flags to control attributes of the spawned threads.
482 * @sa ACE_OS::thr_create() for descriptions of the
483 * possible flags values and their interactions.
485 * @param t_id Pointer to a location to receive the spawned thread's
486 * ID. If 0, the ID is not returned.
488 * @param t_handle Pointer to a location to receive the spawned thread's
489 * thread handle. If 0, the handle is not returned.
491 * @param priority The priority at which the thread is spawned.
493 * @param grp_id The thread group that the spawned thread is
494 * added to. If -1 is specified, a new thread group is
495 * created for the spawned thread.
497 * @param stack Pointers to the base of a pre-allocated stack space
498 * for the thread's stack. If 0, the platform allocates
499 * stack space for the thread. If a stack is specified,
500 * it is recommended that @a stack_size also be supplied
501 * to specify the size of the stack.
502 * Not all platforms support pre-allocated stacks. If
503 * @a stack is specified for a platform which does not
504 * allow pre-allocated stack space this parameter is
507 * @param stack_size Indicate how large the thread's stack should be, in
508 * bytes. If a pre-allocated stack pointer is passed in
509 * @a stack, @a stack_size indicates the size of that
510 * stack area. If no pre-allocated stack is passed,
511 * the stack size specified is passed to the
512 * operating system to request that it allocate a stack
513 * of the specified size.
515 * @param thr_name Pointer to a name to assign to the spawned thread.
516 * This is only meaningful for platforms that have a
517 * capacity to name threads (e.g., VxWorks and some
518 * varieties of Pthreads). This argument is ignored if
519 * specified as 0 and on platforms that do not have the
520 * capability to name threads.
522 * @retval -1 on failure; @c errno contains an error value.
523 * @retval The group id of the spawned thread.
525 int spawn (ACE_THR_FUNC func
,
527 long flags
= THR_NEW_LWP
| THR_JOINABLE
| THR_INHERIT_SCHED
,
528 ACE_thread_t
*t_id
= 0,
529 ACE_hthread_t
*t_handle
= 0,
530 long priority
= ACE_DEFAULT_THREAD_PRIORITY
,
533 size_t stack_size
= ACE_DEFAULT_THREAD_STACKSIZE
,
534 const char** thr_name
= 0);
537 * Spawn a specified number of threads, all of which execute @a func
538 * with argument @a arg.
540 * @param n The number of threads to spawn.
542 * @param func The function that is called in the spawned thread.
544 * @param arg The value passed to each spawned thread's @a func.
546 * @param flags Flags to control attributes of the spawned threads.
547 * @sa ACE_OS::thr_create() for descriptions of the
548 * possible flags values and their interactions.
550 * @param priority The priority at which the threads are spawned.
552 * @param grp_id The thread group that the spawned threads are
553 * added to. If -1 is specified, a new thread group is
554 * created for the spawned threads.
556 * @param task The ACE_Task that the spawned threads are associated
557 * with. If 0, the threads are not associated with an
558 * ACE_Task. This argument is usually assigned by the
559 * ACE_Task_Base::activate() method to associate the
560 * spawned threads with the spawning ACE_Task object.
562 * @param thread_handles An array of @a n entries which will receive
563 * the thread handles of the spawned threads.
565 * @param stack An array of @a n pointers to pre-allocated stack space
566 * for each thread's stack. If specified as 0, the
567 * platform allocates stack space for each thread. If
568 * a stack is specified, it is recommended that a
569 * @a stack_size element also be supplied that specifies
570 * the size of the stack.
571 * Not all platforms support pre-allocated stacks. If
572 * @a stack is specified for a platform which does not
573 * allow pre-allocated stack space this parameter is
576 * @param stack_size An array of @a n values which indicate how large
577 * each thread's stack should be, in bytes.
578 * If pre-allocated stacks are passed in @a stacks, these
579 * sizes are for those stacks. If no pre-allocated stacks
580 * are passed, the stack sizes are specified to the
581 * operating system to request that it allocate stacks
582 * of the specified sizes. If an array entry is 0, the
583 * platform defaults are used for the corresponding thread.
584 * If a 0 array pointer is specified, platform defaults
585 * are used for all thread stack sizes.
587 * @param thr_name An array of names to assign to the spawned threads.
588 * This is only meaningful for platforms that have a
589 * capacity to name threads (e.g., VxWorks and some
590 * varieties of Pthreads). This argument is ignored if
591 * specified as 0 and on platforms that do not have the
592 * capability to name threads.
594 * ACE_Thread_Manager can manipulate threads in groups based on
595 * @a grp_id or @a task using functions such as kill_grp() or
598 * @retval -1 on failure; @c errno contains an error value.
599 * @retval The group id of the threads.
601 int spawn_n (size_t n
,
604 long flags
= THR_NEW_LWP
| THR_JOINABLE
| THR_INHERIT_SCHED
,
605 long priority
= ACE_DEFAULT_THREAD_PRIORITY
,
607 ACE_Task_Base
*task
= 0,
608 ACE_hthread_t thread_handles
[] = 0,
610 size_t stack_size
[] = 0,
611 const char* thr_name
[] = 0);
614 * Spawn a specified number of threads, all of which execute @a func
615 * with argument @a arg.
617 * @param thread_ids An array to receive the thread IDs of successfully
618 * spawned buffer. If 0, the thread IDs are not returned.
619 * If specified, the array must be at least @a n entries.
621 * @param n The number of threads to spawn.
623 * @param func The function that is called in the spawned thread.
625 * @param arg The value passed to each spawned thread's @a func.
627 * @param flags Flags to control attributes of the spawned threads.
628 * @sa ACE_OS::thr_create() for descriptions of the
629 * possible flags values and their interactions.
631 * @param priority The priority at which the threads are spawned.
633 * @param grp_id The thread group that the spawned threads are
634 * added to. If -1 is specified, a new thread group is
635 * created for the spawned threads.
637 * @param stack An array of @a n pointers to pre-allocated stack space
638 * for each thread's stack. If specified as 0, the
639 * platform allocates stack space for each thread. If
640 * a stack is specified, it is recommended that a
641 * @a stack_size element also be supplied that specifies
642 * the size of the stack.
643 * Not all platforms support pre-allocated stacks. If
644 * @a stack is specified for a platform which does not
645 * allow pre-allocated stack space this parameter is
648 * @param stack_size An array of @a n values which indicate how large
649 * each thread's stack should be, in bytes.
650 * If pre-allocated stacks are passed in @a stacks, these
651 * sizes are for those stacks. If no pre-allocated stacks
652 * are passed, the stack sizes are specified to the
653 * operating system to request that it allocate stacks
654 * of the specified sizes. If an array entry is 0, the
655 * platform defaults are used for the corresponding thread.
656 * If a 0 array pointer is specified, platform defaults
657 * are used for all thread stack sizes.
659 * @param thread_handles An array of @a n entries which will receive
660 * the thread handles of the spawned threads.
662 * @param task The ACE_Task that the spawned threads are associated
663 * with. If 0, the threads are not associated with an
664 * ACE_Task. This argument is usually assigned by the
665 * ACE_Task_Base::activate() method to associate the
666 * spawned threads with the spawning ACE_Task object.
668 * @param thr_name An array of names to assign to the spawned threads.
669 * This is only meaningful for platforms that have a
670 * capacity to name threads (e.g., VxWorks and some
671 * varieties of Pthreads). This argument is ignored if
672 * specified as 0 and on platforms that do not have the
673 * capability to name threads.
675 * ACE_Thread_Manager can manipulate threads in groups based on
676 * @a grp_id or @a task using functions such as kill_grp() or
679 * @retval -1 on failure; @c errno contains an error value.
680 * @retval The group id of the threads.
683 int spawn_n (ACE_thread_t thread_ids
[],
688 long priority
= ACE_DEFAULT_THREAD_PRIORITY
,
691 size_t stack_size
[] = 0,
692 ACE_hthread_t thread_handles
[] = 0,
693 ACE_Task_Base
*task
= 0,
694 const char* thr_name
[] = 0);
697 * Called to clean up when a thread exits.
699 * @param do_thread_exit If non-0 then ACE_Thread::exit is called to
701 * @param status If ACE_Thread_Exit is called, this is passed as
702 * the exit value of the thread.
703 * Should _not_ be called by main thread.
705 ACE_THR_FUNC_RETURN
exit (ACE_THR_FUNC_RETURN status
= 0,
706 bool do_thread_exit
= true);
709 * Block until there are no more threads running in this thread
710 * manager or @c timeout expires.
712 * @param timeout is treated as "absolute" time by default, but this
713 * can be changed to "relative" time by setting the @c
714 * use_absolute_time to false.
715 * @param abandon_detached_threads If true, @c wait() will first
716 * check thru its thread list for
717 * threads with THR_DETACHED or
718 * THR_DAEMON flags set and remove
719 * these threads. Notice that
720 * unlike other @c wait_*() methods,
721 * by default, @c wait() does wait on
722 * all thread spawned by this
723 * thread manager no matter the detached
724 * flags are set or not unless it is
726 * abandon_detached_threads flag set.
727 * @param use_absolute_time If true then treat @c timeout as
728 * absolute time, else relative time.
729 * @return 0 on success * and -1 on failure.
731 * @note If this function is called while the @c
732 * ACE_Object_Manager is shutting down (as a result of program
733 * rundown via @c ACE::fini()), it will not wait for any threads to
734 * complete. If you must wait for threads spawned by this thread
735 * manager to complete and you are in a ACE rundown situation (such
736 * as your object is being destroyed by the @c ACE_Object_Manager)
737 * you can use @c wait_grp() instead.
739 int wait (const ACE_Time_Value
*timeout
= 0,
740 bool abandon_detached_threads
= false,
741 bool use_absolute_time
= true);
743 /// Join a thread specified by @a tid. Do not wait on a detached thread.
744 int join (ACE_thread_t tid
, ACE_THR_FUNC_RETURN
*status
= 0);
747 * Block until there are no more threads running in a group.
748 * Returns 0 on success and -1 on failure. Notice that wait_grp
749 * will not wait on detached threads.
751 int wait_grp (int grp_id
);
754 * Return the "real" handle to the calling thread, caching it if
755 * necessary in TSS to speed up subsequent lookups. This is
756 * necessary since on some platforms (e.g., Windows) we can't get this
757 * handle via direct method calls. Notice that you should *not*
758 * close the handle passed back from this method. It is used
759 * internally by Thread Manager. On the other hand, you *have to*
760 * use this internal thread handle when working on Thread_Manager.
763 int thr_self (ACE_hthread_t
&);
766 * Return the unique ID of the calling thread.
767 * Same as calling ACE_Thread::self().
769 ACE_thread_t
thr_self (void);
772 * Returns a pointer to the current ACE_Task_Base we're executing
773 * in if this thread is indeed running in an ACE_Task_Base, else
776 ACE_Task_Base
*task (void);
779 * @name Suspend and resume methods
781 * Suspend/resume is not supported on all platforms. For example, Pthreads
782 * does not support these functions.
786 /// Suspend all threads
787 int suspend_all (void);
789 /// Suspend a single thread.
790 int suspend (ACE_thread_t
);
792 /// Suspend a group of threads.
793 int suspend_grp (int grp_id
);
796 * True if @a t_id is inactive (i.e., suspended), else false. Always
797 * return false if @a t_id is not managed by the Thread_Manager.
799 int testsuspend (ACE_thread_t t_id
);
801 /// Resume all stopped threads
802 int resume_all (void);
804 /// Resume a single thread.
805 int resume (ACE_thread_t
);
807 /// Resume a group of threads.
808 int resume_grp (int grp_id
);
811 * True if @a t_id is active (i.e., resumed), else false. Always
812 * return false if @a t_id is not managed by the Thread_Manager.
814 int testresume (ACE_thread_t t_id
);
818 // = Send signals to one or more threads without blocking.
820 * Send @a signum to all stopped threads. Not supported on platforms
821 * that do not have advanced signal support, such as Win32.
823 int kill_all (int signum
);
825 * Send the @a signum to a single thread. Not supported on platforms
826 * that do not have advanced signal support, such as Win32.
828 int kill (ACE_thread_t
, int signum
);
830 * Send @a signum to a group of threads, not supported on platforms
831 * that do not have advanced signal support, such as Win32.
833 int kill_grp (int grp_id
, int signum
);
835 // = Cancel methods, which provides a cooperative thread-termination mechanism (will not block).
837 * Cancel's all the threads.
839 int cancel_all (int async_cancel
= 0);
842 * Cancel a single thread.
844 int cancel (ACE_thread_t
, int async_cancel
= 0);
847 * Cancel a group of threads.
849 int cancel_grp (int grp_id
, int async_cancel
= 0);
852 * True if @a t_id is cancelled, else false. Always return false if
853 * @a t_id is not managed by the Thread_Manager.
855 int testcancel (ACE_thread_t t_id
);
858 * True if @a t_id has terminated (i.e., is no longer running),
859 * but the slot in the thread manager hasn't been reclaimed yet,
860 * else false. Always return false if @a t_id is not managed by the
863 int testterminate (ACE_thread_t t_id
);
865 /// Set group ids for a particular thread id.
866 int set_grp (ACE_thread_t
,
869 /// Get group ids for a particular thread id.
870 int get_grp (ACE_thread_t
,
874 * @name Task-related operations
878 * Block until there are no more threads running in a specified task.
879 * This method will not wait for either detached or daemon threads;
880 * the threads must have been spawned with the @c THR_JOINABLE flag.
881 * Upon successful completion, the threads have been joined, so further
882 * attempts to join with any of the waited-for threads will fail.
884 * @param task The ACE_Task_Base object whose threads are to waited for.
887 * @retval -1 Failure (consult errno for further information).
889 int wait_task (ACE_Task_Base
*task
);
892 * Suspend all threads in an ACE_Task.
894 int suspend_task (ACE_Task_Base
*task
);
897 * Resume all threads in an ACE_Task.
899 int resume_task (ACE_Task_Base
*task
);
902 * Send a signal @a signum to all threads in an ACE_Task.
904 int kill_task (ACE_Task_Base
*task
, int signum
);
907 * Cancel all threads in an ACE_Task. If @a async_cancel is non-0,
908 * then asynchronously cancel these threads if the OS platform
909 * supports cancellation. Otherwise, perform a "cooperative"
912 int cancel_task (ACE_Task_Base
*task
, int async_cancel
= 0);
916 // = Collect thread handles in the thread manager. Notice that
917 // the collected information is just a snapshot.
918 /// Check if the thread is managed by the thread manager. Return true if
919 /// the thread is found, false otherwise.
920 int hthread_within (ACE_hthread_t handle
);
921 int thread_within (ACE_thread_t tid
);
923 /// Returns the number of ACE_Task_Base in a group.
924 int num_tasks_in_group (int grp_id
);
926 /// Returns the number of threads in an ACE_Task_Base.
927 int num_threads_in_task (ACE_Task_Base
*task
);
930 * Returns a list of ACE_Task_Base pointers corresponding to the tasks
931 * that have active threads in a specified thread group.
933 * @param grp_id The thread group ID to obtain task pointers for.
935 * @param task_list is a pointer to an array to receive the list of pointers.
936 * The caller is responsible for supplying an array with at
937 * least @arg n entries.
939 * @param n The maximum number of ACE_Task_Base pointers to write
942 * @retval If successful, the number of pointers returned, which will be
943 * no greater than @arg n. Returns -1 on error.
945 * @note This method has no way to indicate if there are more than
946 * @arg n ACE_Task_Base pointers available. Therefore, it may be
947 * wise to guess a larger value of @arg n than one thinks in cases
948 * where the exact number of tasks is not known.
950 * @sa num_tasks_in_group(), task_all_list()
952 ssize_t
task_list (int grp_id
,
953 ACE_Task_Base
*task_list
[],
957 * Returns in @a thread_list a list of up to @a n thread ids in an
958 * ACE_Task_Base. The caller must allocate the memory for
959 * @a thread_list. In case of an error, -1 is returned. If no
960 * requested values are found, 0 is returned, otherwise correct
961 * number of retrieved values are returned.
963 ssize_t
thread_list (ACE_Task_Base
*task
,
964 ACE_thread_t thread_list
[],
968 * Returns in @a hthread_list a list of up to @a n thread handles in
969 * an ACE_Task_Base. The caller must allocate memory for
970 * @a hthread_list. In case of an error, -1 is returned. If no
971 * requested values are found, 0 is returned, otherwise correct
972 * number of retrieved values are returned.
974 ssize_t
hthread_list (ACE_Task_Base
*task
,
975 ACE_hthread_t hthread_list
[],
979 * Returns in @a thread_list a list of up to @a n thread ids in a
980 * group @a grp_id. The caller must allocate the memory for
981 * @a thread_list. In case of an error, -1 is returned. If no
982 * requested values are found, 0 is returned, otherwise correct
983 * number of retrieved values are returned.
985 ssize_t
thread_grp_list (int grp_id
,
986 ACE_thread_t thread_list
[],
990 * Returns in @a hthread_list a list of up to @a n thread handles in
991 * a group @a grp_id. The caller must allocate memory for
994 ssize_t
hthread_grp_list (int grp_id
,
995 ACE_hthread_t hthread_list
[],
999 * Returns a list of ACE_Task_Base pointers corresponding to the tasks
1000 * that have active threads managed by this instance.
1002 * @param task_list is a pointer to an array to receive the list of pointers.
1003 * The caller is responsible for supplying an array with at
1004 * least @arg n entries.
1006 * @param n The maximum number of ACE_Task_Base pointers to write
1007 * in @arg task_list.
1009 * @retval If successful, the number of pointers returned, which will be
1010 * no greater than @arg n. Returns -1 on error.
1012 * @note This method has no way to indicate if there are more than
1013 * @arg n ACE_Task_Base pointers available. Therefore, it may be
1014 * wise to guess a larger value of @arg n than one thinks in cases
1015 * where the exact number of tasks is not known.
1017 * @sa count_threads()
1019 ssize_t
task_all_list (ACE_Task_Base
*task_list
[],
1023 * Returns in @a thread_list a list of up to @a n thread ids. The
1024 * caller must allocate the memory for @a thread_list. In case of an
1025 * error, -1 is returned. If no requested values are found, 0 is
1026 * returned, otherwise correct number of retrieved values are
1029 ssize_t
thread_all_list (ACE_thread_t thread_list
[],
1032 /// Set group ids for a particular task.
1033 int set_grp (ACE_Task_Base
*task
, int grp_id
);
1035 /// Get group ids for a particular task.
1036 int get_grp (ACE_Task_Base
*task
, int &grp_id
);
1038 /// Return a count of the current number of threads active in the
1040 size_t count_threads (void) const;
1042 /// Get the state of the thread. Returns false if the thread is not
1043 /// managed by this thread manager.
1044 int thr_state (ACE_thread_t id
, ACE_UINT32
& state
);
1047 * Register an At_Thread_Exit hook and the ownership is acquire by
1048 * Thread_Descriptor, this is the usual case when the AT is dynamically
1051 int at_exit (ACE_At_Thread_Exit
* cleanup
);
1053 /// Register an At_Thread_Exit hook and the ownership is retained for the
1054 /// caller. Normally used when the at_exit hook is created in stack.
1055 int at_exit (ACE_At_Thread_Exit
& cleanup
);
1060 * @deprecated This function is deprecated. Please use the previous two
1061 * at_exit method. Notice that you should avoid mixing this method
1062 * with the previous two at_exit methods.
1065 * Register an object (or array) for cleanup at
1066 * thread termination. "cleanup_hook" points to a (global, or
1067 * static member) function that is called for the object or array
1068 * when it to be destroyed. It may perform any necessary cleanup
1069 * specific for that object or its class. "param" is passed as the
1070 * second parameter to the "cleanup_hook" function; the first
1071 * parameter is the object (or array) to be destroyed.
1072 * "cleanup_hook", for example, may delete the object (or array).
1073 * If @a cleanup_hook == 0, the @a object will _NOT_ get cleanup at
1074 * thread exit. You can use this to cancel the previously added
1077 int at_exit (void *object
,
1078 ACE_CLEANUP_FUNC cleanup_hook
,
1081 /// Access function to determine whether the Thread_Manager will
1082 /// wait for its thread to exit or not when being closing down.
1083 void wait_on_exit (int dowait
);
1084 int wait_on_exit (void);
1086 /// Dump the state of an object.
1089 /// Declare the dynamic allocation hooks.
1090 ACE_ALLOC_HOOK_DECLARE
;
1093 // = Accessors for ACE_Thread_Descriptors.
1095 * Get a pointer to the calling thread's own thread_descriptor.
1096 * This must be called from a spawn thread. This function will
1097 * fetch the info from TSS.
1099 ACE_Thread_Descriptor
*thread_desc_self (void);
1101 /// Return a pointer to the thread's Thread_Descriptor,
1103 ACE_Thread_Descriptor
*thread_descriptor (ACE_thread_t
);
1105 /// Return a pointer to the thread's Thread_Descriptor,
1107 ACE_Thread_Descriptor
*hthread_descriptor (ACE_hthread_t
);
1109 /// Create a new thread (must be called with locks held).
1110 int spawn_i (ACE_THR_FUNC func
,
1114 ACE_hthread_t
*t_handle
= 0,
1115 long priority
= ACE_DEFAULT_THREAD_PRIORITY
,
1118 size_t stack_size
= 0,
1119 ACE_Task_Base
*task
= 0,
1120 const char** thr_name
= 0);
1122 /// Run the registered hooks when the thread exits.
1123 void run_thread_exit_hooks (int i
);
1125 /// Locate the index of the table slot occupied by @a t_id. Returns
1126 /// -1 if @a t_id is not in the table doesn't contain @a t_id.
1127 ACE_Thread_Descriptor
*find_thread (ACE_thread_t t_id
);
1129 /// Locate the index of the table slot occupied by @a h_id. Returns
1130 /// -1 if @a h_id is not in the table doesn't contain @a h_id.
1131 ACE_Thread_Descriptor
*find_hthread (ACE_hthread_t h_id
);
1134 * Locate the thread descriptor address of the list occupied by
1135 * @a task. Returns 0 if @a task is not in the table doesn't contain
1138 ACE_Thread_Descriptor
*find_task (ACE_Task_Base
*task
,
1141 /// Insert a thread in the table (checks for duplicates).
1142 int insert_thr (ACE_thread_t t_id
,
1147 /// Append a thread in the table (adds at the end, growing the table
1149 int append_thr (ACE_thread_t t_id
, ACE_hthread_t
,
1152 ACE_Task_Base
*task
= 0,
1154 ACE_Thread_Descriptor
*td
= 0);
1156 /// Remove thread from the table.
1157 void remove_thr (ACE_Thread_Descriptor
*td
,
1160 /// Remove all threads from the table.
1161 void remove_thr_all (void);
1163 // = The following four methods implement a simple scheme for
1164 // operating on a collection of threads atomically.
1167 * Efficiently check whether @a thread is in a particular @a state.
1168 * This call updates the TSS cache if possible to speed up
1169 * subsequent searches.
1171 int check_state (ACE_UINT32 state
,
1172 ACE_thread_t thread
,
1175 /// Apply @a func to all members of the table that match the @a task
1176 int apply_task (ACE_Task_Base
*task
,
1177 ACE_THR_MEMBER_FUNC func
,
1180 /// Apply @a func to all members of the table that match the @a grp_id.
1181 int apply_grp (int grp_id
,
1182 ACE_THR_MEMBER_FUNC func
,
1185 /// Apply @a func to all members of the table.
1186 int apply_all (ACE_THR_MEMBER_FUNC
,
1189 /// Join the thread described in @a td.
1190 int join_thr (ACE_Thread_Descriptor
*td
,
1193 /// Resume the thread described in @a td.
1194 int resume_thr (ACE_Thread_Descriptor
*td
,
1197 /// Suspend the thread described in @a td.
1198 int suspend_thr (ACE_Thread_Descriptor
*td
,
1201 /// Send signal @a signum to the thread described in @a td.
1202 int kill_thr (ACE_Thread_Descriptor
*td
,
1205 /// Set the cancellation flag for the thread described in @a td.
1206 int cancel_thr (ACE_Thread_Descriptor
*td
,
1207 int async_cancel
= 0);
1209 /// Register a thread as terminated and put it into the terminated_thr_list_.
1210 int register_as_terminated (ACE_Thread_Descriptor
*td
);
1212 /// Setting the static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_ pointer.
1213 static int set_thr_exit (ACE_TSS_TYPE (ACE_Thread_Exit
) *ptr
);
1216 * Keeping a list of thread descriptors within the thread manager.
1217 * Double-linked list enables us to cache the entries in TSS
1218 * and adding/removing thread descriptor entries without
1219 * affecting other thread's descriptor entries.
1221 ACE_Double_Linked_List
<ACE_Thread_Descriptor
> thr_list_
;
1223 #if !defined (ACE_HAS_VXTHREADS)
1224 /// Collect terminated but not yet joined thread entries.
1225 ACE_Double_Linked_List
<ACE_Thread_Descriptor_Base
> terminated_thr_list_
;
1226 #endif /* !ACE_HAS_VXTHREADS */
1228 /// Collect pointers to thread descriptors of threads to be removed later.
1229 ACE_Unbounded_Queue
<ACE_Thread_Descriptor
*> thr_to_be_removed_
;
1231 /// Keeps track of the next group id to assign.
1234 /// Set if we want the Thread_Manager to wait on all threads before
1235 /// being closed, reset otherwise.
1236 int automatic_wait_
;
1238 // = ACE_Thread_Mutex and condition variable for synchronizing termination.
1239 #if defined (ACE_HAS_THREADS)
1240 /// Serialize access to the zero_cond_.
1241 ACE_Thread_Mutex lock_
;
1243 /// Keep track of when there are no more threads.
1244 ACE_Condition_Thread_Mutex zero_cond_
;
1245 #endif /* ACE_HAS_THREADS */
1247 ACE_Locked_Free_List
<ACE_Thread_Descriptor
, ACE_SYNCH_MUTEX
> thread_desc_freelist_
;
1249 #if defined (ACE_HAS_THREADS) && defined (ACE_LACKS_PTHREAD_JOIN)
1250 ACE_Condition_Thread_Mutex join_cond_
;
1254 #if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
1255 /// Pointer to a process-wide ACE_Thread_Manager.
1256 static ACE_Thread_Manager
*thr_mgr_
;
1258 /// Must delete the thr_mgr_ if true.
1259 static bool delete_thr_mgr_
;
1261 /// Global ACE_TSS (ACE_Thread_Exit) object ptr.
1262 static ACE_TSS_TYPE (ACE_Thread_Exit
) *thr_exit_
;
1263 #endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */
1266 #if defined (ACE_THREAD_MANAGER_LACKS_STATICS)
1267 #define ACE_THREAD_MANAGER_SINGLETON_DEFINE \
1268 ACE_Singleton<ACE_Thread_Manager, ACE_SYNCH_MUTEX>;
1269 typedef ACE_Singleton
<ACE_Thread_Manager
, ACE_SYNCH_MUTEX
> ACE_THREAD_MANAGER_SINGLETON
;
1270 #endif /* defined (ACE_THREAD_MANAGER_LACKS_STATICS) */
1272 ACE_END_VERSIONED_NAMESPACE_DECL
1274 #if defined (__ACE_INLINE__)
1275 #include "ace/Thread_Manager.inl"
1276 #endif /* __ACE_INLINE__ */
1278 #include /**/ "ace/post.h"
1279 #endif /* ACE_THREAD_MANAGER_H */