Direct base class for the ACE_Task template. More...
#include <Task.h>
Public Member Functions | |
ACE_Task_Base (ACE_Thread_Manager *=0) | |
Constructor. | |
virtual | ~ACE_Task_Base (void) |
Destructor. | |
virtual int | open (void *args=0) |
Default ACE_Task open routine. | |
virtual int | close (u_long flags=0) |
Default ACE_Task close routine. | |
virtual int | module_closed (void) |
virtual int | put (ACE_Message_Block *, ACE_Time_Value *=0) |
Default ACE_Task put routine. | |
virtual int | svc (void) |
Run by a daemon thread to handle deferred processing. | |
virtual int | activate (long flags=THR_NEW_LWP|THR_JOINABLE|THR_INHERIT_SCHED, int n_threads=1, int force_active=0, long priority=ACE_DEFAULT_THREAD_PRIORITY, int grp_id=-1, ACE_Task_Base *task=0, ACE_hthread_t thread_handles[]=0, void *stack[]=0, size_t stack_size[]=0, ACE_thread_t thread_ids[]=0, const char *thr_name[]=0) |
virtual int | wait (void) |
Wait for all threads running in a task to exit. | |
virtual int | suspend (void) |
Suspend a task. | |
virtual int | resume (void) |
Resume a suspended task. | |
int | grp_id (void) const |
Get the current group id. | |
void | grp_id (int) |
Set the current group id. | |
ACE_Thread_Manager * | thr_mgr (void) const |
Get the thread manager associated with this Task. | |
void | thr_mgr (ACE_Thread_Manager *) |
Set the thread manager associated with this Task. | |
int | is_reader (void) const |
True if queue is a reader, else false. | |
int | is_writer (void) const |
True if queue is a writer, else false. | |
size_t | thr_count (void) const |
ACE_thread_t | last_thread (void) const |
Static Public Member Functions | |
static ACE_THR_FUNC_RETURN | svc_run (void *) |
Routine that runs the service routine as a daemon thread. | |
static void | cleanup (void *object, void *params) |
Protected Attributes | |
size_t | thr_count_ |
ACE_Thread_Manager * | thr_mgr_ |
Multi-threading manager. | |
u_long | flags_ |
ACE_Task flags. | |
int | grp_id_ |
This maintains the group id of the Task. | |
ACE_thread_t | last_thread_id_ |
Holds the thread ID of the last thread to exit svc() in this object. | |
Private Member Functions | |
ACE_Task_Base & | operator= (const ACE_Task_Base &) |
ACE_Task_Base (const ACE_Task_Base &) |
Direct base class for the ACE_Task template.
This class factors out the non-template code in order to reduce template bloat, as well as to make it possible for the ACE_Thread_Manager to store ACE_Task_Base *'s polymorphically.
Definition at line 64 of file Task.h.
ACE_Task_Base::ACE_Task_Base | ( | ACE_Thread_Manager * | thr_man = 0 |
) |
Constructor.
Definition at line 12 of file Task.cpp.
00013 : thr_count_ (0), 00014 thr_mgr_ (thr_man), 00015 flags_ (0), 00016 grp_id_ (-1) 00017 #if !(defined (ACE_TANDEM_T1248_PTHREADS) || defined (ACE_THREAD_T_IS_A_STRUCT)) 00018 ,last_thread_id_ (0) 00019 #endif /* ! ACE_TANDEM_T1248_PTHREADS || ACE_THREAD_T_IS_A_STRUCT */ 00020 { 00021 #if defined (ACE_TANDEM_T1248_PTHREADS) || defined (ACE_THREAD_T_IS_A_STRUCT) 00022 ACE_OS::memset( &this->last_thread_id_, '\0', sizeof( this->last_thread_id_ )); 00023 #endif /* ACE_TANDEM_T1248_PTHREADS || ACE_THREAD_T_IS_A_STRUCT */ 00024 }
ACE_Task_Base::~ACE_Task_Base | ( | void | ) | [virtual] |
ACE_Task_Base::ACE_Task_Base | ( | const ACE_Task_Base & | ) | [private] |
int ACE_Task_Base::activate | ( | long | flags = THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED , |
|
int | n_threads = 1 , |
|||
int | force_active = 0 , |
|||
long | priority = ACE_DEFAULT_THREAD_PRIORITY , |
|||
int | grp_id = -1 , |
|||
ACE_Task_Base * | task = 0 , |
|||
ACE_hthread_t | thread_handles[] = 0 , |
|||
void * | stack[] = 0 , |
|||
size_t | stack_size[] = 0 , |
|||
ACE_thread_t | thread_ids[] = 0 , |
|||
const char * | thr_name[] = 0 | |||
) | [virtual] |
Turn the task into an active object, i.e., having n_threads of control, all running at the priority level (see below) with the same grp_id, all of which invoke <Task::svc>. Returns -1 if failure occurs, returns 1 if Task is already an active object and force_active is false (i.e., do *not* create a new thread in this case), and returns 0 if Task was not already an active object and a thread is created successfully or thread is an active object and force_active is true. Note that if force_active is true and there are already threads spawned in this <Task>, the grp_id parameter is ignored and the grp_id of any newly activated thread(s) will inherit the existing grp_id of the existing thread(s) in the <Task>.
The <{flags}> are a bitwise-OR of the following: = BEGIN<INDENT> THR_CANCEL_DISABLE, THR_CANCEL_ENABLE, THR_CANCEL_DEFERRED, THR_CANCEL_ASYNCHRONOUS, THR_BOUND, THR_NEW_LWP, THR_DETACHED, THR_SUSPENDED, THR_DAEMON, THR_JOINABLE, THR_SCHED_FIFO, THR_SCHED_RR, THR_SCHED_DEFAULT, THR_EXPLICIT_SCHED, THR_SCOPE_SYSTEM, THR_SCOPE_PROCESS = END<INDENT> If THR_SCHED_INHERIT is not desirable, applications should specifically pass in THR_EXPLICIT_SCHED.
By default, or if <{priority}> is set to ACE_DEFAULT_THREAD_PRIORITY, an "appropriate" priority value for the given scheduling policy (specified in <{flags}>, e.g., <THR_SCHED_DEFAULT>) is used. This value is calculated dynamically, and is the median value between the minimum and maximum priority values for the given policy. If an explicit value is given, it is used. Note that actual priority values are EXTREMEMLY implementation-dependent, and are probably best avoided.
If thread_handles != 0 it is assumed to be an array of n thread_handles that will be assigned the values of the thread handles being spawned. Returns -1 on failure (errno
will explain...), otherwise returns the group id of the threads.
Assigning task allows you to associate the newly spawned threads with an instance of ACE_Task_Base. If task == 0, then the new threads are associated automatically with this
ACE_Task_Base. Setting the task argument to value other than this
makes the thread manipulating methods, such as wait(), suspend(), resume(), useless. Threads spawned with user specified task value must therefore be manipulated thru ACE_Thread_Manager directly.
If stack != 0 it is assumed to be an array of n pointers to the base of the stacks to use for the threads being spawned. Likewise, if stack_size != 0 it is assumed to be an array of n values indicating how big each of the corresponding stacks are.
Definition at line 109 of file Task.cpp.
00120 { 00121 ACE_TRACE ("ACE_Task_Base::activate"); 00122 00123 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) 00124 ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); 00125 00126 // If the task passed in is zero, we will use <this> 00127 if (task == 0) 00128 task = this; 00129 00130 if (this->thr_count_ > 0 && force_active == 0) 00131 return 1; // Already active. 00132 else 00133 { 00134 if ((this->thr_count_ > 0 || grp_id == -1) && 00135 this->grp_id_ != -1) 00136 // If we're joining an existing group of threads then make 00137 // sure to (re)use its group id. 00138 grp_id = this->grp_id_; 00139 else if (grp_id != -1) 00140 // make sure to reset the cached grp_id 00141 this->grp_id_ = -1; 00142 this->thr_count_ += n_threads; 00143 } 00144 00145 // Use the ACE_Thread_Manager singleton if we're running as an 00146 // active object and the caller didn't supply us with a 00147 // Thread_Manager. 00148 if (this->thr_mgr_ == 0) 00149 # if defined (ACE_THREAD_MANAGER_LACKS_STATICS) 00150 this->thr_mgr_ = ACE_THREAD_MANAGER_SINGLETON::instance (); 00151 # else /* ! ACE_THREAD_MANAGER_LACKS_STATICS */ 00152 this->thr_mgr_ = ACE_Thread_Manager::instance (); 00153 # endif /* ACE_THREAD_MANAGER_LACKS_STATICS */ 00154 00155 int grp_spawned = -1; 00156 if (thread_ids == 0) 00157 // Thread Ids were not specified 00158 grp_spawned = 00159 this->thr_mgr_->spawn_n (n_threads, 00160 &ACE_Task_Base::svc_run, 00161 (void *) this, 00162 flags, 00163 priority, 00164 grp_id, 00165 task, 00166 thread_handles, 00167 stack, 00168 stack_size, 00169 thr_name); 00170 else 00171 // thread names were specified 00172 grp_spawned = 00173 this->thr_mgr_->spawn_n (thread_ids, 00174 n_threads, 00175 &ACE_Task_Base::svc_run, 00176 (void *) this, 00177 flags, 00178 priority, 00179 grp_id, 00180 stack, 00181 stack_size, 00182 thread_handles, 00183 task, 00184 thr_name); 00185 if (grp_spawned == -1) 00186 { 00187 // If spawn_n fails, restore original thread count. 00188 this->thr_count_ -= n_threads; 00189 return -1; 00190 } 00191 00192 if (this->grp_id_ == -1) 00193 this->grp_id_ = grp_spawned; 00194 00195 #if defined(ACE_TANDEM_T1248_PTHREADS) || defined (ACE_THREAD_T_IS_A_STRUCT) 00196 ACE_OS::memcpy( &this->last_thread_id_, '\0', sizeof(this->last_thread_id_)); 00197 #else 00198 this->last_thread_id_ = 0; // Reset to prevent inadvertant match on ID 00199 #endif /* ACE_TANDEM_T1248_PTHREADS || ACE_THREAD_T_IS_A_STRUCT */ 00200 00201 return 0; 00202 00203 #else 00204 { 00205 // Keep the compiler from complaining. 00206 ACE_UNUSED_ARG (flags); 00207 ACE_UNUSED_ARG (n_threads); 00208 ACE_UNUSED_ARG (force_active); 00209 ACE_UNUSED_ARG (priority); 00210 ACE_UNUSED_ARG (grp_id); 00211 ACE_UNUSED_ARG (task); 00212 ACE_UNUSED_ARG (thread_handles); 00213 ACE_UNUSED_ARG (stack); 00214 ACE_UNUSED_ARG (stack_size); 00215 ACE_UNUSED_ARG (thread_ids); 00216 ACE_UNUSED_ARG (thr_name); 00217 ACE_NOTSUP_RETURN (-1); 00218 } 00219 #endif /* ACE_MT_SAFE */ 00220 }
void ACE_Task_Base::cleanup | ( | void * | object, | |
void * | params | |||
) | [static] |
Cleanup hook that is called when a thread exits to gracefully shutdown an ACE_Task.
Definition at line 223 of file Task.cpp.
00224 { 00225 ACE_Task_Base *t = (ACE_Task_Base *) object; 00226 00227 // The thread count must be decremented first in case the <close> 00228 // hook does something crazy like "delete this". 00229 { 00230 ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, t->lock_)); 00231 t->thr_count_--; 00232 if (0 == t->thr_count_) 00233 t->last_thread_id_ = ACE_Thread::self (); 00234 } 00235 00236 // @@ Is it possible to pass in the exit status somehow? 00237 t->close (); 00238 // t is undefined here. close() could have deleted it. 00239 }
int ACE_Task_Base::close | ( | u_long | flags = 0 |
) | [virtual] |
Default ACE_Task close routine.
Hook called from ACE_Thread_Exit when during thread exit and from the default implementation of module_closed()
. In general, this method shouldn't be called directly by an application, particularly if the Task is running as an Active Object. Instead, a special message should be passed into the Task via the put() method defined below, and the svc() method should interpret this as a flag to shut down the Task.
Reimplemented in ACE_Stream_Head< ACE_SYNCH_DECL, TIME_POLICY >, ACE_Stream_Tail< ACE_SYNCH_DECL, TIME_POLICY >, ACE_Thru_Task< ACE_SYNCH_DECL, TIME_POLICY >, and ACE_Svc_Handler< PEER_STREAM, SYNCH_TRAITS >.
void ACE_Task_Base::grp_id | ( | int | identifier | ) |
Set the current group id.
Definition at line 15 of file Task.inl.
00016 { 00017 ACE_TRACE ("ACE_Task_Base::grp_id"); 00018 ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_)); 00019 00020 // Cache the group id in the task and then set it in the 00021 // Thread_Manager, if there is one. 00022 this->grp_id_ = identifier; 00023 if (this->thr_mgr ()) 00024 this->thr_mgr ()->set_grp (this, identifier); 00025 }
int ACE_Task_Base::grp_id | ( | void | ) | const |
int ACE_Task_Base::is_reader | ( | void | ) | const |
True if queue is a reader, else false.
Definition at line 42 of file Task.inl.
00043 { 00044 ACE_TRACE ("ACE_Task_Base::is_reader"); 00045 return (ACE_BIT_ENABLED (this->flags_, ACE_Task_Flags::ACE_READER)); 00046 }
int ACE_Task_Base::is_writer | ( | void | ) | const |
True if queue is a writer, else false.
Definition at line 49 of file Task.inl.
00050 { 00051 ACE_TRACE ("ACE_Task_Base::is_writer"); 00052 return (ACE_BIT_DISABLED (this->flags_, ACE_Task_Flags::ACE_READER)); 00053 }
ACE_thread_t ACE_Task_Base::last_thread | ( | void | ) | const |
Returns the thread ID of the thread whose exit caused this object's thread count to be decremented to 0.
When a thread spawned in the context of this object (using activate()) returns from its svc() method ACE calls the close() hook. Before it does so, it decrements the number of active threads. If the number of threads is decremented to 0, the thread ID of the current thread is stored for access by this method. If the returned thread ID matches the calling thread's ID, the calling thread knows that there are no other threads still active in the ACE_Task.
ACE_thread_t | of the last thread to close. 0 if the last thread is not yet known; for example, if no threads are active, or if multiple threads are active. |
Definition at line 67 of file Task.inl.
00068 { 00069 ACE_TRACE ("ACE_Task_Base::last_thread"); 00070 return this->last_thread_id_; 00071 }
int ACE_Task_Base::module_closed | ( | void | ) | [virtual] |
Hook called during ACE_Module::close(). The default implementation calls forwards the call to close(1). Please notice the changed value of the default argument of close(). This allows tasks to differ between the call has been originated from ACE_Thread_Exit or from module_closed(). Be aware that close(0) will be also called when a thread associated with the ACE_Task instance exits.
Forward the call to close() so that existing applications don't break.
Definition at line 57 of file Task.cpp.
00058 { 00059 return this->close (1); 00060 }
int ACE_Task_Base::open | ( | void * | args = 0 |
) | [virtual] |
Default ACE_Task open routine.
Hook called to initialize a task and prepare it for execution. args can be used to pass arbitrary information into <open>.
Reimplemented in ACE_NT_Service, ACE_Stream_Head< ACE_SYNCH_DECL, TIME_POLICY >, ACE_Stream_Tail< ACE_SYNCH_DECL, TIME_POLICY >, ACE_Thru_Task< ACE_SYNCH_DECL, TIME_POLICY >, and ACE_Svc_Handler< PEER_STREAM, SYNCH_TRAITS >.
ACE_Task_Base& ACE_Task_Base::operator= | ( | const ACE_Task_Base & | ) | [private] |
int ACE_Task_Base::put | ( | ACE_Message_Block * | , | |
ACE_Time_Value * | = 0 | |||
) | [virtual] |
Default ACE_Task put routine.
A hook method that can be used to pass a message to a task, where it can be processed immediately or queued for subsequent processing in the svc() hook method.
Reimplemented in ACE_Stream_Head< ACE_SYNCH_DECL, TIME_POLICY >, ACE_Stream_Tail< ACE_SYNCH_DECL, TIME_POLICY >, ACE_Thru_Task< ACE_SYNCH_DECL, TIME_POLICY >, and ACE_Buffered_Svc_Handler< PEER_STREAM, SYNCH_TRAITS >.
int ACE_Task_Base::resume | ( | void | ) | [virtual] |
Resume a suspended task.
Reimplemented from ACE_Service_Object.
Definition at line 98 of file Task.cpp.
00099 { 00100 ACE_TRACE ("ACE_Task_Base::resume"); 00101 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); 00102 if (this->thr_count_ > 0) 00103 return this->thr_mgr_->resume_task (this); 00104 00105 return 0; 00106 }
int ACE_Task_Base::suspend | ( | void | ) | [virtual] |
Suspend a task.
Reimplemented from ACE_Service_Object.
Definition at line 86 of file Task.cpp.
00087 { 00088 ACE_TRACE ("ACE_Task_Base::suspend"); 00089 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); 00090 if (this->thr_count_ > 0) 00091 return this->thr_mgr_->suspend_task (this); 00092 00093 return 0; 00094 }
int ACE_Task_Base::svc | ( | void | ) | [virtual] |
Run by a daemon thread to handle deferred processing.
Default ACE_Task service routine.
Reimplemented in ACE_Asynch_Pseudo_Task, ACE_NT_Service, ACE_Proactor_Timer_Handler, ACE_Stream_Head< ACE_SYNCH_DECL, TIME_POLICY >, ACE_Stream_Tail< ACE_SYNCH_DECL, TIME_POLICY >, ACE_Thru_Task< ACE_SYNCH_DECL, TIME_POLICY >, and ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >.
ACE_THR_FUNC_RETURN ACE_Task_Base::svc_run | ( | void * | args | ) | [static] |
Routine that runs the service routine as a daemon thread.
Definition at line 251 of file Task.cpp.
00252 { 00253 ACE_TRACE ("ACE_Task_Base::svc_run"); 00254 00255 ACE_Task_Base *t = (ACE_Task_Base *) args; 00256 00257 // Register ourself with our <Thread_Manager>'s thread exit hook 00258 // mechanism so that our close() hook will be sure to get invoked 00259 // when this thread exits. 00260 00261 #if defined ACE_HAS_SIG_C_FUNC 00262 t->thr_mgr ()->at_exit (t, ACE_Task_Base_cleanup, 0); 00263 #else 00264 t->thr_mgr ()->at_exit (t, ACE_Task_Base::cleanup, 0); 00265 #endif /* ACE_HAS_SIG_C_FUNC */ 00266 00267 ACE_THR_FUNC_RETURN status; 00268 // Call the Task's svc() hook method. 00269 int const svc_status = t->svc (); 00270 00271 #if defined (ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN) 00272 // Reinterpret case between integral types is not mentioned in the C++ spec 00273 status = static_cast<ACE_THR_FUNC_RETURN> (svc_status); 00274 #else 00275 status = reinterpret_cast<ACE_THR_FUNC_RETURN> (svc_status); 00276 #endif /* ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN */ 00277 00278 // If we changed this zero change the other if in OS.cpp Thread_Adapter::invoke 00279 #if 1 00280 // Call the <Task->close> hook. 00281 ACE_Thread_Manager *thr_mgr_ptr = t->thr_mgr (); 00282 00283 // This calls the Task->close () hook. 00284 t->cleanup (t, 0); 00285 00286 // This prevents a second invocation of the cleanup code 00287 // (called later by <ACE_Thread_Manager::exit>. 00288 thr_mgr_ptr->at_exit (t, 0, 0); 00289 #endif 00290 return status; 00291 }
size_t ACE_Task_Base::thr_count | ( | void | ) | const |
Returns the number of threads currently running within a task. If we're a passive object this value is 0, else it's greater than 0.
Definition at line 57 of file Task.inl.
00058 { 00059 ACE_TRACE ("ACE_Task_Base::thr_count"); 00060 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); 00061 00062 return this->thr_count_; 00063 }
void ACE_Task_Base::thr_mgr | ( | ACE_Thread_Manager * | thr_mgr | ) |
ACE_Thread_Manager * ACE_Task_Base::thr_mgr | ( | void | ) | const |
int ACE_Task_Base::wait | ( | void | ) | [virtual] |
Wait for all threads running in a task to exit.
Block until there are no more threads running in this task. This method will not wait for either detached or daemon threads; the threads must have been spawned with the THR_JOINABLE
flag. Upon successful completion, the threads have been joined, so further attempts to join with any of the waited-for threads will fail.
0 | Success. | |
-1 | Failure (consult errno for further information). |
u_long ACE_Task_Base::flags_ [protected] |
int ACE_Task_Base::grp_id_ [protected] |
ACE_thread_t ACE_Task_Base::last_thread_id_ [protected] |
size_t ACE_Task_Base::thr_count_ [protected] |
ACE_Thread_Manager* ACE_Task_Base::thr_mgr_ [protected] |