00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Task_Ex_T.h 00006 * 00007 * $Id: Task_Ex_T.h 79337 2007-08-14 14:33:48Z sowayaa $ 00008 * 00009 * @author Kobi Cohen-Arazi <kobi-co@barak-online.net> 00010 */ 00011 //============================================================================= 00012 00013 #ifndef ACE_TASK_EX_T_H 00014 #define ACE_TASK_EX_T_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/Synch_Traits.h" 00024 #include "ace/Task.h" 00025 00026 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00027 00028 // Forward decls... 00029 template <ACE_SYNCH_DECL> class ACE_Module; 00030 00031 /** 00032 * @class ACE_Task_Ex 00033 * 00034 * @brief Primary interface for application message processing, as well 00035 * as input and output message queueing. 00036 * 00037 * Unlike ACE_Task, these class doesn't have the ability to be a part of 00038 * a Stream chain. I.e. You cannot (yet) chain modules based on ACE_Task_Ex. 00039 * 00040 * @todo: We can merge ACE_Task and ACE_Task_Ex to be one class. 00041 * something like that: 00042 * template <ACE_SYNCH_DECL, ACE_MESSAGE_TYPE = ACE_Message_Block> 00043 * class ACE_Task : public ACE_Task_Base 00044 * { 00045 * // use here the code from ACE_Task_Ex using ACE_Message_Queue_Ex 00046 * }; 00047 * 00048 * Now specialized version of ACE_Task with ACE_Message_Block as its 00049 * ACE_MESSAGE_TYPE... 00050 * 00051 * template <ACE_SYNCH_DECL> 00052 * class ACE_Task <ACE_SYNCH_USE, ACE_Message_Block> : public ACE_Task_Base 00053 * { 00054 * // put here the good old ACE_Task code 00055 * }; 00056 * 00057 * When User (and legacy code) write ACE_Task<ACE_MT_SYNCH>, specialized ACE_Task 00058 * code is in action. 00059 */ 00060 template <ACE_SYNCH_DECL, class ACE_MESSAGE_TYPE> 00061 class ACE_Task_Ex : public ACE_Task_Base 00062 { 00063 public: 00064 friend class ACE_Module<ACE_SYNCH_USE>; 00065 friend class ACE_Module_Type; 00066 typedef ACE_Message_Queue_Ex<ACE_MESSAGE_TYPE, ACE_SYNCH_USE> MESSAGE_QUEUE_EX; 00067 00068 // = Initialization/termination methods. 00069 /** 00070 * Initialize a Task, supplying a thread manager and a message 00071 * queue. If the user doesn't supply a ACE_Message_Queue pointer 00072 * then we'll allocate one dynamically. Otherwise, we'll use the 00073 * one passed as a parameter. 00074 */ 00075 ACE_Task_Ex (ACE_Thread_Manager *thr_mgr = 0, 00076 MESSAGE_QUEUE_EX *mq = 0); 00077 00078 /// Destructor. 00079 virtual ~ACE_Task_Ex (void); 00080 00081 /// Gets the message queue associated with this task. 00082 MESSAGE_QUEUE_EX *msg_queue (void); 00083 00084 /// Sets the message queue associated with this task. 00085 void msg_queue (MESSAGE_QUEUE_EX *); 00086 00087 public: // Should be protected: 00088 // = Message queue manipulation methods. 00089 00090 // = Enqueue and dequeue methods. 00091 00092 // For the following five method if @a timeout == 0, the caller will 00093 // block until action is possible, else will wait until the 00094 // <{absolute}> time specified in *@a timeout elapses). These calls 00095 // will return, however, when queue is closed, deactivated, when a 00096 // signal occurs, or if the time specified in timeout elapses, (in 00097 // which case errno = EWOULDBLOCK). 00098 00099 /// Insert message into the message queue. Note that @a timeout uses 00100 /// <{absolute}> time rather than <{relative}> time. 00101 int putq (ACE_MESSAGE_TYPE *, ACE_Time_Value *timeout = 0); 00102 00103 /** 00104 * Extract the first message from the queue (blocking). Note that 00105 * @a timeout uses <{absolute}> time rather than <{relative}> time. 00106 * Returns number of items in queue if the call succeeds or -1 otherwise. 00107 */ 00108 int getq (ACE_MESSAGE_TYPE *&mb, ACE_Time_Value *timeout = 0); 00109 00110 /// Return a message to the queue. Note that @a timeout uses 00111 /// <{absolute}> time rather than <{relative}> time. 00112 int ungetq (ACE_MESSAGE_TYPE *, ACE_Time_Value *timeout = 0); 00113 00114 /** 00115 * Turn the message around and send it back down the Stream. Note 00116 * that @a timeout uses <{absolute}> time rather than <{relative}> 00117 * time. 00118 */ 00119 int reply (ACE_MESSAGE_TYPE *, ACE_Time_Value *timeout = 0); 00120 00121 /** 00122 * Transfer message to the adjacent ACE_Task_Ex in a ACE_Stream. Note 00123 * that @a timeout uses <{absolute}> time rather than <{relative}> 00124 * time. 00125 */ 00126 int put_next (ACE_MESSAGE_TYPE *msg, ACE_Time_Value *timeout = 0); 00127 00128 /// Tests whether we can enqueue a message without blocking. 00129 int can_put (ACE_MESSAGE_TYPE *); 00130 00131 // = ACE_Task utility routines to identify names et al. 00132 /// Return the name of the enclosing Module if there's one associated 00133 /// with the Task, else returns 0. 00134 const ACE_TCHAR *name (void) const; 00135 00136 // = Pointers to next ACE_Task_Base (if ACE is part of an ACE_Stream). 00137 /// Get next Task pointer. 00138 ACE_Task<ACE_SYNCH_USE> *next (void); 00139 00140 /// Set next Task pointer. 00141 void next (ACE_Task<ACE_SYNCH_USE> *); 00142 00143 /// Alwasy return 0. @todo FIXME 00144 ACE_Task<ACE_SYNCH_USE> *sibling (void); 00145 00146 /// Return the Task's Module if there is one, else returns 0. 00147 ACE_Module<ACE_SYNCH_USE> *module (void) const; 00148 00149 /** 00150 * Flush the task's queue, i.e., free all of the enqueued 00151 * message blocks and releases any threads blocked on the queue. 00152 * Note that if this conflicts with the C++ iostream <flush> 00153 * function, just rewrite the iostream function as ::<flush>. 00154 */ 00155 int flush (u_long flag = ACE_Task_Flags::ACE_FLUSHALL); 00156 00157 // = Special routines corresponding to certain message types. 00158 00159 /// Manipulate watermarks. 00160 void water_marks (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds, size_t); 00161 00162 /// Queue of messages on the ACE_Task.. 00163 MESSAGE_QUEUE_EX *msg_queue_; 00164 00165 /// 1 if should delete Message_Queue, 0 otherwise. 00166 int delete_msg_queue_; 00167 00168 /// Back-pointer to the enclosing module. 00169 ACE_Module<ACE_SYNCH_USE> *mod_; 00170 00171 /// Pointer to adjacent ACE_Task. 00172 ACE_Task<ACE_SYNCH_USE> *next_; 00173 00174 /// Dump the state of an object. 00175 void dump (void) const; 00176 00177 /// Declare the dynamic allocation hooks. 00178 ACE_ALLOC_HOOK_DECLARE; 00179 00180 private: 00181 00182 // = Disallow these operations. 00183 ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Task_Ex<ACE_SYNCH_USE, ACE_MESSAGE_TYPE> &)) 00184 ACE_UNIMPLEMENTED_FUNC (ACE_Task_Ex (const ACE_Task_Ex<ACE_SYNCH_USE, ACE_MESSAGE_TYPE> &)) 00185 }; 00186 00187 ACE_END_VERSIONED_NAMESPACE_DECL 00188 00189 #if defined (__ACE_INLINE__) 00190 #include "ace/Task_Ex_T.inl" 00191 #endif /* __ACE_INLINE__ */ 00192 00193 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00194 #include "ace/Task_Ex_T.cpp" 00195 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00196 00197 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00198 #pragma implementation ("Task_Ex_T.cpp") 00199 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00200 00201 #include /**/ "ace/post.h" 00202 #endif /* ACE_TASK_EX_H */