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)
virtual int close (u_long flags=0)
virtual int module_closed (void)
virtual int put (ACE_Message_Block *, ACE_Time_Value *=0)
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)
virtual int wait (void)
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

ACE_THR_FUNC_RETURN svc_run (void *)
 Routine that runs the service routine as a daemon thread.

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 to store *'s polymorphically.

Definition at line 66 of file Task.h.


Constructor & Destructor Documentation

ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_Task_Base::ACE_Task_Base ACE_Thread_Manager = 0  ) 
 

Constructor.

Definition at line 18 of file Task.cpp.

00019   : thr_count_ (0),
00020     thr_mgr_ (thr_man),
00021     flags_ (0),
00022     grp_id_ (-1),
00023     last_thread_id_ (0)
00024 {
00025 }

ACE_Task_Base::~ACE_Task_Base void   )  [virtual]
 

Destructor.

Definition at line 27 of file Task.cpp.

00028 {
00029 }

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
[virtual]
 

Turn the task into an active object, i.e., having of control, all running at the level (see below) with the same , all of which invoke <Task::svc>. Returns -1 if failure occurs, returns 1 if Task is already an active object and 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 is true. Note that if is true and there are already threads spawned in this , the parameter is ignored and the of any newly activated thread(s) will inherit the existing of the existing thread(s) in the .

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., ) 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 != 0 it is assumed to be an array of thread_handles that will be assigned the values of the thread handles being spawned. Returns -1 on failure ( will explain...), otherwise returns the group id of the threads.

Assigning allows you to associate the newly spawned threads with an instance of ACE_Task_Base. If == 0, then the new threads are associated automatically with ACE_Task_Base. Setting the argument to value other than makes the thread manipulating methods, such as wait(), suspend(), resume(), useless. Threads spawned with user specified value must therefore be manipulated thru ACE_Thread_Manager directly.

If != 0 it is assumed to be an array of pointers to the base of the stacks to use for the threads being spawned. Likewise, if != 0 it is assumed to be an array of values indicating how big each of the corresponding s are.

Reimplemented in ACE_Thread_Timer_Queue_Adapter< TQ >.

Definition at line 116 of file Task.cpp.

References ACE_GUARD_RETURN, ACE_hthread_t, ACE_NOTSUP_RETURN, ACE_TRACE, grp_id_, ACE_Thread_Manager::instance(), last_thread_id_, ACE_Thread_Manager::spawn_n(), svc_run(), and thr_count_.

Referenced by ACE_Proactor::ACE_Proactor(), ACE_Thread_Timer_Queue_Adapter< TQ >::activate(), and ACE_Asynch_Pseudo_Task::start().

00126 {
00127   ACE_TRACE ("ACE_Task_Base::activate");
00128 
00129 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00130   ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1);
00131 
00132   // If the task passed in is zero, we will use <this>
00133   if (task == 0)
00134     task = this;
00135 
00136   if (this->thr_count_ > 0 && force_active == 0)
00137     return 1; // Already active.
00138   else
00139     {
00140       if (this->thr_count_ > 0 && this->grp_id_ != -1)
00141         // If we're joining an existing group of threads then make
00142         // sure to use its group id.
00143         grp_id = this->grp_id_;
00144       this->thr_count_ += n_threads;
00145     }
00146 
00147   // Use the ACE_Thread_Manager singleton if we're running as an
00148   // active object and the caller didn't supply us with a
00149   // Thread_Manager.
00150   if (this->thr_mgr_ == 0)
00151 # if defined (ACE_THREAD_MANAGER_LACKS_STATICS)
00152     this->thr_mgr_ = ACE_THREAD_MANAGER_SINGLETON::instance ();
00153 # else /* ! ACE_THREAD_MANAGER_LACKS_STATICS */
00154     this->thr_mgr_ = ACE_Thread_Manager::instance ();
00155 # endif /* ACE_THREAD_MANAGER_LACKS_STATICS */
00156 
00157   int grp_spawned = -1;
00158   if (thread_ids == 0)
00159     // Thread Ids were not specified
00160     grp_spawned =
00161       this->thr_mgr_->spawn_n (n_threads,
00162                                &ACE_Task_Base::svc_run,
00163                                (void *) this,
00164                                flags,
00165                                priority,
00166                                grp_id,
00167                                task,
00168                                thread_handles,
00169                                stack,
00170                                stack_size);
00171   else
00172     // thread names were specified
00173     grp_spawned =
00174       this->thr_mgr_->spawn_n (thread_ids,
00175                                n_threads,
00176                                &ACE_Task_Base::svc_run,
00177                                (void *) this,
00178                                flags,
00179                                priority,
00180                                grp_id,
00181                                stack,
00182                                stack_size,
00183                                thread_handles,
00184                                task);
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   this->last_thread_id_ = 0;    // Reset to prevent inadvertant match on ID
00196 
00197   return 0;
00198 
00199 #else
00200   {
00201     // Keep the compiler from complaining.
00202     ACE_UNUSED_ARG (flags);
00203     ACE_UNUSED_ARG (n_threads);
00204     ACE_UNUSED_ARG (force_active);
00205     ACE_UNUSED_ARG (priority);
00206     ACE_UNUSED_ARG (grp_id);
00207     ACE_UNUSED_ARG (task);
00208     ACE_UNUSED_ARG (thread_handles);
00209     ACE_UNUSED_ARG (stack);
00210     ACE_UNUSED_ARG (stack_size);
00211     ACE_UNUSED_ARG (thread_ids);
00212     ACE_NOTSUP_RETURN (-1);
00213   }
00214 #endif /* ACE_MT_SAFE */
00215 }

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 218 of file Task.cpp.

