ACE_Task_Base Class Reference

Direct base class for the ACE_Task template. More...

#include <Task.h>

Inheritance diagram for ACE_Task_Base:
Inheritance graph
[legend]
Collaboration diagram for ACE_Task_Base:
Collaboration graph
[legend]

List of all members.

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_Managerthr_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_Managerthr_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_Baseoperator= (const ACE_Task_Base &)
 ACE_Task_Base (const ACE_Task_Base &)

Detailed Description

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.


Constructor & Destructor Documentation

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]

Destructor.

Definition at line 26 of file Task.cpp.

00027 {
00028 }

ACE_Task_Base::ACE_Task_Base ( const ACE_Task_Base  )  [private]

Member Function Documentation

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 >.

Definition at line 48 of file Task.cpp.

00049 {
00050   ACE_TRACE ("ACE_Task_Base::close");
00051   return 0;
00052 }

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

Get the current group id.

Definition at line 6 of file Task.inl.

00007 {
00008   ACE_TRACE ("ACE_Task_Base::grp_id");
00009   return this->grp_id_;
00010 }

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.

Return values:
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 >.

Definition at line 40 of file Task.cpp.

00041 {
00042   ACE_TRACE ("ACE_Task_Base::open");
00043   return 0;
00044 }

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 >.

Definition at line 64 of file Task.cpp.

00065 {
00066   ACE_TRACE ("ACE_Task_Base::put");
00067   return 0;
00068 }

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 >.

Definition at line 32 of file Task.cpp.

00033 {
00034   ACE_TRACE ("ACE_Task_Base::svc");
00035   return 0;
00036 }

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  ) 

Set the thread manager associated with this Task.

Definition at line 35 of file Task.inl.

00036 {
00037   ACE_TRACE ("ACE_Task_Base::thr_mgr");
00038   this->thr_mgr_ = thr_mgr;
00039 }

ACE_Thread_Manager * ACE_Task_Base::thr_mgr ( void   )  const

Get the thread manager associated with this Task.

Definition at line 28 of file Task.inl.

00029 {
00030   ACE_TRACE ("ACE_Task_Base::thr_mgr");
00031   return this->thr_mgr_;
00032 }

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.

Return values:
0 Success.
-1 Failure (consult errno for further information).

Definition at line 72 of file Task.cpp.

00073 {
00074   ACE_TRACE ("ACE_Task_Base::wait");
00075 
00076   // If we don't have a thread manager, we probably were never
00077   // activated.
00078   if (this->thr_mgr () != 0)
00079     return this->thr_mgr ()->wait_task (this);
00080   else
00081     return 0;
00082 }


Member Data Documentation

ACE_Task flags.

Definition at line 274 of file Task.h.

int ACE_Task_Base::grp_id_ [protected]

This maintains the group id of the Task.

Definition at line 277 of file Task.h.

Holds the thread ID of the last thread to exit svc() in this object.

Definition at line 286 of file Task.h.

Count of the number of threads running within the task. If this value is greater than 0 then we're an active object and the value of <thr_count_> is the number of active threads at this instant. If the value == 0, then we're a passive object.

Definition at line 268 of file Task.h.

Multi-threading manager.

Definition at line 271 of file Task.h.


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

Generated on 10 Aug 2018 for ACE by  doxygen 1.6.1