Initial Patch of Auction House bot rev. 135
[auctionmangos.git] / dep / ACE_wrappers / ace / Thread_Manager.h
blob2703aae405ad694e287df30f8279c7298f6ce3d5
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Thread_Manager.h
7 * $Id: Thread_Manager.h 82588 2008-08-11 13:37:41Z johnnyw $
9 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
11 //=============================================================================
13 #ifndef ACE_THREAD_MANAGER_H
14 #define ACE_THREAD_MANAGER_H
15 #include /**/ "ace/pre.h"
17 #include "ace/Thread.h"
18 #include "ace/Thread_Adapter.h"
19 #include "ace/Thread_Exit.h"
21 #if !defined (ACE_LACKS_PRAGMA_ONCE)
22 # pragma once
23 #endif /* ACE_LACKS_PRAGMA_ONCE */
25 #include "ace/Condition_Thread_Mutex.h"
26 #include "ace/Unbounded_Queue.h"
27 #include "ace/Containers.h"
28 #include "ace/Free_List.h"
29 #include "ace/Singleton.h"
30 #include "ace/Log_Msg.h"
31 #include "ace/Synch_Traits.h"
32 #include "ace/Basic_Types.h"
34 // The following macros control how a Thread Manager manages a pool of
35 // Thread_Descriptor. Currently, the default behavior is not to
36 // preallocate any thread descriptor and never (well, almost never)
37 // free up any thread descriptor until the Thread Manager gets
38 // destructed. Which means, once your system is stable, you rarely
39 // need to pay the price of memory allocation. On a deterministic
40 // system, which means, the number of threads spawned can be
41 // determined before hand, you can either redefine the memory pool
42 // size macros to suit your need or constructed the Thread_Manager
43 // accordingly. That way, you don't pay the price of memory
44 // allocation when the system is really doing its job. OTOH, on
45 // system with resources constraint, you may want to lower the size of
46 // ACE_DEFAULT_THREAD_MANAGER_HWM to avoid unused memory hanging
47 // around.
49 #if !defined (ACE_DEFAULT_THREAD_MANAGER_PREALLOC)
50 # define ACE_DEFAULT_THREAD_MANAGER_PREALLOC 0
51 #endif /* ACE_DEFAULT_THREAD_MANAGER_PREALLOC */
53 #if !defined (ACE_DEFAULT_THREAD_MANAGER_LWM)
54 # define ACE_DEFAULT_THREAD_MANAGER_LWM 1
55 #endif /* ACE_DEFAULT_THREAD_MANAGER_LWM */
57 #if !defined (ACE_DEFAULT_THREAD_MANAGER_INC)
58 # define ACE_DEFAULT_THREAD_MANAGER_INC 1
59 #endif /* ACE_DEFAULT_THREAD_MANAGER_INC */
61 #if !defined (ACE_DEFAULT_THREAD_MANAGER_HWM)
62 # define ACE_DEFAULT_THREAD_MANAGER_HWM ACE_DEFAULT_FREE_LIST_HWM
63 // this is a big number
64 #endif /* ACE_DEFAULT_THREAD_MANAGER_HWM */
66 // This is the synchronization mechanism used to prevent a thread
67 // descriptor gets removed from the Thread_Manager before it gets
68 // stash into it. If you want to disable this feature (and risk of
69 // corrupting the freelist,) you define the lock as ACE_Null_Mutex.
70 // Usually, if you can be sure that your threads will run for an
71 // extended period of time, you can safely disable the lock.
73 #if !defined (ACE_DEFAULT_THREAD_MANAGER_LOCK)
74 # define ACE_DEFAULT_THREAD_MANAGER_LOCK ACE_SYNCH_MUTEX
75 #endif /* ACE_DEFAULT_THREAD_MANAGER_LOCK */
77 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
79 // Forward declarations.
80 class ACE_Task_Base;
81 class ACE_Thread_Manager;
82 class ACE_Thread_Descriptor;
84 /**
85 * @class ACE_At_Thread_Exit
87 * @brief Contains a method to be applied when a thread is terminated.
89 class ACE_Export ACE_At_Thread_Exit
91 friend class ACE_Thread_Descriptor;
92 friend class ACE_Thread_Manager;
93 public:
94 /// Default constructor
95 ACE_At_Thread_Exit (void);
97 /// The destructor
98 virtual ~ACE_At_Thread_Exit (void);
100 /// At_Thread_Exit has the ownership?
101 bool is_owner (void) const;
103 /// Set the ownership of the At_Thread_Exit.
104 bool is_owner (bool owner);
106 /// This At_Thread_Exit was applied?
107 bool was_applied (void) const;
109 /// Set applied state of At_Thread_Exit.
110 bool was_applied (bool applied);
112 protected:
113 /// The next At_Thread_Exit hook in the list.
114 ACE_At_Thread_Exit *next_;
116 /// Do the apply if necessary
117 void do_apply (void);
119 /// The apply method.
120 virtual void apply (void) = 0;
122 /// The Thread_Descriptor where this at is registered.
123 ACE_Thread_Descriptor* td_;
125 /// The at was applied?
126 bool was_applied_;
128 /// The at has the ownership of this?
129 bool is_owner_;
132 class ACE_Export ACE_At_Thread_Exit_Func : public ACE_At_Thread_Exit
134 public:
135 /// Constructor
136 ACE_At_Thread_Exit_Func (void *object,
137 ACE_CLEANUP_FUNC func,
138 void *param = 0);
140 virtual ~ACE_At_Thread_Exit_Func (void);
142 protected:
143 /// The object to be cleanup
144 void *object_;
146 /// The cleanup func
147 ACE_CLEANUP_FUNC func_;
149 /// A param if required
150 void *param_;
152 /// The apply method
153 void apply (void);
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
161 * terminated.
163 * @internal
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>;
175 public:
176 ACE_Thread_Descriptor_Base (void);
177 ~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;
187 /// Group ID.
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 protected:
198 /// Reset this base thread descriptor.
199 void reset (void);
201 /// Unique thread ID.
202 ACE_thread_t thr_id_;
204 /// Unique handle to thread (used by Win32 and AIX).
205 ACE_hthread_t thr_handle_;
207 /// Group ID.
208 int grp_id_;
210 /// Current state of the thread.
211 ACE_UINT32 thr_state_;
213 /// Pointer to an ACE_Task_Base or NULL if there's no
214 /// ACE_Task_Base.
215 ACE_Task_Base *task_;
217 /// We need these pointers to maintain the double-linked list in a
218 /// thread managers.
219 ACE_Thread_Descriptor_Base *next_;
220 ACE_Thread_Descriptor_Base *prev_;
224 * @class ACE_Thread_Descriptor
226 * @brief Information for controlling threads that run under the control
227 * of the <Thread_Manager>.
229 class ACE_Export ACE_Thread_Descriptor : public ACE_Thread_Descriptor_Base
231 friend class ACE_At_Thread_Exit;
232 friend class ACE_Thread_Manager;
233 friend class ACE_Double_Linked_List<ACE_Thread_Descriptor>;
234 friend class ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor>;
235 public:
236 // = Initialization method.
237 ACE_Thread_Descriptor (void);
239 // = Accessor methods.
240 /// Unique thread id.
241 ACE_thread_t self (void) const;
243 /// Unique handle to thread (used by Win32 and AIX).
244 void self (ACE_hthread_t &);
246 /// Dump the state of an object.
247 void dump (void) const;
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
259 * allocated.
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 * arrayt) had already been registered.
278 int at_exit (void *object,
279 ACE_CLEANUP_FUNC cleanup_hook,
280 void *param);
282 /// Do nothing destructor to keep some compilers happy
283 ~ACE_Thread_Descriptor (void);
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 (void);
295 void acquire (void);
296 void release (void);
299 * Set/get the @c next_ pointer. These are required by the
300 * ACE_Free_List.
302 void set_next (ACE_Thread_Descriptor *td);
303 ACE_Thread_Descriptor *get_next (void) const;
305 private:
306 /// Reset this thread descriptor.
307 void reset (ACE_Thread_Manager *tm);
309 /// Pop an At_Thread_Exit from at thread termination list, apply the at
310 /// if apply is true.
311 void at_pop (int apply = 1);
313 /// Push an At_Thread_Exit to at thread termination list and set the
314 /// ownership of at.
315 void at_push (ACE_At_Thread_Exit* cleanup,
316 bool is_owner = false);
318 /// Run the AT_Thread_Exit hooks.
319 void do_at_exit (void);
321 /// Terminate realize the cleanup process to thread termination
322 void terminate (void);
324 /// Thread_Descriptor is the ownership of ACE_Log_Msg if log_msg_!=0
325 /// This can occur because ACE_TSS_cleanup was executed before terminate.
326 ACE_Log_Msg *log_msg_;
328 /// The AT_Thread_Exit list
329 ACE_At_Thread_Exit *at_exit_list_;
332 * Stores the cleanup info for a thread.
333 * @note This should be generalized to be a stack of ACE_Cleanup_Info's.
335 ACE_Cleanup_Info cleanup_info_;
337 /// Pointer to an ACE_Thread_Manager or NULL if there's no
338 /// ACE_Thread_Manager>
339 ACE_Thread_Manager* tm_;
341 /// Registration lock to prevent premature removal of thread descriptor.
342 ACE_DEFAULT_THREAD_MANAGER_LOCK *sync_;
344 /// Keep track of termination status.
345 bool terminated_;
348 // Forward declaration.
349 class ACE_Thread_Control;
351 // This typedef should be (and used to be) inside the
352 // ACE_Thread_Manager declaration. But, it caused compilation
353 // problems on g++/VxWorks/i960 with -g. Note that
354 // ACE_Thread_Manager::THR_FUNC is only used internally in
355 // ACE_Thread_Manager, so it's not useful for anyone else.
356 // It also caused problems on IRIX5 with g++.
357 #if defined (__GNUG__)
358 typedef int (ACE_Thread_Manager::*ACE_THR_MEMBER_FUNC)(ACE_Thread_Descriptor *, int);
359 #endif /* __GNUG__ */
362 * @class ACE_Thread_Manager
364 * @brief Manages a pool of threads.
366 * This class allows operations on groups of threads atomically.
367 * The default behavior of thread manager is to wait on
368 * all threads under it's management when it gets destructed.
369 * Therefore, remember to remove a thread from thread manager if
370 * you don't want it to wait for the thread. There are also
371 * functions to disable this default wait-on-exit behavior.
372 * However, if your program depends on turning this off to run
373 * correctly, you are probably doing something wrong. Rule of
374 * thumb, use ACE_Thread to manage your daemon threads.
375 * Notice that if there're threads which live beyond the scope of
376 * main(), you are sure to have resource leaks in your program.
377 * Remember to wait on threads before exiting your main program if that
378 * could happen in your programs.
380 class ACE_Export ACE_Thread_Manager
382 public:
383 friend class ACE_Thread_Control;
385 // Allow ACE_THread_Exit to register the global TSS instance object.
386 friend class ACE_Thread_Exit;
387 friend class ACE_Thread_Descriptor;
389 #if !defined (__GNUG__)
390 typedef int (ACE_Thread_Manager::*ACE_THR_MEMBER_FUNC)(ACE_Thread_Descriptor *, int);
391 #endif /* !__GNUG__ */
393 /// These are the various states a thread managed by the
394 /// ACE_Thread_Manager can be in.
395 enum
397 /// Uninitialized.
398 ACE_THR_IDLE = 0x00000000,
400 /// Created but not yet running.
401 ACE_THR_SPAWNED = 0x00000001,
403 /// Thread is active (naturally, we don't know if it's actually
404 /// *running* because we aren't the scheduler...).
405 ACE_THR_RUNNING = 0x00000002,
407 /// Thread is suspended.
408 ACE_THR_SUSPENDED = 0x00000004,
410 /// Thread has been cancelled (which is an indiction that it needs to
411 /// terminate...).
412 ACE_THR_CANCELLED = 0x00000008,
414 /// Thread has shutdown, but the slot in the thread manager hasn't
415 /// been reclaimed yet.
416 ACE_THR_TERMINATED = 0x00000010,
418 /// Join operation has been invoked on the thread by thread manager.
419 ACE_THR_JOINING = 0x10000000
423 * @brief Initialization and termination methods.
425 * Internally, ACE_Thread_Manager keeps a freelist for caching
426 * resources it uses to keep track of managed threads (not the
427 * threads themselves.) @a prealloc, @a lwm, @a inc, @hwm
428 * determine the initial size, the low water mark, increment step,
429 * and high water mark of the freelist.
431 * @sa ACE_Free_List
433 ACE_Thread_Manager (size_t preaolloc = ACE_DEFAULT_THREAD_MANAGER_PREALLOC,
434 size_t lwm = ACE_DEFAULT_THREAD_MANAGER_LWM,
435 size_t inc = ACE_DEFAULT_THREAD_MANAGER_INC,
436 size_t hwm = ACE_DEFAULT_THREAD_MANAGER_HWM);
437 ~ACE_Thread_Manager (void);
439 #if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
440 /// Get pointer to a process-wide ACE_Thread_Manager.
441 static ACE_Thread_Manager *instance (void);
443 /// Set pointer to a process-wide ACE_Thread_Manager and return
444 /// existing pointer.
445 static ACE_Thread_Manager *instance (ACE_Thread_Manager *);
447 /// Delete the dynamically allocated Singleton
448 static void close_singleton (void);
449 #endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */
451 /// No-op. Currently unused.
452 int open (size_t size = 0);
455 * Release all resources.
456 * By default, this method will wait until all threads exit.
457 * However, when called from close_singleton(), most global resources
458 * are destroyed and thus, close() does not try to wait; it simply cleans
459 * up internal thread records (the thread descriptor list).
461 int close (void);
464 * Create a new thread, which executes @a func with argument @a arg.
466 * @param func The function that is called in the spawned thread.
468 * @param arg The value passed to each spawned thread's @a func.
470 * @param flags Flags to control attributes of the spawned threads.
471 * @sa ACE_OS::thr_create() for descriptions of the
472 * possible flags values and their interactions.
474 * @param t_id Pointer to a location to receive the spawned thread's
475 * ID. If 0, the ID is not returned.
477 * @param t_handle Pointer to a location to receive the spawned thread's
478 * thread handle. If 0, the handle is not returned.
480 * @param priority The priority at which the thread is spawned.
482 * @param grp_id The thread group that the spawned thread is
483 * added to. If -1 is specified, a new thread group is
484 * created for the spawned thread.
486 * @param stack Pointers to the base of a pre-allocated stack space
487 * for the thread's stack. If 0, the platform allocates
488 * stack space for the thread. If a stack is specified,
489 * it is recommended that @a stack_size also be supplied
490 * to specify the size of the stack.
491 * Not all platforms support pre-allocated stacks. If
492 * @a stack is specified for a platform which does not
493 * allow pre-allocated stack space this parameter is
494 * ignored.
496 * @param stack_size Indicate how large the thread's stack should be, in
497 * bytes. If a pre-allocated stack pointer is passed in
498 * @a stack, @a stack_size indicates the size of that
499 * stack area. If no pre-allocated stack is passed,
500 * the stack size specified is passed to the
501 * operating system to request that it allocate a stack
502 * of the specified size.
504 * @param thr_name Pointer to a name to assign to the spawned thread.
505 * This is only meaningful for platforms that have a
506 * capacity to name threads (e.g., VxWorks and some
507 * varieties of Pthreads). This argument is ignored if
508 * specified as 0 and on platforms that do not have the
509 * capability to name threads.
511 * @retval -1 on failure; @c errno contains an error value.
512 * @retval The group id of the spawned thread.
514 int spawn (ACE_THR_FUNC func,
515 void *arg = 0,
516 long flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED,
517 ACE_thread_t *t_id = 0,
518 ACE_hthread_t *t_handle = 0,
519 long priority = ACE_DEFAULT_THREAD_PRIORITY,
520 int grp_id = -1,
521 void *stack = 0,
522 size_t stack_size = ACE_DEFAULT_THREAD_STACKSIZE,
523 const char** thr_name = 0);
526 * Spawn a specified number of threads, all of which execute @a func
527 * with argument @a arg.
529 * @param n The number of threads to spawn.
531 * @param func The function that is called in the spawned thread.
533 * @param arg The value passed to each spawned thread's @a func.
535 * @param flags Flags to control attributes of the spawned threads.
536 * @sa ACE_OS::thr_create() for descriptions of the
537 * possible flags values and their interactions.
539 * @param priority The priority at which the threads are spawned.
541 * @param grp_id The thread group that the spawned threads are
542 * added to. If -1 is specified, a new thread group is
543 * created for the spawned threads.
545 * @param task The ACE_Task that the spawned threads are associated
546 * with. If 0, the threads are not associated with an
547 * ACE_Task. This argument is usually assigned by the
548 * ACE_Task_Base::activate() method to associate the
549 * spawned threads with the spawning ACE_Task object.
551 * @param thread_handles An array of @a n entries which will receive
552 * the thread handles of the spawned threads.
554 * @param stack An array of @a n pointers to pre-allocated stack space
555 * for each thread's stack. If specified as 0, the
556 * platform allocates stack space for each thread. If
557 * a stack is specified, it is recommended that a
558 * @a stack_size element also be supplied that specifies
559 * the size of the stack.
560 * Not all platforms support pre-allocated stacks. If
561 * @a stack is specified for a platform which does not
562 * allow pre-allocated stack space this parameter is
563 * ignored.
565 * @param stack_size An array of @a n values which indicate how large
566 * each thread's stack should be, in bytes.
567 * If pre-allocated stacks are passed in @a stacks, these
568 * sizes are for those stacks. If no pre-allocated stacks
569 * are passed, the stack sizes are specified to the
570 * operating system to request that it allocate stacks
571 * of the specified sizes. If an array entry is 0, the
572 * platform defaults are used for the corresponding thread.
573 * If a 0 array pointer is specified, platform defaults
574 * are used for all thread stack sizes.
576 * @param thr_name An array of names to assign to the spawned threads.
577 * This is only meaningful for platforms that have a
578 * capacity to name threads (e.g., VxWorks and some
579 * varieties of Pthreads). This argument is ignored if
580 * specified as 0 and on platforms that do not have the
581 * capability to name threads.
583 * ACE_Thread_Manager can manipulate threads in groups based on
584 * @a grp_id or @a task using functions such as kill_grp() or
585 * cancel_task().
587 * @retval -1 on failure; @c errno contains an error value.
588 * @retval The group id of the threads.
590 int spawn_n (size_t n,
591 ACE_THR_FUNC func,
592 void *arg = 0,
593 long flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED,
594 long priority = ACE_DEFAULT_THREAD_PRIORITY,
595 int grp_id = -1,
596 ACE_Task_Base *task = 0,
597 ACE_hthread_t thread_handles[] = 0,
598 void *stack[] = 0,
599 size_t stack_size[] = 0,
600 const char* thr_name[] = 0);
603 * Spawn a specified number of threads, all of which execute @a func
604 * with argument @a arg.
606 * @param thread_ids An array to receive the thread IDs of successfully
607 * spawned buffer. If 0, the thread IDs are not returned.
608 * If specified, the array must be at least @a n entries.
610 * @param n The number of threads to spawn.
612 * @param func The function that is called in the spawned thread.
614 * @param arg The value passed to each spawned thread's @a func.
616 * @param flags Flags to control attributes of the spawned threads.
617 * @sa ACE_OS::thr_create() for descriptions of the
618 * possible flags values and their interactions.
620 * @param priority The priority at which the threads are spawned.
622 * @param grp_id The thread group that the spawned threads are
623 * added to. If -1 is specified, a new thread group is
624 * created for the spawned threads.
626 * @param stack An array of @a n pointers to pre-allocated stack space
627 * for each thread's stack. If specified as 0, the
628 * platform allocates stack space for each thread. If
629 * a stack is specified, it is recommended that a
630 * @a stack_size element also be supplied that specifies
631 * the size of the stack.
632 * Not all platforms support pre-allocated stacks. If
633 * @a stack is specified for a platform which does not
634 * allow pre-allocated stack space this parameter is
635 * ignored.
637 * @param stack_size An array of @a n values which indicate how large
638 * each thread's stack should be, in bytes.
639 * If pre-allocated stacks are passed in @a stacks, these
640 * sizes are for those stacks. If no pre-allocated stacks
641 * are passed, the stack sizes are specified to the
642 * operating system to request that it allocate stacks
643 * of the specified sizes. If an array entry is 0, the
644 * platform defaults are used for the corresponding thread.
645 * If a 0 array pointer is specified, platform defaults
646 * are used for all thread stack sizes.
648 * @param thread_handles An array of @a n entries which will receive
649 * the thread handles of the spawned threads.
651 * @param task The ACE_Task that the spawned threads are associated
652 * with. If 0, the threads are not associated with an
653 * ACE_Task. This argument is usually assigned by the
654 * ACE_Task_Base::activate() method to associate the
655 * spawned threads with the spawning ACE_Task object.
657 * @param thr_name An array of names to assign to the spawned threads.
658 * This is only meaningful for platforms that have a
659 * capacity to name threads (e.g., VxWorks and some
660 * varieties of Pthreads). This argument is ignored if
661 * specified as 0 and on platforms that do not have the
662 * capability to name threads.
664 * ACE_Thread_Manager can manipulate threads in groups based on
665 * @a grp_id or @a task using functions such as kill_grp() or
666 * cancel_task().
668 * @retval -1 on failure; @c errno contains an error value.
669 * @retval The group id of the threads.
672 int spawn_n (ACE_thread_t thread_ids[],
673 size_t n,
674 ACE_THR_FUNC func,
675 void *arg,
676 long flags,
677 long priority = ACE_DEFAULT_THREAD_PRIORITY,
678 int grp_id = -1,
679 void *stack[] = 0,
680 size_t stack_size[] = 0,
681 ACE_hthread_t thread_handles[] = 0,
682 ACE_Task_Base *task = 0,
683 const char* thr_name[] = 0);
686 * Called to clean up when a thread exits.
688 * @param do_thread_exit If non-0 then ACE_Thread::exit is called to
689 * exit the thread
690 * @param status If ACE_Thread_Exit is called, this is passed as
691 * the exit value of the thread.
692 * Should _not_ be called by main thread.
694 ACE_THR_FUNC_RETURN exit (ACE_THR_FUNC_RETURN status = 0,
695 bool do_thread_exit = true);
698 * Block until there are no more threads running in this thread
699 * manager or @c timeout expires.
701 * @param timeout is treated as "absolute" time by default, but this
702 * can be changed to "relative" time by setting the @c
703 * use_absolute_time to false.
704 * @param abandon_detached_threads If true, @c wait() will first
705 * check thru its thread list for
706 * threads with THR_DETACHED or
707 * THR_DAEMON flags set and remove
708 * these threads. Notice that
709 * unlike other @c wait_*() methods,
710 * by default, @c wait() does wait on
711 * all thread spawned by this
712 * thread manager no matter the detached
713 * flags are set or not unless it is
714 * called with @c
715 * abandon_detached_threads flag set.
716 * @param use_absolute_time If true then treat @c timeout as
717 * absolute time, else relative time.
718 * @return 0 on success * and -1 on failure.
720 * @note If this function is called while the @c
721 * ACE_Object_Manager is shutting down (as a result of program
722 * rundown via @c ACE::fini()), it will not wait for any threads to
723 * complete. If you must wait for threads spawned by this thread
724 * manager to complete and you are in a ACE rundown situation (such
725 * as your object is being destroyed by the @c ACE_Object_Manager)
726 * you can use @c wait_grp() instead.
728 int wait (const ACE_Time_Value *timeout = 0,
729 bool abandon_detached_threads = false,
730 bool use_absolute_time = true);
732 /// Join a thread specified by @a tid. Do not wait on a detached thread.
733 int join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status = 0);
736 * Block until there are no more threads running in a group.
737 * Returns 0 on success and -1 on failure. Notice that wait_grp
738 * will not wait on detached threads.
740 int wait_grp (int grp_id);
743 * Return the "real" handle to the calling thread, caching it if
744 * necessary in TSS to speed up subsequent lookups. This is
745 * necessary since on some platforms (e.g., Windows) we can't get this
746 * handle via direct method calls. Notice that you should *not*
747 * close the handle passed back from this method. It is used
748 * internally by Thread Manager. On the other hand, you *have to*
749 * use this internal thread handle when working on Thread_Manager.
750 * Return -1 if fail.
752 int thr_self (ACE_hthread_t &);
755 * Return the unique ID of the calling thread.
756 * Same as calling ACE_Thread::self().
758 ACE_thread_t thr_self (void);
761 * Returns a pointer to the current ACE_Task_Base we're executing
762 * in if this thread is indeed running in an ACE_Task_Base, else
763 * return 0.
765 ACE_Task_Base *task (void);
768 * @name Suspend and resume methods
770 * Suspend/resume is not supported on all platforms. For example, Pthreads
771 * does not support these functions.
773 //@{
775 /// Suspend all threads
776 int suspend_all (void);
778 /// Suspend a single thread.
779 int suspend (ACE_thread_t);
781 /// Suspend a group of threads.
782 int suspend_grp (int grp_id);
785 * True if @a t_id is inactive (i.e., suspended), else false. Always
786 * return false if @a t_id is not managed by the Thread_Manager.
788 int testsuspend (ACE_thread_t t_id);
790 /// Resume all stopped threads
791 int resume_all (void);
793 /// Resume a single thread.
794 int resume (ACE_thread_t);
796 /// Resume a group of threads.
797 int resume_grp (int grp_id);
800 * True if @a t_id is active (i.e., resumed), else false. Always
801 * return false if @a t_id is not managed by the Thread_Manager.
803 int testresume (ACE_thread_t t_id);
805 //@}
807 // = Send signals to one or more threads without blocking.
809 * Send @a signum to all stopped threads. Not supported on platforms
810 * that do not have advanced signal support, such as Win32.
812 int kill_all (int signum);
814 * Send the @a signum to a single thread. Not supported on platforms
815 * that do not have advanced signal support, such as Win32.
817 int kill (ACE_thread_t, int signum);
819 * Send @a signum to a group of threads, not supported on platforms
820 * that do not have advanced signal support, such as Win32.
822 int kill_grp (int grp_id, int signum);
824 // = Cancel methods, which provides a cooperative thread-termination mechanism (will not block).
826 * Cancel's all the threads.
828 int cancel_all (int async_cancel = 0);
831 * Cancel a single thread.
833 int cancel (ACE_thread_t, int async_cancel = 0);
836 * Cancel a group of threads.
838 int cancel_grp (int grp_id, int async_cancel = 0);
841 * True if @a t_id is cancelled, else false. Always return false if
842 * @a t_id is not managed by the Thread_Manager.
844 int testcancel (ACE_thread_t t_id);
847 * True if @a t_id has terminated (i.e., is no longer running),
848 * but the slot in the thread manager hasn't been reclaimed yet,
849 * else false. Always return false if @a t_id is not managed by the
850 * Thread_Manager.
852 int testterminate (ACE_thread_t t_id);
854 /// Set group ids for a particular thread id.
855 int set_grp (ACE_thread_t,
856 int grp_id);
858 /// Get group ids for a particular thread id.
859 int get_grp (ACE_thread_t,
860 int &grp_id);
863 * @name Task-related operations
865 //@{
867 * Block until there are no more threads running in a specified task.
868 * This method will not wait for either detached or daemon threads;
869 * the threads must have been spawned with the @c THR_JOINABLE flag.
870 * Upon successful completion, the threads have been joined, so further
871 * attempts to join with any of the waited-for threads will fail.
873 * @param task The ACE_Task_Base object whose threads are to waited for.
875 * @retval 0 Success.
876 * @retval -1 Failure (consult errno for further information).
878 int wait_task (ACE_Task_Base *task);
881 * Suspend all threads in an ACE_Task.
883 int suspend_task (ACE_Task_Base *task);
886 * Resume all threads in an ACE_Task.
888 int resume_task (ACE_Task_Base *task);
891 * Send a signal @a signum to all threads in an ACE_Task.
893 int kill_task (ACE_Task_Base *task, int signum);
896 * Cancel all threads in an ACE_Task. If <async_cancel> is non-0,
897 * then asynchronously cancel these threads if the OS platform
898 * supports cancellation. Otherwise, perform a "cooperative"
899 * cancellation.
901 int cancel_task (ACE_Task_Base *task, int async_cancel = 0);
903 //@}
905 // = Collect thread handles in the thread manager. Notice that
906 // the collected information is just a snapshot.
907 /// Check if the thread is managed by the thread manager. Return true if
908 /// the thread is found, false otherwise.
909 int hthread_within (ACE_hthread_t handle);
910 int thread_within (ACE_thread_t tid);
912 /// Returns the number of ACE_Task_Base in a group.
913 int num_tasks_in_group (int grp_id);
915 /// Returns the number of threads in an ACE_Task_Base.
916 int num_threads_in_task (ACE_Task_Base *task);
919 * Returns a list of ACE_Task_Base pointers corresponding to the tasks
920 * that have active threads in a specified thread group.
922 * @param grp_id The thread group ID to obtain task pointers for.
924 * @param task_list is a pointer to an array to receive the list of pointers.
925 * The caller is responsible for supplying an array with at
926 * least @arg n entries.
928 * @param n The maximum number of ACE_Task_Base pointers to write
929 * in @arg task_list.
931 * @retval If successful, the number of pointers returned, which will be
932 * no greater than @arg n. Returns -1 on error.
934 * @note This method has no way to indicate if there are more than
935 * @arg n ACE_Task_Base pointers available. Therefore, it may be
936 * wise to guess a larger value of @arg n than one thinks in cases
937 * where the exact number of tasks is not known.
939 * @sa num_tasks_in_group(), task_all_list()
941 ssize_t task_list (int grp_id,
942 ACE_Task_Base *task_list[],
943 size_t n);
946 * Returns in @a thread_list a list of up to @a n thread ids in an
947 * ACE_Task_Base. The caller must allocate the memory for
948 * @a thread_list. In case of an error, -1 is returned. If no
949 * requested values are found, 0 is returned, otherwise correct
950 * number of retrieved values are returned.
952 ssize_t thread_list (ACE_Task_Base *task,
953 ACE_thread_t thread_list[],
954 size_t n);
957 * Returns in @a hthread_list a list of up to @a n thread handles in
958 * an ACE_Task_Base. The caller must allocate memory for
959 * @a hthread_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 hthread_list (ACE_Task_Base *task,
964 ACE_hthread_t hthread_list[],
965 size_t n);
968 * Returns in @a thread_list a list of up to @a n thread ids in a
969 * group @a grp_id. The caller must allocate the memory for
970 * @a thread_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 thread_grp_list (int grp_id,
975 ACE_thread_t thread_list[],
976 size_t n);
979 * Returns in @a hthread_list a list of up to @a n thread handles in
980 * a group @a grp_id. The caller must allocate memory for
981 * @a hthread_list.
983 ssize_t hthread_grp_list (int grp_id,
984 ACE_hthread_t hthread_list[],
985 size_t n);
988 * Returns a list of ACE_Task_Base pointers corresponding to the tasks
989 * that have active threads managed by this instance.
991 * @param task_list is a pointer to an array to receive the list of pointers.
992 * The caller is responsible for supplying an array with at
993 * least @arg n entries.
995 * @param n The maximum number of ACE_Task_Base pointers to write
996 * in @arg task_list.
998 * @retval If successful, the number of pointers returned, which will be
999 * no greater than @arg n. Returns -1 on error.
1001 * @note This method has no way to indicate if there are more than
1002 * @arg n ACE_Task_Base pointers available. Therefore, it may be
1003 * wise to guess a larger value of @arg n than one thinks in cases
1004 * where the exact number of tasks is not known.
1006 * @sa count_threads()
1008 ssize_t task_all_list (ACE_Task_Base *task_list[],
1009 size_t n);
1012 * Returns in @a thread_list a list of up to @a n thread ids. The
1013 * caller must allocate the memory for @a thread_list. In case of an
1014 * error, -1 is returned. If no requested values are found, 0 is
1015 * returned, otherwise correct number of retrieved values are
1016 * returned.
1018 ssize_t thread_all_list (ACE_thread_t thread_list[],
1019 size_t n);
1021 /// Set group ids for a particular task.
1022 int set_grp (ACE_Task_Base *task, int grp_id);
1024 /// Get group ids for a particular task.
1025 int get_grp (ACE_Task_Base *task, int &grp_id);
1027 /// Return a count of the current number of threads active in the
1028 /// <Thread_Manager>.
1029 size_t count_threads (void) const;
1031 /// Get the state of the thread. Returns false if the thread is not
1032 /// managed by this thread manager.
1033 int thr_state (ACE_thread_t id, ACE_UINT32& state);
1036 * Register an At_Thread_Exit hook and the ownership is acquire by
1037 * Thread_Descriptor, this is the usual case when the AT is dynamically
1038 * allocated.
1040 int at_exit (ACE_At_Thread_Exit* cleanup);
1042 /// Register an At_Thread_Exit hook and the ownership is retained for the
1043 /// caller. Normally used when the at_exit hook is created in stack.
1044 int at_exit (ACE_At_Thread_Exit& cleanup);
1048 *****
1049 * @deprecated This function is deprecated. Please use the previous two
1050 * at_exit method. Notice that you should avoid mixing this method
1051 * with the previous two at_exit methods.
1052 *****
1054 * Register an object (or array) for cleanup at
1055 * thread termination. "cleanup_hook" points to a (global, or
1056 * static member) function that is called for the object or array
1057 * when it to be destroyed. It may perform any necessary cleanup
1058 * specific for that object or its class. "param" is passed as the
1059 * second parameter to the "cleanup_hook" function; the first
1060 * parameter is the object (or array) to be destroyed.
1061 * "cleanup_hook", for example, may delete the object (or array).
1062 * If <cleanup_hook> == 0, the <object> will _NOT_ get cleanup at
1063 * thread exit. You can use this to cancel the previously added
1064 * at_exit.
1066 int at_exit (void *object,
1067 ACE_CLEANUP_FUNC cleanup_hook,
1068 void *param);
1070 /// Access function to determine whether the Thread_Manager will
1071 /// wait for its thread to exit or not when being closing down.
1072 void wait_on_exit (int dowait);
1073 int wait_on_exit (void);
1075 /// Dump the state of an object.
1076 void dump (void);
1078 /// Declare the dynamic allocation hooks.
1079 ACE_ALLOC_HOOK_DECLARE;
1081 protected:
1082 // = Accessors for ACE_Thread_Descriptors.
1084 * Get a pointer to the calling thread's own thread_descriptor.
1085 * This must be called from a spawn thread. This function will
1086 * fetch the info from TSS.
1088 ACE_Thread_Descriptor *thread_desc_self (void);
1090 /// Return a pointer to the thread's Thread_Descriptor,
1091 /// 0 if fail.
1092 ACE_Thread_Descriptor *thread_descriptor (ACE_thread_t);
1094 /// Return a pointer to the thread's Thread_Descriptor,
1095 /// 0 if fail.
1096 ACE_Thread_Descriptor *hthread_descriptor (ACE_hthread_t);
1098 /// Create a new thread (must be called with locks held).
1099 int spawn_i (ACE_THR_FUNC func,
1100 void *arg,
1101 long flags,
1102 ACE_thread_t * = 0,
1103 ACE_hthread_t *t_handle = 0,
1104 long priority = ACE_DEFAULT_THREAD_PRIORITY,
1105 int grp_id = -1,
1106 void *stack = 0,
1107 size_t stack_size = 0,
1108 ACE_Task_Base *task = 0,
1109 const char** thr_name = 0);
1111 /// Run the registered hooks when the thread exits.
1112 void run_thread_exit_hooks (int i);
1114 /// Locate the index of the table slot occupied by <t_id>. Returns
1115 /// -1 if <t_id> is not in the table doesn't contain <t_id>.
1116 ACE_Thread_Descriptor *find_thread (ACE_thread_t t_id);
1118 /// Locate the index of the table slot occupied by <h_id>. Returns
1119 /// -1 if <h_id> is not in the table doesn't contain <h_id>.
1120 ACE_Thread_Descriptor *find_hthread (ACE_hthread_t h_id);
1123 * Locate the thread descriptor address of the list occupied by
1124 * @a task. Returns 0 if @a task is not in the table doesn't contain
1125 * @a task.
1127 ACE_Thread_Descriptor *find_task (ACE_Task_Base *task,
1128 size_t slot = 0);
1130 /// Insert a thread in the table (checks for duplicates).
1131 int insert_thr (ACE_thread_t t_id,
1132 ACE_hthread_t,
1133 int grp_id = -1,
1134 long flags = 0);
1136 /// Append a thread in the table (adds at the end, growing the table
1137 /// if necessary).
1138 int append_thr (ACE_thread_t t_id, ACE_hthread_t,
1139 ACE_UINT32,
1140 int grp_id,
1141 ACE_Task_Base *task = 0,
1142 long flags = 0,
1143 ACE_Thread_Descriptor *td = 0);
1145 /// Remove thread from the table.
1146 void remove_thr (ACE_Thread_Descriptor *td,
1147 int close_handler);
1149 /// Remove all threads from the table.
1150 void remove_thr_all (void);
1152 // = The following four methods implement a simple scheme for
1153 // operating on a collection of threads atomically.
1156 * Efficiently check whether @a thread is in a particular @a state.
1157 * This call updates the TSS cache if possible to speed up
1158 * subsequent searches.
1160 int check_state (ACE_UINT32 state,
1161 ACE_thread_t thread,
1162 int enable = 1);
1164 /// Apply @a func to all members of the table that match the @a task
1165 int apply_task (ACE_Task_Base *task,
1166 ACE_THR_MEMBER_FUNC func,
1167 int = 0);
1169 /// Apply @a func to all members of the table that match the @a grp_id.
1170 int apply_grp (int grp_id,
1171 ACE_THR_MEMBER_FUNC func,
1172 int arg = 0);
1174 /// Apply @a func to all members of the table.
1175 int apply_all (ACE_THR_MEMBER_FUNC,
1176 int = 0);
1178 /// Join the thread described in @a td.
1179 int join_thr (ACE_Thread_Descriptor *td,
1180 int = 0);
1182 /// Resume the thread described in @a td.
1183 int resume_thr (ACE_Thread_Descriptor *td,
1184 int = 0);
1186 /// Suspend the thread described in @a td.
1187 int suspend_thr (ACE_Thread_Descriptor *td,
1188 int = 0);
1190 /// Send signal @a signum to the thread described in @a td.
1191 int kill_thr (ACE_Thread_Descriptor *td,
1192 int signum);
1194 /// Set the cancellation flag for the thread described in @a td.
1195 int cancel_thr (ACE_Thread_Descriptor *td,
1196 int async_cancel = 0);
1198 /// Register a thread as terminated and put it into the <terminated_thr_list_>.
1199 int register_as_terminated (ACE_Thread_Descriptor *td);
1201 /// Setting the static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_ pointer.
1202 static int set_thr_exit (ACE_TSS_TYPE (ACE_Thread_Exit) *ptr);
1205 * Keeping a list of thread descriptors within the thread manager.
1206 * Double-linked list enables us to cache the entries in TSS
1207 * and adding/removing thread descriptor entries without
1208 * affecting other thread's descriptor entries.
1210 ACE_Double_Linked_List<ACE_Thread_Descriptor> thr_list_;
1212 #if !defined (ACE_HAS_VXTHREADS)
1213 /// Collect terminated but not yet joined thread entries.
1214 ACE_Double_Linked_List<ACE_Thread_Descriptor_Base> terminated_thr_list_;
1215 #endif /* !ACE_HAS_VXTHREADS */
1217 /// Collect pointers to thread descriptors of threads to be removed later.
1218 ACE_Unbounded_Queue<ACE_Thread_Descriptor*> thr_to_be_removed_;
1220 /// Keeps track of the next group id to assign.
1221 int grp_id_;
1223 /// Set if we want the Thread_Manager to wait on all threads before
1224 /// being closed, reset otherwise.
1225 int automatic_wait_;
1227 // = ACE_Thread_Mutex and condition variable for synchronizing termination.
1228 #if defined (ACE_HAS_THREADS)
1229 /// Serialize access to the <zero_cond_>.
1230 ACE_Thread_Mutex lock_;
1232 /// Keep track of when there are no more threads.
1233 ACE_Condition_Thread_Mutex zero_cond_;
1234 #endif /* ACE_HAS_THREADS */
1236 ACE_Locked_Free_List<ACE_Thread_Descriptor, ACE_SYNCH_MUTEX> thread_desc_freelist_;
1238 private:
1239 #if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
1240 /// Pointer to a process-wide ACE_Thread_Manager.
1241 static ACE_Thread_Manager *thr_mgr_;
1243 /// Must delete the thr_mgr_ if true.
1244 static bool delete_thr_mgr_;
1246 /// Global ACE_TSS (ACE_Thread_Exit) object ptr.
1247 static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_;
1248 #endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */
1251 #if defined (ACE_THREAD_MANAGER_LACKS_STATICS)
1252 #define ACE_THREAD_MANAGER_SINGLETON_DEFINE \
1253 ACE_Singleton<ACE_Thread_Manager, ACE_SYNCH_MUTEX>;
1254 typedef ACE_Singleton<ACE_Thread_Manager, ACE_SYNCH_MUTEX> ACE_THREAD_MANAGER_SINGLETON;
1255 #endif /* defined (ACE_THREAD_MANAGER_LACKS_STATICS) */
1257 ACE_END_VERSIONED_NAMESPACE_DECL
1259 #if defined (__ACE_INLINE__)
1260 #include "ace/Thread_Manager.inl"
1261 #endif /* __ACE_INLINE__ */
1263 #include /**/ "ace/post.h"
1264 #endif /* ACE_THREAD_MANAGER_H */