References ACE_GUARD, close(), last_thread_id_, ACE_Thread::self(), and thr_count_.

Referenced by ACE_OS_Thread_Adapter::invoke(), ACE_Thread_Adapter::invoke_i(), and svc_run().

00219 {
00220   ACE_Task_Base *t = (ACE_Task_Base *) object;
00221 
00222   // The thread count must be decremented first in case the <close>
00223   // hook does something crazy like "delete this".
00224   {
00225     ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, t->lock_));
00226     t->thr_count_--;
00227     if (0 == t->thr_count_)
00228       t->last_thread_id_ = ACE_Thread::self ();
00229   }
00230 
00231   // @@ Is it possible to pass in the exit status somehow?
00232   t->close ();
00233   // t is undefined here. close() could have deleted it.
00234 }

int ACE_Task_Base::close u_long  flags = 0  )  [virtual]
 

Hook called from ACE_Thread_Exit when during thread exit and from the default implementation of . In general, this method shouldn't be called directly by an application, particularly if the is running as an Active Object. Instead, a special message should be passed into the via the method defined below, and the method should interpret this as a flag to shut down the .

Reimplemented in ACE_Stream_Head<>, ACE_Stream_Tail<>, ACE_Thru_Task<>, ACE_Svc_Handler<, >, and ACE_Svc_Handler< ACE_PEER_STREAM_2, ACE_SYNCH_USE >.

Definition at line 52 of file Task.cpp.

References ACE_TRACE.

Referenced by cleanup(), and module_closed().

00053 {
00054   ACE_TRACE ("ACE_Task_Base::close");
00055   return 0;
00056 }

ACE_INLINE void ACE_Task_Base::grp_id int   ) 
 

Set the current group id.

Definition at line 19 of file Task.inl.

References ACE_GUARD, ACE_TRACE, grp_id_, ACE_Thread_Manager::set_grp(), and thr_mgr().

00020 {
00021   ACE_TRACE ("ACE_Task_Base::grp_id");
00022   ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_));
00023 
00024   // Cache the group id in the task and then set it in the
00025   // Thread_Manager, if there is one.
00026   this->grp_id_ = identifier;
00027   if (this->thr_mgr ())
00028     this->thr_mgr ()->set_grp (this, identifier);
00029 }

ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE int ACE_Task_Base::grp_id void   )  const
 

Get the current group id.

Definition at line 9 of file Task.inl.

References ACE_GUARD_RETURN, ACE_TRACE, and grp_id_.

00010 {
00011   ACE_TRACE ("ACE_Task_Base::grp_id");
00012   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, const_cast <ACE_Thread_Mutex&>(this->lock_), -1));
00013   return this->grp_id_;
00014 }

ACE_INLINE int ACE_Task_Base::is_reader void   )  const
 

True if queue is a reader, else false.

Definition at line 46 of file Task.inl.

References ACE_BIT_ENABLED, and ACE_TRACE.

00047 {
00048   ACE_TRACE ("ACE_Task_Base::is_reader");
00049   return (ACE_BIT_ENABLED (this->flags_, ACE_Task_Flags::ACE_READER));
00050 }

ACE_INLINE int ACE_Task_Base::is_writer void   )  const
 

True if queue is a writer, else false.

Definition at line 53 of file Task.inl.

References ACE_BIT_DISABLED, and ACE_TRACE.

Referenced by ACE_Stream_Tail<>::put(), and ACE_Stream_Head<>::put().

