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 */
1.2.14 written by Dimitri van Heesch,
© 1997-2002