Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Task.h

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Task.h
00006  *
00007  *  $Id: Task.h,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $
00008  *
00009  *  @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
00010  */
00011 //=============================================================================
00012 
00013 #ifndef ACE_TASK_H
00014 #define ACE_TASK_H
00015 #include "ace/pre.h"
00016 
00017 #include "ace/Service_Object.h"
00018 
00019 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00020 # pragma once
00021 #endif /* ACE_LACKS_PRAGMA_ONCE */
00022 
00023 #include "ace/Thread_Manager.h"
00024 
00025 /**
00026  * @class ACE_Task_Flags
00027  *
00028  * @brief These flags are used within the ACE_Task.
00029  *
00030  *    These flags should be hidden within ACE_Task.  Unfortunately, the
00031  *    HP/UX C++ compiler can't grok this...  Fortunately, there's no
00032  *    code defined here, so we don't have to worry about multiple
00033  *    definitions.
00034  */
00035 class ACE_Export ACE_Task_Flags
00036 {
00037 public:
00038   enum
00039   {
00040     /// Identifies a Task as being the "reader" in a Module.
00041     ACE_READER     = 01,
00042     /// Just flush data messages in the queue.
00043     ACE_FLUSHDATA  = 02,
00044     /// Flush all messages in the Queue.
00045     ACE_FLUSHALL   = 04,
00046     /// Flush read queue
00047     ACE_FLUSHR     = 010,
00048     /// Flush write queue
00049     ACE_FLUSHW     = 020,
00050     /// Flush both queues
00051     ACE_FLUSHRW    = 030
00052   };
00053 };
00054 
00055 /**
00056  * @class ACE_Task_Base
00057  *
00058  * @brief Direct base class for the ACE_Task template.
00059  *
00060  * This class factors out the non-template code in order to
00061  * reduce template bloat, as well as to make it possible for the
00062  * <ACE_Thread_Manager> to store <ACE_Task_Base> *'s
00063  * polymorphically.
00064  */
00065 class ACE_Export ACE_Task_Base : public ACE_Service_Object
00066 {
00067 public:
00068   // = Initialization and termination methods.
00069   /// Constructor.
00070   ACE_Task_Base (ACE_Thread_Manager * = 0);
00071 
00072   /// Destructor.
00073   virtual ~ACE_Task_Base (void);
00074 
00075   // = Initialization and termination hooks.
00076 
00077   // These methods should be overridden by subclasses if you'd like to
00078   // provide <Task>-specific initialization and termination behavior.
00079 
00080   /// Hook called to open a Task.  <args> can be used to pass arbitrary
00081   /// information into <open>.
00082   virtual int open (void *args = 0);
00083 
00084   /**
00085    * Hook called from <ACE_Thread_Exit> when during thread exit and from
00086    * the default implementation of <module_closed>.  In general, this
00087    * method shouldn't be called directly by an application,
00088    * particularly if the <Task> is running as an Active Object.
00089    * Instead, a special message should be passed into the <Task> via
00090    * the <put> method defined below, and the <svc> method should
00091    * interpret this as a flag to shut down the <Task>.
00092    */
00093   virtual int close (u_long flags = 0);
00094 
00095   /**
00096    * Hook called during <ACE_Module::close>.  The default
00097    * implementation calls forwards the call to close(1).  Please
00098    * notice the changed value of the default argument of <close>.
00099    * This allows tasks to differ between the call has been originated
00100    * from <ACE_Thread_Exit> or from <module_closed>.  Be aware that
00101    * close(0) will be also called when a thread associated with the
00102    * ACE_Task instance exits.
00103    */
00104   virtual int module_closed (void);
00105 
00106   // = Immediate and deferred processing methods, respectively.
00107 
00108   // These methods should be overridden by subclasses if you'd like to
00109   // provide <Task>-specific message processing behavior.
00110 
00111   /// A hook method that can be used to pass a message to a
00112   /// task, where it can be processed immediately or queued for subsequent
00113   /// processing in the <svc> hook method.
00114   virtual int put (ACE_Message_Block *, ACE_Time_Value * = 0);
00115 
00116   /// Run by a daemon thread to handle deferred processing.
00117   virtual int svc (void);
00118 
00119   // = Active object activation method.
00120   /**
00121    * Turn the task into an active object, i.e., having <n_threads> of
00122    * control, all running at the <priority> level (see below) with the
00123    * same <grp_id>, all of which invoke <Task::svc>.  Returns -1 if
00124    * failure occurs, returns 1 if Task is already an active object and
00125    * <force_active> is false (i.e., do *not* create a new thread in
00126    * this case), and returns 0 if Task was not already an active
00127    * object and a thread is created successfully or thread is an
00128    * active object and <force_active> is true.  Note that if
00129    * <force_active> is true and there are already threads spawned in
00130    * this <Task>, the <grp_id> parameter is ignored and the <grp_id>
00131    * of any newly activated thread(s) will inherit the existing
00132    * <grp_id> of the existing thread(s) in the <Task>.
00133    *
00134    * The <{flags}> are a bitwise-OR of the following:
00135    * = BEGIN<INDENT>
00136    * THR_CANCEL_DISABLE, THR_CANCEL_ENABLE, THR_CANCEL_DEFERRED,
00137    * THR_CANCEL_ASYNCHRONOUS, THR_BOUND, THR_NEW_LWP, THR_DETACHED,
00138    * THR_SUSPENDED, THR_DAEMON, THR_JOINABLE, THR_SCHED_FIFO,
00139    * THR_SCHED_RR, THR_SCHED_DEFAULT, THR_EXPLICIT_SCHED,
00140    * THR_SCOPE_SYSTEM, THR_SCOPE_PROCESS
00141    * = END<INDENT>
00142    *
00143    * By default, or if <{priority}> is set to
00144    * ACE_DEFAULT_THREAD_PRIORITY, an "appropriate" priority value for
00145    * the given scheduling policy (specified in <{flags}>, e.g.,
00146    * <THR_SCHED_DEFAULT>) is used.  This value is calculated
00147    * dynamically, and is the median value between the minimum and
00148    * maximum priority values for the given policy.  If an explicit
00149    * value is given, it is used.  Note that actual priority values are
00150    * EXTREMEMLY implementation-dependent, and are probably best
00151    * avoided.
00152    *
00153    * If <thread_handles> != 0 it is assumed to be an array of <n>
00154    * thread_handles that will be assigned the values of the thread
00155    * handles being spawned.  Returns -1 on failure (<errno> will
00156    * explain...), otherwise returns the group id of the threads.
00157    *
00158    * Assigning <task> allows you to associate the newly spawned
00159    * threads with an instance of ACE_Task_Base.  If <task> == 0, then
00160    * the new threads are associated automatically with <this>
00161    * ACE_Task_Base.  Setting the <task> argument to value other than
00162    * <this> makes the thread manipulating methods, such as wait(),
00163    * suspend(), resume(), useless.  Threads spawned with user
00164    * specified <task> value must therefore be manipulated thru
00165    * ACE_Thread_Manager directly.
00166    *
00167    * If <stack> != 0 it is assumed to be an array of <n> pointers to
00168    * the base of the stacks to use for the threads being spawned.
00169    * Likewise, if <stack_size> != 0 it is assumed to be an array of
00170    * <n> values indicating how big each of the corresponding <stack>s
00171    * are.  */
00172   virtual int activate (long flags = THR_NEW_LWP | THR_JOINABLE,
00173                         int n_threads = 1,
00174                         int force_active = 0,
00175                         long priority = ACE_DEFAULT_THREAD_PRIORITY,
00176                         int grp_id = -1,
00177                         ACE_Task_Base *task = 0,
00178                         ACE_hthread_t thread_handles[] = 0,
00179                         void *stack[] = 0,
00180                         size_t stack_size[] = 0,
00181                         ACE_thread_t thread_ids[] = 0);
00182 
00183   /**
00184    * Block until there are no more threads running in this task.
00185    * This method will not wait for either detached or daemon threads;
00186    * the threads must have been spawned with the @c THR_JOINABLE flag.
00187    * Upon successful completion, the threads have been joined, so further
00188    * attempts to join with any of the waited-for threads will fail.
00189    *
00190    * @retval 0  Success.
00191    * @retval -1 Failure (consult errno for further information).
00192    */
00193   virtual int wait (void);
00194 
00195   // = Suspend/resume a Task.
00196 
00197   // Note that these methods are not portable and should be avoided
00198   // since they are inherently error-prone to use.  They are only here
00199   // for (the rare) applications that know how to use them correctly.
00200   /// Suspend a task.
00201   virtual int suspend (void);
00202   /// Resume a suspended task.
00203   virtual int resume (void);
00204 
00205   /// Get the current group id.
00206   int grp_id (void) const;
00207 
00208   /// Set the current group id.
00209   void grp_id (int);
00210 
00211   /// Get the thread manager associated with this Task.
00212   ACE_Thread_Manager *thr_mgr (void) const;
00213 
00214   /// Set the thread manager associated with this Task.
00215   void thr_mgr (ACE_Thread_Manager *);
00216 
00217   /// True if queue is a reader, else false.
00218   int is_reader (void) const;
00219 
00220   /// True if queue is a writer, else false.
00221   int is_writer (void) const;
00222 
00223   /**
00224    * Returns the number of threads currently running within a task.
00225    * If we're a passive object this value is 0, else it's greater than
00226    * 0.
00227    */
00228   size_t thr_count (void) const;
00229 
00230   /// Atomically decrement the thread count by 1.  This should only be
00231   /// called by the <ACE_Thread_Exit> class destructor.
00232   void thr_count_dec (void);
00233 
00234   /// Routine that runs the service routine as a daemon thread.
00235   static ACE_THR_FUNC_RETURN svc_run (void *);
00236 
00237   /// Cleanup hook that is called when a thread exits to gracefully
00238   /// shutdown an <ACE_Task>.
00239   static void cleanup (void *object, void *params);
00240 
00241   // = Internal data (should be private...).
00242 // private:
00243 
00244   /**
00245    * Count of the number of threads running within the task.  If this
00246    * value is greater than 0 then we're an active object and the value
00247    * of <thr_count_> is the number of active threads at this instant.
00248    * If the value == 0, then we're a passive object.
00249    */
00250   size_t thr_count_;
00251 
00252   /// Multi-threading manager.
00253   ACE_Thread_Manager *thr_mgr_;
00254 
00255   /// ACE_Task flags.
00256   u_long flags_;
00257 
00258   /// This maintains the group id of the Task.
00259   int grp_id_;
00260 
00261 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00262   /// Protect the state of a Task during concurrent operations, but
00263   /// only if we're configured as MT safe...
00264   ACE_Thread_Mutex lock_;
00265 #endif /* ACE_MT_SAFE */
00266 
00267 private:
00268 
00269   // = Disallow these operations.
00270   ACE_Task_Base &operator= (const ACE_Task_Base &);
00271   ACE_Task_Base (const ACE_Task_Base &);
00272 };
00273 
00274 #if defined (__ACE_INLINE__)
00275 #include "ace/Task.i"
00276 #endif /* __ACE_INLINE__ */
00277 
00278 // Include the ACE_Task templates classes at this point.
00279 #include "ace/Task_T.h"
00280 
00281 #include "ace/post.h"
00282 #endif /* ACE_TASK_H */

Generated on Mon Jun 16 11:21:44 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002