00054 {
00055   ACE_TRACE ("ACE_Task_Base::is_writer");
00056   return (ACE_BIT_DISABLED (this->flags_, ACE_Task_Flags::ACE_READER));
00057 }

ACE_INLINE 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 71 of file Task.inl.

References ACE_TRACE, and last_thread_id_.

00072 {
00073   ACE_TRACE ("ACE_Task_Base::last_thread");
00074   return this->last_thread_id_;
00075 }

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 . This allows tasks to differ between the call has been originated from or from . Be aware that close(0) will be also called when a thread associated with the ACE_Task instance exits.

Definition at line 62 of file Task.cpp.

References close().

00063 {
00064   return this->close (1);
00065 }

int ACE_Task_Base::open void *  args = 0  )  [virtual]
 

Hook called to initialize a task and prepare it for execution. args can be used to pass arbitrary information into .

Reimplemented in ACE_NT_Service, ACE_Stream_Head<>, ACE_Stream_Tail<>, ACE_Thru_Task<>, ACE_Svc_Handler<, >, and ACE_Svc_Handler< ACE_PEER_STREAM_2, ACE_SYNCH_USE >.

Definition at line 43 of file Task.cpp.

References ACE_TRACE.

Referenced by ACE_Stream<>::insert(), ACE_Stream<>::push_module(), and ACE_Stream<>::replace().

00044 {
00045   ACE_TRACE ("ACE_Task_Base::open");
00046   return 0;
00047 }

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]
 

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

Reimplemented in ACE_Stream_Head<>, ACE_Stream_Tail<>, ACE_Thru_Task<>, and ACE_Buffered_Svc_Handler<, >.

Definition at line 70 of file Task.cpp.

References ACE_TRACE.

Referenced by ACE_Task< ACE_SYNCH_USE >::put_next().

00071 {
00072   ACE_TRACE ("ACE_Task_Base::put");
00073   return 0;
00074 }

int ACE_Task_Base::resume void   )  [virtual]
 

Resume a suspended task.

Reimplemented from ACE_Service_Object.

Definition at line 105 of file Task.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Thread_Manager::resume_task(), and thr_count_.

Referenced by ACE_NT_Service::continue_requested(), and ACE_Module_Type::resume().

00106 {
00107   ACE_TRACE ("ACE_Task_Base::resume");
00108   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00109   if (this->thr_count_ > 0)
00110     return this->thr_mgr_->resume_task (this);
00111 
00112   return 0;
00113 }

int ACE_Task_Base::suspend void   )  [virtual]
 

Suspend a task.

Reimplemented from ACE_Service_Object.

Definition at line 93 of file Task.cpp.

References ACE_GUARD_RETURN, ACE_TRACE, ACE_Thread_Manager::suspend_task(), and thr_count_.

Referenced by ACE_NT_Service::pause_requested(), and ACE_Module_Type::suspend().

00094 {
00095   ACE_TRACE ("ACE_Task_Base::suspend");
00096   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00097   if (this->thr_count_ > 0)
00098     return this->thr_mgr_->suspend_task (this);
00099 
00100   return 0;
00101 }

int ACE_Task_Base::svc void   )  [virtual]
 

Run by a daemon thread to handle deferred processing.

Reimplemented in ACE_Asynch_Pseudo_Task, ACE_NT_Service, ACE_Proactor_Timer_Handler, ACE_Stream_Head<>, ACE_Stream_Tail<>, ACE_Thru_Task<>, and ACE_Thread_Timer_Queue_Adapter< TQ >.

Definition at line 34 of file Task.cpp.

References ACE_TRACE.

Referenced by svc_run().

00035 {
00036   ACE_TRACE ("ACE_Task_Base::svc");
00037   return 0;
00038 }

ACE_THR_FUNC_RETURN ACE_Task_Base::svc_run void *   )  [static]
 

Routine that runs the service routine as a daemon thread.

Definition at line 246 of file Task.cpp.

References ACE_TRACE, ACE_Thread_Manager::at_exit(), cleanup(), svc(), and thr_mgr().

Referenced by activate().

