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 ();
96 virtual ~ACE_At_Thread_Exit ();
98 /// At_Thread_Exit has the ownership?
99 bool is_owner () 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 () 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
117 /// The apply method.
118 virtual void apply () = 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 ();
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
167 friend class ACE_Thread_Manager
;
168 friend class ACE_Double_Linked_List
<ACE_Thread_Descriptor_Base
>;
169 friend class ACE_Double_Linked_List_Iterator_Base
<ACE_Thread_Descriptor_Base
>;
170 friend class ACE_Double_Linked_List_Iterator
<ACE_Thread_Descriptor_Base
>;
171 friend class ACE_Double_Linked_List
<ACE_Thread_Descriptor
>;
172 friend class ACE_Double_Linked_List_Iterator_Base
<ACE_Thread_Descriptor
>;
173 friend class ACE_Double_Linked_List_Iterator
<ACE_Thread_Descriptor
>;
175 ACE_Thread_Descriptor_Base ();
176 virtual ~ACE_Thread_Descriptor_Base ();
178 // = We need the following operators to make Borland happy.
180 /// Equality operator.
181 bool operator== (const ACE_Thread_Descriptor_Base
&rhs
) const;
183 /// Inequality operator.
184 bool operator!= (const ACE_Thread_Descriptor_Base
&rhs
) const;
189 /// Current state of the thread.
190 ACE_UINT32
state () const;
192 /// Return the pointer to an ACE_Task_Base or NULL if there's no
193 /// ACE_Task_Base associated with this thread.;
194 ACE_Task_Base
*task () const;
196 ACE_ALLOC_HOOK_DECLARE
;
199 /// Reset this base thread descriptor.
202 /// Unique thread ID.
203 ACE_thread_t thr_id_
;
205 /// Unique handle to thread (used by Win32).
206 ACE_hthread_t thr_handle_
;
211 /// Current state of the thread.
212 ACE_UINT32 thr_state_
;
214 /// Pointer to an ACE_Task_Base or NULL if there's no
216 ACE_Task_Base
*task_
;
218 /// We need these pointers to maintain the double-linked list in a
220 ACE_Thread_Descriptor_Base
*next_
;
221 ACE_Thread_Descriptor_Base
*prev_
;
225 * @class ACE_Thread_Descriptor
227 * @brief Information for controlling threads that run under the control
228 * of the Thread_Manager.
230 class ACE_Export ACE_Thread_Descriptor
: public ACE_Thread_Descriptor_Base
232 friend class ACE_At_Thread_Exit
;
233 friend class ACE_Thread_Manager
;
234 friend class ACE_Double_Linked_List
<ACE_Thread_Descriptor
>;
235 friend class ACE_Double_Linked_List_Iterator
<ACE_Thread_Descriptor
>;
237 ACE_Thread_Descriptor ();
239 // = Accessor methods.
240 /// Unique thread id.
241 ACE_thread_t
self () const;
243 /// Unique handle to thread (used by Win32).
244 void self (ACE_hthread_t
&);
246 /// Dump the state of an object.
250 * This cleanup function must be called only for ACE_TSS_cleanup.
251 * The ACE_TSS_cleanup delegate Log_Msg instance destruction when
252 * Log_Msg cleanup is called before terminate.
254 void log_msg_cleanup(ACE_Log_Msg
* log_msg
);
257 * Register an At_Thread_Exit hook and the ownership is acquire by
258 * Thread_Descriptor, this is the usual case when the AT is dynamically
261 int at_exit (ACE_At_Thread_Exit
* cleanup
);
263 /// Register an At_Thread_Exit hook and the ownership is retained for the
264 /// caller. Normally used when the at_exit hook is created in stack.
265 int at_exit (ACE_At_Thread_Exit
& cleanup
);
268 * Register an object (or array) for cleanup at thread termination.
269 * "cleanup_hook" points to a (global, or static member) function
270 * that is called for the object or array when it to be destroyed.
271 * It may perform any necessary cleanup specific for that object or
272 * its class. "param" is passed as the second parameter to the
273 * "cleanup_hook" function; the first parameter is the object (or
274 * array) to be destroyed. Returns 0 on success, non-zero on
275 * failure: -1 if virtual memory is exhausted or 1 if the object (or
276 * array) had already been registered.
278 int at_exit (void *object
,
279 ACE_CLEANUP_FUNC cleanup_hook
,
282 /// Do nothing destructor to keep some compilers happy
283 ~ACE_Thread_Descriptor ();
286 * Do nothing but to acquire the thread descriptor's lock and
287 * release. This will first check if the thread is registered or
288 * not. If it is already registered, there's no need to reacquire
289 * the lock again. This is used mainly to get newly spawned thread
290 * in synch with thread manager and prevent it from accessing its
291 * thread descriptor before it gets fully built. This function is
292 * only called from ACE_Log_Msg::thr_desc.
294 void acquire_release ();
299 * Set/get the @c next_ pointer. These are required by the
302 void set_next (ACE_Thread_Descriptor
*td
);
303 ACE_Thread_Descriptor
*get_next () const;
306 /// Run the AT_Thread_Exit hooks.
309 /// Terminate realize the cleanup process to thread termination
313 /// Reset this thread descriptor.
314 void reset (ACE_Thread_Manager
*tm
);
316 /// Pop an At_Thread_Exit from at thread termination list, apply the at
317 /// if apply is true.
318 void at_pop (int apply
= 1);
320 /// Push an At_Thread_Exit to at thread termination list and set the
322 void at_push (ACE_At_Thread_Exit
* cleanup
,
323 bool is_owner
= false);
326 /// Thread_Descriptor is the ownership of ACE_Log_Msg if log_msg_!=0
327 /// This can occur because ACE_TSS_cleanup was executed before terminate.
328 ACE_Log_Msg
*log_msg_
;
330 /// The AT_Thread_Exit list
331 ACE_At_Thread_Exit
*at_exit_list_
;
334 /// Currently not used
336 * Stores the cleanup info for a thread.
337 * @note This should be generalized to be a stack of ACE_Cleanup_Info's.
339 ACE_Cleanup_Info_Node_List cleanup_info_
;
342 /// Pointer to an ACE_Thread_Manager or NULL if there's no
343 /// ACE_Thread_Manager
344 ACE_Thread_Manager
* tm_
;
346 /// Registration lock to prevent premature removal of thread descriptor.
347 ACE_DEFAULT_THREAD_MANAGER_LOCK
*sync_
;
349 /// Keep track of termination status.
353 // Forward declaration.
354 class ACE_Thread_Control
;
356 // This typedef should be (and used to be) inside the
357 // ACE_Thread_Manager declaration. But, it caused compilation
358 // problems on g++/VxWorks/i960 with -g. Note that
359 // ACE_Thread_Manager::THR_FUNC is only used internally in
360 // ACE_Thread_Manager, so it's not useful for anyone else.
361 // It also caused problems on IRIX5 with g++.
362 #if defined (__GNUG__)
363 typedef int (ACE_Thread_Manager::*ACE_THR_MEMBER_FUNC
)(ACE_Thread_Descriptor
*, int);
364 #endif /* __GNUG__ */
367 * @class ACE_Thread_Manager
369 * @brief Manages a pool of threads.
371 * This class allows operations on groups of threads atomically.
372 * The default behavior of thread manager is to wait on
373 * all threads under it's management when it gets destructed.
374 * Therefore, remember to remove a thread from thread manager if
375 * you don't want it to wait for the thread. There are also
376 * functions to disable this default wait-on-exit behavior.
377 * However, if your program depends on turning this off to run
378 * correctly, you are probably doing something wrong. Rule of
379 * thumb, use ACE_Thread to manage your daemon threads.
380 * Notice that if there're threads which live beyond the scope of
381 * main(), you are sure to have resource leaks in your program.
382 * Remember to wait on threads before exiting your main program if that
383 * could happen in your programs.
385 class ACE_Export ACE_Thread_Manager
388 friend class ACE_Thread_Control
;
390 // Allow ACE_Thread_Exit to register the global TSS instance object.
391 friend class ACE_Thread_Exit
;
392 friend class ACE_Thread_Descriptor
;
394 #if !defined (__GNUG__)
395 typedef int (ACE_Thread_Manager::*ACE_THR_MEMBER_FUNC
)(ACE_Thread_Descriptor
*, int);
396 #endif /* !__GNUG__ */
398 /// These are the various states a thread managed by the
399 /// ACE_Thread_Manager can be in.
403 ACE_THR_IDLE
= 0x00000000,
405 /// Created but not yet running.
406 ACE_THR_SPAWNED
= 0x00000001,
408 /// Thread is active (naturally, we don't know if it's actually
409 /// *running* because we aren't the scheduler...).
410 ACE_THR_RUNNING
= 0x00000002,
412 /// Thread is suspended.
413 ACE_THR_SUSPENDED
= 0x00000004,
415 /// Thread has been cancelled (which is an indiction that it needs to
417 ACE_THR_CANCELLED
= 0x00000008,
419 /// Thread has shutdown, but the slot in the thread manager hasn't
420 /// been reclaimed yet.
421 ACE_THR_TERMINATED
= 0x00000010,
423 /// Join operation has been invoked on the thread by thread manager.
424 ACE_THR_JOINING
= 0x10000000
428 * @brief Initialization and termination methods.
430 * Internally, ACE_Thread_Manager keeps a freelist for caching
431 * resources it uses to keep track of managed threads (not the
432 * threads themselves.) @a prealloc, @a lwm, @a inc, @hwm
433 * determine the initial size, the low water mark, increment step,
434 * and high water mark of the freelist.
438 ACE_Thread_Manager (size_t preaolloc
= ACE_DEFAULT_THREAD_MANAGER_PREALLOC
,
439 size_t lwm
= ACE_DEFAULT_THREAD_MANAGER_LWM
,
440 size_t inc
= ACE_DEFAULT_THREAD_MANAGER_INC
,
441 size_t hwm
= ACE_DEFAULT_THREAD_MANAGER_HWM
);
442 ACE_Thread_Manager (const ACE_Condition_Attributes
&attributes
,
443 size_t preaolloc
= ACE_DEFAULT_THREAD_MANAGER_PREALLOC
,
444 size_t lwm
= ACE_DEFAULT_THREAD_MANAGER_LWM
,
445 size_t inc
= ACE_DEFAULT_THREAD_MANAGER_INC
,
446 size_t hwm
= ACE_DEFAULT_THREAD_MANAGER_HWM
);
447 ~ACE_Thread_Manager ();
449 #if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
450 /// Get pointer to a process-wide ACE_Thread_Manager.
451 static ACE_Thread_Manager
*instance ();
453 /// Set pointer to a process-wide ACE_Thread_Manager and return
454 /// existing pointer.
455 static ACE_Thread_Manager
*instance (ACE_Thread_Manager
*);
457 /// Delete the dynamically allocated Singleton
458 static void close_singleton ();
459 #endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */
461 /// No-op. Currently unused.
462 int open (size_t size
= 0);
465 * Release all resources.
466 * By default, this method will wait until all threads exit.
467 * However, when called from close_singleton(), most global resources
468 * are destroyed and thus, close() does not try to wait; it simply cleans
469 * up internal thread records (the thread descriptor list).
474 * Create a new thread, which executes @a func with argument @a arg.
476 * @param func The function that is called in the spawned thread.
478 * @param arg The value passed to each spawned thread's @a func.
480 * @param flags Flags to control attributes of the spawned threads.
481 * @sa ACE_OS::thr_create() for descriptions of the
482 * possible flags values and their interactions.
484 * @param t_id Pointer to a location to receive the spawned thread's
485 * ID. If 0, the ID is not returned.
487 * @param t_handle Pointer to a location to receive the spawned thread's
488 * thread handle. If 0, the handle is not returned.
490 * @param priority The priority at which the thread is spawned.
492 * @param grp_id The thread group that the spawned thread is
493 * added to. If -1 is specified, a new thread group is
494 * created for the spawned thread.
496 * @param stack Pointers to the base of a pre-allocated stack space
497 * for the thread's stack. If 0, the platform allocates
498 * stack space for the thread. If a stack is specified,
499 * it is recommended that @a stack_size also be supplied
500 * to specify the size of the stack.
501 * Not all platforms support pre-allocated stacks. If
502 * @a stack is specified for a platform which does not
503 * allow pre-allocated stack space this parameter is
506 * @param stack_size Indicate how large the thread's stack should be, in
507 * bytes. If a pre-allocated stack pointer is passed in
508 * @a stack, @a stack_size indicates the size of that
509 * stack area. If no pre-allocated stack is passed,
510 * the stack size specified is passed to the
511 * operating system to request that it allocate a stack
512 * of the specified size.
514 * @param thr_name Pointer to a name to assign to the spawned thread.
515 * This is only meaningful for platforms that have a
516 * capacity to name threads (e.g., VxWorks and some
517 * varieties of Pthreads). This argument is ignored if
518 * specified as 0 and on platforms that do not have the
519 * capability to name threads.
521 * @retval -1 on failure; @c errno contains an error value.
522 * @retval The group id of the spawned thread.
524 int spawn (ACE_THR_FUNC func
,
526 long flags
= THR_NEW_LWP
| THR_JOINABLE
| THR_INHERIT_SCHED
,
527 ACE_thread_t
*t_id
= 0,
528 ACE_hthread_t
*t_handle
= 0,
529 long priority
= ACE_DEFAULT_THREAD_PRIORITY
,
532 size_t stack_size
= ACE_DEFAULT_THREAD_STACKSIZE
,
533 const char** thr_name
= 0);
536 * Spawn a specified number of threads, all of which execute @a func
537 * with argument @a arg.
539 * @param n The number of threads to spawn.
541 * @param func The function that is called in the spawned thread.
543 * @param arg The value passed to each spawned thread's @a func.
545 * @param flags Flags to control attributes of the spawned threads.
546 * @sa ACE_OS::thr_create() for descriptions of the
547 * possible flags values and their interactions.
549 * @param priority The priority at which the threads are spawned.
551 * @param grp_id The thread group that the spawned threads are
552 * added to. If -1 is specified, a new thread group is
553 * created for the spawned threads.
555 * @param task The ACE_Task that the spawned threads are associated
556 * with. If 0, the threads are not associated with an
557 * ACE_Task. This argument is usually assigned by the
558 * ACE_Task_Base::activate() method to associate the
559 * spawned threads with the spawning ACE_Task object.
561 * @param thread_handles An array of @a n entries which will receive
562 * the thread handles of the spawned threads.
564 * @param stack An array of @a n pointers to pre-allocated stack space
565 * for each thread's stack. If specified as 0, the
566 * platform allocates stack space for each thread. If
567 * a stack is specified, it is recommended that a
568 * @a stack_size element also be supplied that specifies
569 * the size of the stack.
570 * Not all platforms support pre-allocated stacks. If
571 * @a stack is specified for a platform which does not
572 * allow pre-allocated stack space this parameter is
575 * @param stack_size An array of @a n values which indicate how large
576 * each thread's stack should be, in bytes.
577 * If pre-allocated stacks are passed in @a stacks, these
578 * sizes are for those stacks. If no pre-allocated stacks
579 * are passed, the stack sizes are specified to the
580 * operating system to request that it allocate stacks
581 * of the specified sizes. If an array entry is 0, the
582 * platform defaults are used for the corresponding thread.
583 * If a 0 array pointer is specified, platform defaults
584 * are used for all thread stack sizes.
586 * @param thr_name An array of names to assign to the spawned threads.
587 * This is only meaningful for platforms that have a
588 * capacity to name threads (e.g., VxWorks and some
589 * varieties of Pthreads). This argument is ignored if
590 * specified as 0 and on platforms that do not have the
591 * capability to name threads.
593 * ACE_Thread_Manager can manipulate threads in groups based on
594 * @a grp_id or @a task using functions such as kill_grp() or
597 * @retval -1 on failure; @c errno contains an error value.
598 * @retval The group id of the threads.
600 int spawn_n (size_t n
,
603 long flags
= THR_NEW_LWP
| THR_JOINABLE
| THR_INHERIT_SCHED
,
604 long priority
= ACE_DEFAULT_THREAD_PRIORITY
,
606 ACE_Task_Base
*task
= 0,
607 ACE_hthread_t thread_handles
[] = 0,
609 size_t stack_size
[] = 0,
610 const char* thr_name
[] = 0);
613 * Spawn a specified number of threads, all of which execute @a func
614 * with argument @a arg.
616 * @param thread_ids An array to receive the thread IDs of successfully
617 * spawned buffer. If 0, the thread IDs are not returned.
618 * If specified, the array must be at least @a n entries.
620 * @param n The number of threads to spawn.
622 * @param func The function that is called in the spawned thread.
624 * @param arg The value passed to each spawned thread's @a func.
626 * @param flags Flags to control attributes of the spawned threads.
627 * @sa ACE_OS::thr_create() for descriptions of the
628 * possible flags values and their interactions.
630 * @param priority The priority at which the threads are spawned.
632 * @param grp_id The thread group that the spawned threads are
633 * added to. If -1 is specified, a new thread group is
634 * created for the spawned threads.
636 * @param stack An array of @a n pointers to pre-allocated stack space
637 * for each thread's stack. If specified as 0, the
638 * platform allocates stack space for each thread. If
639 * a stack is specified, it is recommended that a
640 * @a stack_size element also be supplied that specifies
641 * the size of the stack.
642 * Not all platforms support pre-allocated stacks. If
643 * @a stack is specified for a platform which does not
644 * allow pre-allocated stack space this parameter is
647 * @param stack_size An array of @a n values which indicate how large
648 * each thread's stack should be, in bytes.
649 * If pre-allocated stacks are passed in @a stacks, these
650 * sizes are for those stacks. If no pre-allocated stacks
651 * are passed, the stack sizes are specified to the
652 * operating system to request that it allocate stacks
653 * of the specified sizes. If an array entry is 0, the
654 * platform defaults are used for the corresponding thread.
655 * If a 0 array pointer is specified, platform defaults
656 * are used for all thread stack sizes.
658 * @param thread_handles An array of @a n entries which will receive
659 * the thread handles of the spawned threads.
661 * @param task The ACE_Task that the spawned threads are associated
662 * with. If 0, the threads are not associated with an
663 * ACE_Task. This argument is usually assigned by the
664 * ACE_Task_Base::activate() method to associate the
665 * spawned threads with the spawning ACE_Task object.
667 * @param thr_name An array of names to assign to the spawned threads.
668 * This is only meaningful for platforms that have a
669 * capacity to name threads (e.g., VxWorks and some
670 * varieties of Pthreads). This argument is ignored if
671 * specified as 0 and on platforms that do not have the
672 * capability to name threads.
674 * ACE_Thread_Manager can manipulate threads in groups based on
675 * @a grp_id or @a task using functions such as kill_grp() or
678 * @retval -1 on failure; @c errno contains an error value.
679 * @retval The group id of the threads.
682 int spawn_n (ACE_thread_t thread_ids
[],
687 long priority
= ACE_DEFAULT_THREAD_PRIORITY
,
690 size_t stack_size
[] = 0,
691 ACE_hthread_t thread_handles
[] = 0,
692 ACE_Task_Base
*task
= 0,
693 const char* thr_name
[] = 0);
696 * Called to clean up when a thread exits.
698 * @param do_thread_exit If non-0 then ACE_Thread::exit is called to
700 * @param status If ACE_Thread_Exit is called, this is passed as
701 * the exit value of the thread.
702 * Should _not_ be called by main thread.
704 ACE_THR_FUNC_RETURN
exit (ACE_THR_FUNC_RETURN status
= 0,
705 bool do_thread_exit
= true);
708 * Block until there are no more threads running in this thread
709 * manager or @c timeout expires.
711 * @param timeout is treated as "absolute" time by default, but this
712 * can be changed to "relative" time by setting the @c
713 * use_absolute_time to false.
714 * @param abandon_detached_threads If true, @c wait() will first
715 * check thru its thread list for
716 * threads with THR_DETACHED or
717 * THR_DAEMON flags set and remove
718 * these threads. Notice that
719 * unlike other @c wait_*() methods,
720 * by default, @c wait() does wait on
721 * all thread spawned by this
722 * thread manager no matter the detached
723 * flags are set or not unless it is
725 * abandon_detached_threads flag set.
726 * @param use_absolute_time If true then treat @c timeout as
727 * absolute time, else relative time.
728 * @return 0 on success * and -1 on failure.
730 * @note If this function is called while the @c
731 * ACE_Object_Manager is shutting down (as a result of program
732 * rundown via @c ACE::fini()), it will not wait for any threads to
733 * complete. If you must wait for threads spawned by this thread
734 * manager to complete and you are in a ACE rundown situation (such
735 * as your object is being destroyed by the @c ACE_Object_Manager)
736 * you can use @c wait_grp() instead.
738 int wait (const ACE_Time_Value
*timeout
= 0,
739 bool abandon_detached_threads
= false,
740 bool use_absolute_time
= true);
742 /// Join a thread specified by @a tid. Do not wait on a detached thread.
743 int join (ACE_thread_t tid
, ACE_THR_FUNC_RETURN
*status
= 0);
746 * Block until there are no more threads running in a group.
747 * Returns 0 on success and -1 on failure. Notice that wait_grp
748 * will not wait on detached threads.
750 int wait_grp (int grp_id
);
753 * Return the "real" handle to the calling thread, caching it if
754 * necessary in TSS to speed up subsequent lookups. This is
755 * necessary since on some platforms (e.g., Windows) we can't get this
756 * handle via direct method calls. Notice that you should *not*
757 * close the handle passed back from this method. It is used
758 * internally by Thread Manager. On the other hand, you *have to*
759 * use this internal thread handle when working on Thread_Manager.
762 int thr_self (ACE_hthread_t
&);
765 * Return the unique ID of the calling thread.
766 * Same as calling ACE_Thread::self().
768 ACE_thread_t
thr_self ();
771 * Returns a pointer to the current ACE_Task_Base we're executing
772 * in if this thread is indeed running in an ACE_Task_Base, else
775 ACE_Task_Base
*task ();
778 * @name Suspend and resume methods
780 * Suspend/resume is not supported on all platforms. For example, Pthreads
781 * does not support these functions.
784 /// Suspend all threads
787 /// Suspend a single thread.
788 int suspend (ACE_thread_t
);
790 /// Suspend a group of threads.
791 int suspend_grp (int grp_id
);
794 * True if @a t_id is inactive (i.e., suspended), else false. Always
795 * return false if @a t_id is not managed by the Thread_Manager.
797 int testsuspend (ACE_thread_t t_id
);
799 /// Resume all stopped threads
802 /// Resume a single thread.
803 int resume (ACE_thread_t
);
805 /// Resume a group of threads.
806 int resume_grp (int grp_id
);
809 * True if @a t_id is active (i.e., resumed), else false. Always
810 * return false if @a t_id is not managed by the Thread_Manager.
812 int testresume (ACE_thread_t t_id
);
816 // = Send signals to one or more threads without blocking.
818 * Send @a signum to all stopped threads. Not supported on platforms
819 * that do not have advanced signal support, such as Win32.
821 int kill_all (int signum
);
823 * Send the @a signum to a single thread. Not supported on platforms
824 * that do not have advanced signal support, such as Win32.
826 int kill (ACE_thread_t
, int signum
);
828 * Send @a signum to a group of threads, not supported on platforms
829 * that do not have advanced signal support, such as Win32.
831 int kill_grp (int grp_id
, int signum
);
833 // = Cancel methods, which provides a cooperative thread-termination mechanism (will not block).
835 * Cancel's all the threads.
837 int cancel_all (int async_cancel
= 0);
840 * Cancel a single thread.
842 int cancel (ACE_thread_t
, int async_cancel
= 0);
845 * Cancel a group of threads.
847 int cancel_grp (int grp_id
, int async_cancel
= 0);
850 * True if @a t_id is cancelled, else false. Always return false if
851 * @a t_id is not managed by the Thread_Manager.
853 int testcancel (ACE_thread_t t_id
);
856 * True if @a t_id has terminated (i.e., is no longer running),
857 * but the slot in the thread manager hasn't been reclaimed yet,
858 * else false. Always return false if @a t_id is not managed by the
861 int testterminate (ACE_thread_t t_id
);
863 /// Set group ids for a particular thread id.
864 int set_grp (ACE_thread_t
,
867 /// Get group ids for a particular thread id.
868 int get_grp (ACE_thread_t
,
872 * @name Task-related operations
876 * Block until there are no more threads running in a specified task.
877 * This method will not wait for either detached or daemon threads;
878 * the threads must have been spawned with the @c THR_JOINABLE flag.
879 * Upon successful completion, the threads have been joined, so further
880 * attempts to join with any of the waited-for threads will fail.
882 * @param task The ACE_Task_Base object whose threads are to waited for.
885 * @retval -1 Failure (consult errno for further information).
887 int wait_task (ACE_Task_Base
*task
);
890 * Suspend all threads in an ACE_Task.
892 int suspend_task (ACE_Task_Base
*task
);
895 * Resume all threads in an ACE_Task.
897 int resume_task (ACE_Task_Base
*task
);
900 * Send a signal @a signum to all threads in an ACE_Task.
902 int kill_task (ACE_Task_Base
*task
, int signum
);
905 * Cancel all threads in an ACE_Task. If @a async_cancel is non-0,
906 * then asynchronously cancel these threads if the OS platform
907 * supports cancellation. Otherwise, perform a "cooperative"
910 int cancel_task (ACE_Task_Base
*task
, int async_cancel
= 0);
914 // = Collect thread handles in the thread manager. Notice that
915 // the collected information is just a snapshot.
916 /// Check if the thread is managed by the thread manager. Return true if
917 /// the thread is found, false otherwise.
918 int hthread_within (ACE_hthread_t handle
);
919 int thread_within (ACE_thread_t tid
);
921 /// Returns the number of ACE_Task_Base in a group.
922 int num_tasks_in_group (int grp_id
);
924 /// Returns the number of threads in an ACE_Task_Base.
925 int num_threads_in_task (ACE_Task_Base
*task
);
928 * Returns a list of ACE_Task_Base pointers corresponding to the tasks
929 * that have active threads in a specified thread group.
931 * @param grp_id The thread group ID to obtain task pointers for.
933 * @param task_list is a pointer to an array to receive the list of pointers.
934 * The caller is responsible for supplying an array with at
935 * least @arg n entries.
937 * @param n The maximum number of ACE_Task_Base pointers to write
940 * @retval If successful, the number of pointers returned, which will be
941 * no greater than @arg n. Returns -1 on error.
943 * @note This method has no way to indicate if there are more than
944 * @arg n ACE_Task_Base pointers available. Therefore, it may be
945 * wise to guess a larger value of @arg n than one thinks in cases
946 * where the exact number of tasks is not known.
948 * @sa num_tasks_in_group(), task_all_list()
950 ssize_t
task_list (int grp_id
,
951 ACE_Task_Base
*task_list
[],
955 * Returns in @a thread_list a list of up to @a n thread ids in an
956 * ACE_Task_Base. The caller must allocate the memory for
957 * @a thread_list. In case of an error, -1 is returned. If no
958 * requested values are found, 0 is returned, otherwise correct
959 * number of retrieved values are returned.
961 ssize_t
thread_list (ACE_Task_Base
*task
,
962 ACE_thread_t thread_list
[],
966 * Returns in @a hthread_list a list of up to @a n thread handles in
967 * an ACE_Task_Base. The caller must allocate memory for
968 * @a hthread_list. In case of an error, -1 is returned. If no
969 * requested values are found, 0 is returned, otherwise correct
970 * number of retrieved values are returned.
972 ssize_t
hthread_list (ACE_Task_Base
*task
,
973 ACE_hthread_t hthread_list
[],
977 * Returns in @a thread_list a list of up to @a n thread ids in a
978 * group @a grp_id. The caller must allocate the memory for
979 * @a thread_list. In case of an error, -1 is returned. If no
980 * requested values are found, 0 is returned, otherwise correct
981 * number of retrieved values are returned.
983 ssize_t
thread_grp_list (int grp_id
,
984 ACE_thread_t thread_list
[],
988 * Returns in @a hthread_list a list of up to @a n thread handles in
989 * a group @a grp_id. The caller must allocate memory for
992 ssize_t
hthread_grp_list (int grp_id
,
993 ACE_hthread_t hthread_list
[],
997 * Returns a list of ACE_Task_Base pointers corresponding to the tasks
998 * that have active threads managed by this instance.
1000 * @param task_list is a pointer to an array to receive the list of pointers.
1001 * The caller is responsible for supplying an array with at
1002 * least @arg n entries.
1004 * @param n The maximum number of ACE_Task_Base pointers to write
1005 * in @arg task_list.
1007 * @retval If successful, the number of pointers returned, which will be
1008 * no greater than @arg n. Returns -1 on error.
1010 * @note This method has no way to indicate if there are more than
1011 * @arg n ACE_Task_Base pointers available. Therefore, it may be
1012 * wise to guess a larger value of @arg n than one thinks in cases
1013 * where the exact number of tasks is not known.
1015 * @sa count_threads()
1017 ssize_t
task_all_list (ACE_Task_Base
*task_list
[],
1021 * Returns in @a thread_list a list of up to @a n thread ids. The
1022 * caller must allocate the memory for @a thread_list. In case of an
1023 * error, -1 is returned. If no requested values are found, 0 is
1024 * returned, otherwise correct number of retrieved values are
1027 ssize_t
thread_all_list (ACE_thread_t thread_list
[],
1030 /// Set group ids for a particular task.
1031 int set_grp (ACE_Task_Base
*task
, int grp_id
);
1033 /// Get group ids for a particular task.
1034 int get_grp (ACE_Task_Base
*task
, int &grp_id
);
1036 /// Return a count of the current number of threads active in the
1038 size_t count_threads () const;
1040 /// Get the state of the thread. Returns false if the thread is not
1041 /// managed by this thread manager.
1042 int thr_state (ACE_thread_t id
, ACE_UINT32
& state
);
1045 * Register an At_Thread_Exit hook and the ownership is acquire by
1046 * Thread_Descriptor, this is the usual case when the AT is dynamically
1049 int at_exit (ACE_At_Thread_Exit
* cleanup
);
1051 /// Register an At_Thread_Exit hook and the ownership is retained for the
1052 /// caller. Normally used when the at_exit hook is created in stack.
1053 int at_exit (ACE_At_Thread_Exit
& cleanup
);
1058 * @deprecated This function is deprecated. Please use the previous two
1059 * at_exit method. Notice that you should avoid mixing this method
1060 * with the previous two at_exit methods.
1063 * Register an object (or array) for cleanup at
1064 * thread termination. "cleanup_hook" points to a (global, or
1065 * static member) function that is called for the object or array
1066 * when it to be destroyed. It may perform any necessary cleanup
1067 * specific for that object or its class. "param" is passed as the
1068 * second parameter to the "cleanup_hook" function; the first
1069 * parameter is the object (or array) to be destroyed.
1070 * "cleanup_hook", for example, may delete the object (or array).
1071 * If @a cleanup_hook == 0, the @a object will _NOT_ get cleanup at
1072 * thread exit. You can use this to cancel the previously added
1075 int at_exit (void *object
,
1076 ACE_CLEANUP_FUNC cleanup_hook
,
1079 /// Access function to determine whether the Thread_Manager will
1080 /// wait for its thread to exit or not when being closing down.
1081 void wait_on_exit (int dowait
);
1082 int wait_on_exit ();
1084 /// Dump the state of an object.
1087 /// Declare the dynamic allocation hooks.
1088 ACE_ALLOC_HOOK_DECLARE
;
1091 // = Accessors for ACE_Thread_Descriptors.
1093 * Get a pointer to the calling thread's own thread_descriptor.
1094 * This must be called from a spawn thread. This function will
1095 * fetch the info from TSS.
1097 ACE_Thread_Descriptor
*thread_desc_self ();
1099 /// Return a pointer to the thread's Thread_Descriptor,
1101 ACE_Thread_Descriptor
*thread_descriptor (ACE_thread_t
);
1103 /// Return a pointer to the thread's Thread_Descriptor,
1105 ACE_Thread_Descriptor
*hthread_descriptor (ACE_hthread_t
);
1107 /// Create a new thread (must be called with locks held).
1108 int spawn_i (ACE_THR_FUNC func
,
1112 ACE_hthread_t
*t_handle
= 0,
1113 long priority
= ACE_DEFAULT_THREAD_PRIORITY
,
1116 size_t stack_size
= 0,
1117 ACE_Task_Base
*task
= 0,
1118 const char** thr_name
= 0);
1120 /// Run the registered hooks when the thread exits.
1121 void run_thread_exit_hooks (int i
);
1123 /// Locate the index of the table slot occupied by @a t_id. Returns
1124 /// -1 if @a t_id is not in the table doesn't contain @a t_id.
1125 ACE_Thread_Descriptor
*find_thread (ACE_thread_t t_id
);
1127 /// Locate the index of the table slot occupied by @a h_id. Returns
1128 /// -1 if @a h_id is not in the table doesn't contain @a h_id.
1129 ACE_Thread_Descriptor
*find_hthread (ACE_hthread_t h_id
);
1132 * Locate the thread descriptor address of the list occupied by
1133 * @a task. Returns 0 if @a task is not in the table doesn't contain
1136 ACE_Thread_Descriptor
*find_task (ACE_Task_Base
*task
,
1139 /// Insert a thread in the table (checks for duplicates).
1140 int insert_thr (ACE_thread_t t_id
,
1145 /// Append a thread in the table (adds at the end, growing the table
1147 int append_thr (ACE_thread_t t_id
, ACE_hthread_t
,
1150 ACE_Task_Base
*task
= 0,
1152 ACE_Thread_Descriptor
*td
= 0);
1154 /// Remove thread from the table.
1155 void remove_thr (ACE_Thread_Descriptor
*td
,
1158 /// Remove all threads from the table.
1159 void remove_thr_all ();
1161 // = The following four methods implement a simple scheme for
1162 // operating on a collection of threads atomically.
1165 * Efficiently check whether @a thread is in a particular @a state.
1166 * This call updates the TSS cache if possible to speed up
1167 * subsequent searches.
1169 int check_state (ACE_UINT32 state
,
1170 ACE_thread_t thread
,
1173 /// Apply @a func to all members of the table that match the @a task
1174 int apply_task (ACE_Task_Base
*task
,
1175 ACE_THR_MEMBER_FUNC func
,
1178 /// Apply @a func to all members of the table that match the @a grp_id.
1179 int apply_grp (int grp_id
,
1180 ACE_THR_MEMBER_FUNC func
,
1183 /// Apply @a func to all members of the table.
1184 int apply_all (ACE_THR_MEMBER_FUNC
,
1187 /// Join the thread described in @a td.
1188 int join_thr (ACE_Thread_Descriptor
*td
,
1191 /// Resume the thread described in @a td.
1192 int resume_thr (ACE_Thread_Descriptor
*td
,
1195 /// Suspend the thread described in @a td.
1196 int suspend_thr (ACE_Thread_Descriptor
*td
,
1199 /// Send signal @a signum to the thread described in @a td.
1200 int kill_thr (ACE_Thread_Descriptor
*td
,
1203 /// Set the cancellation flag for the thread described in @a td.
1204 int cancel_thr (ACE_Thread_Descriptor
*td
,
1205 int async_cancel
= 0);
1207 /// Register a thread as terminated and put it into the terminated_thr_list_.
1208 int register_as_terminated (ACE_Thread_Descriptor
*td
);
1210 /// Setting the static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_ pointer.
1211 static int set_thr_exit (ACE_TSS_TYPE (ACE_Thread_Exit
) *ptr
);
1214 * Keeping a list of thread descriptors within the thread manager.
1215 * Double-linked list enables us to cache the entries in TSS
1216 * and adding/removing thread descriptor entries without
1217 * affecting other thread's descriptor entries.
1219 ACE_Double_Linked_List
<ACE_Thread_Descriptor
> thr_list_
;
1221 #if !defined (ACE_HAS_VXTHREADS)
1222 /// Collect terminated but not yet joined thread entries.
1223 ACE_Double_Linked_List
<ACE_Thread_Descriptor_Base
> terminated_thr_list_
;
1224 #endif /* !ACE_HAS_VXTHREADS */
1226 /// Collect pointers to thread descriptors of threads to be removed later.
1227 ACE_Unbounded_Queue
<ACE_Thread_Descriptor
*> thr_to_be_removed_
;
1229 /// Keeps track of the next group id to assign.
1232 /// Set if we want the Thread_Manager to wait on all threads before
1233 /// being closed, reset otherwise.
1234 int automatic_wait_
;
1236 // = ACE_Thread_Mutex and condition variable for synchronizing termination.
1237 #if defined (ACE_HAS_THREADS)
1238 /// Serialize access to the zero_cond_.
1239 ACE_Thread_Mutex lock_
;
1241 /// Keep track of when there are no more threads.
1242 ACE_Condition_Thread_Mutex zero_cond_
;
1243 #endif /* ACE_HAS_THREADS */
1245 ACE_Locked_Free_List
<ACE_Thread_Descriptor
, ACE_SYNCH_MUTEX
> thread_desc_freelist_
;
1247 #if defined (ACE_HAS_THREADS) && defined (ACE_LACKS_PTHREAD_JOIN)
1248 ACE_Condition_Thread_Mutex join_cond_
;
1252 #if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
1253 /// Pointer to a process-wide ACE_Thread_Manager.
1254 static ACE_Thread_Manager
*thr_mgr_
;
1256 /// Must delete the thr_mgr_ if true.
1257 static bool delete_thr_mgr_
;
1259 /// Global ACE_TSS (ACE_Thread_Exit) object ptr.
1260 static ACE_TSS_TYPE (ACE_Thread_Exit
) *thr_exit_
;
1261 #endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */
1264 #if defined (ACE_THREAD_MANAGER_LACKS_STATICS)
1265 #define ACE_THREAD_MANAGER_SINGLETON_DEFINE \
1266 ACE_Singleton<ACE_Thread_Manager, ACE_SYNCH_MUTEX>;
1267 typedef ACE_Singleton
<ACE_Thread_Manager
, ACE_SYNCH_MUTEX
> ACE_THREAD_MANAGER_SINGLETON
;
1268 #endif /* defined (ACE_THREAD_MANAGER_LACKS_STATICS) */
1270 ACE_END_VERSIONED_NAMESPACE_DECL
1272 #if defined (__ACE_INLINE__)
1273 #include "ace/Thread_Manager.inl"
1274 #endif /* __ACE_INLINE__ */
1276 #include /**/ "ace/post.h"
1277 #endif /* ACE_THREAD_MANAGER_H */