00247 {
00248   ACE_TRACE ("ACE_Task_Base::svc_run");
00249 
00250   ACE_Task_Base *t = (ACE_Task_Base *) args;
00251 
00252   // Register ourself with our <Thread_Manager>'s thread exit hook
00253   // mechanism so that our close() hook will be sure to get invoked
00254   // when this thread exits.
00255 
00256 #if defined ACE_HAS_SIG_C_FUNC
00257   t->thr_mgr ()->at_exit (t, ACE_Task_Base_cleanup, 0);
00258 #else
00259   t->thr_mgr ()->at_exit (t, ACE_Task_Base::cleanup, 0);
00260 #endif /* ACE_HAS_SIG_C_FUNC */
00261 
00262   // Call the Task's svc() hook method.
00263   int svc_status = t->svc ();
00264   ACE_THR_FUNC_RETURN status;
00265 #if (defined (__BORLANDC__) && (__BORLANDC__ < 0x600)) || defined (__MINGW32__) || (defined (_MSC_VER) && (_MSC_VER <= 1400)) || (defined (ACE_WIN32) && defined(__IBMCPP__) || defined (__DCC__))
00266   // Some compilers complain about reinterpret_cast from int to unsigned long...
00267   status = static_cast<ACE_THR_FUNC_RETURN> (svc_status);
00268 #else
00269   status = reinterpret_cast<ACE_THR_FUNC_RETURN> (svc_status);
00270 #endif /* (__BORLANDC__ < 0x600) || __MINGW32__ || _MSC_VER <= 1400 || __IBMCPP__ */
00271 
00272 // If we changed this zero change the other if in OS.cpp Thread_Adapter::invoke
00273 #if 1
00274   // Call the <Task->close> hook.
00275   ACE_Thread_Manager *thr_mgr_ptr = t->thr_mgr ();
00276 
00277   // This calls the Task->close () hook.
00278   t->cleanup (t, 0);
00279 
00280   // This prevents a second invocation of the cleanup code
00281   // (called later by <ACE_Thread_Manager::exit>.
00282   thr_mgr_ptr->at_exit (t, 0, 0);
00283 #endif
00284   return status;
00285 }

ACE_INLINE 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 61 of file Task.inl.

References ACE_GUARD_RETURN, ACE_TRACE, and thr_count_.

Referenced by ACE_Asynch_Pseudo_Task::stop().

00062 {
00063   ACE_TRACE ("ACE_Task_Base::thr_count");
00064   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, const_cast <ACE_Thread_Mutex&>(this->lock_), 0));
00065 
00066   return this->thr_count_;
00067 }

ACE_INLINE void ACE_Task_Base::thr_mgr ACE_Thread_Manager  ) 
 

Set the thread manager associated with this Task.

Definition at line 39 of file Task.inl.

References ACE_TRACE.

00040 {
00041   ACE_TRACE ("ACE_Task_Base::thr_mgr");
00042   this->thr_mgr_ = thr_mgr;
00043 }

ACE_INLINE ACE_Thread_Manager * ACE_Task_Base::thr_mgr void   )  const
 

Get the thread manager associated with this Task.

Definition at line 32 of file Task.inl.

References ACE_TRACE.

Referenced by grp_id(), ACE_OS_Thread_Adapter::invoke(), ACE_Thread_Adapter::invoke_i(), svc_run(), wait(), and ACE_Proactor_Timer_Handler::~ACE_Proactor_Timer_Handler().

00033 {
00034   ACE_TRACE ("ACE_Task_Base::thr_mgr");
00035   return this->thr_mgr_;
00036 }

int ACE_Task_Base::wait void   )  [virtual]
 

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 79 of file Task.cpp.

References ACE_TRACE, thr_mgr(), and ACE_Thread_Manager::wait_task().

Referenced by ACE_Asynch_Pseudo_Task::stop().

00080 {
00081   ACE_TRACE ("ACE_Task_Base::wait");
00082 
00083   // If we don't have a thread manager, we probably were never
00084   // activated.
00085   if (this->thr_mgr () != 0)
00086     return this->thr_mgr ()->wait_task (this);
00087   else
00088     return 0;
00089 }


Member Data Documentation

u_long ACE_Task_Base::flags_ [protected]
 

ACE_Task flags.

Definition at line 275 of file Task.h.

int ACE_Task_Base::grp_id_ [protected]
 

This maintains the group id of the Task.

Definition at line 278 of file Task.h.

Referenced by activate(), and grp_id().

ACE_thread_t ACE_Task_Base::last_thread_id_ [protected]
 

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

Definition at line 287 of file Task.h.

Referenced by activate(), cleanup(), and last_thread().

size_t ACE_Task_Base::thr_count_ [protected]
 

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 is the number of active threads at this instant. If the value == 0, then we're a passive object.

Definition at line 269 of file Task.h.

Referenced by activate(), cleanup(), resume(), suspend(), and thr_count().

ACE_Thread_Manager* ACE_Task_Base::thr_mgr_ [protected]
 

Multi-threading manager.

Definition at line 272 of file Task.h.


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 11:30:43 2006 for ACE by doxygen 1.3.6