00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Svc_Handler.h 00006 * 00007 * Svc_Handler.h,v 4.56 2006/03/06 15:43:36 jwillemsen Exp 00008 * 00009 * @author Douglas Schmidt <schmidt@uci.edu> 00010 * @author Irfan Pyarali <irfan@cs.wustl.edu> 00011 */ 00012 //============================================================================= 00013 00014 #ifndef ACE_SVC_HANDLER_H 00015 #define ACE_SVC_HANDLER_H 00016 00017 #include /**/ "ace/pre.h" 00018 00019 #include "ace/Synch_Options.h" 00020 00021 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00022 # pragma once 00023 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00024 00025 #include "ace/Task.h" 00026 #include "ace/Recyclable.h" 00027 #include "ace/Reactor.h" 00028 00029 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00030 00031 // Forward decls. 00032 class ACE_Connection_Recycling_Strategy; 00033 00034 /** 00035 * @class ACE_Svc_Handler 00036 * 00037 * @brief Defines the interface for a service that exchanges data with 00038 * its connected peer. 00039 * 00040 * This class provides a well-defined interface that the 00041 * Acceptor and Connector pattern factories use as their target. 00042 * Typically, client applications will subclass ACE_Svc_Handler 00043 * and do all the interesting work in the subclass. One thing 00044 * that the ACE_Svc_Handler does contain is a PEER_STREAM 00045 * endpoint that is initialized by an ACE_Acceptor or 00046 * ACE_Connector when a connection is established successfully. 00047 * This endpoint is used to exchange data between a 00048 * ACE_Svc_Handler and the peer it is connected with. 00049 */ 00050 template <ACE_PEER_STREAM_1, ACE_SYNCH_DECL> 00051 class ACE_Svc_Handler : public ACE_Task<ACE_SYNCH_USE> 00052 { 00053 public: 00054 00055 // Useful STL-style traits. 00056 typedef ACE_PEER_STREAM_ADDR addr_type; 00057 typedef ACE_PEER_STREAM stream_type; 00058 00059 /** 00060 * Constructor initializes the @a thr_mgr and @a mq by passing them 00061 * down to the ACE_Task base class. The @a reactor is passed to 00062 * the ACE_Event_Handler. 00063 */ 00064 ACE_Svc_Handler (ACE_Thread_Manager *thr_mgr = 0, 00065 ACE_Message_Queue<ACE_SYNCH_USE> *mq = 0, 00066 ACE_Reactor *reactor = ACE_Reactor::instance ()); 00067 00068 /// Destructor. 00069 virtual ~ACE_Svc_Handler (void); 00070 00071 /// Activate the client handler. This is typically called by the 00072 /// ACE_Acceptor or ACE_Connector. 00073 virtual int open (void * = 0); 00074 00075 /** 00076 * Object termination hook -- application-specific cleanup code goes 00077 * here. This function is called by the idle() function if the object 00078 * does not have a ACE_Connection_Recycling_Strategy associated with it. 00079 * Also, due to this class's derivation from ACE_Task, close() is 00080 * also called when a thread activated with this object exits. See 00081 * ACE_Task::close() for further details. The default action of this 00082 * function is to call handle_close() with the default arguments. 00083 */ 00084 virtual int close (u_long flags = 0); 00085 00086 /** 00087 * Call this method if you want to recycling the @c Svc_Handler 00088 * instead of closing it. If the object does not have a recycler, 00089 * it will be closed. 00090 */ 00091 virtual int idle (u_long flags = 0); 00092 00093 /** 00094 * Call this method if you want to get/set the state of the 00095 * @c Svc_Handler. If the object does not have a recycler, this call 00096 * will have no effect (and the accessor will return 00097 * ACE_RECYCLABLE_UNKNOWN). 00098 */ 00099 virtual ACE_Recyclable_State recycle_state (void) const; 00100 virtual int recycle_state (ACE_Recyclable_State new_state); 00101 00102 /** 00103 * When the svc_handle is no longer needed around as a hint, call 00104 * this method. In addition, reset @c *act_holder to zero if 00105 * @a act_holder != 0. 00106 */ 00107 virtual void cleanup_hint (void **act_holder = 0); 00108 00109 // = Dynamic linking hooks. 00110 /// Default version does no work and returns -1. Must be overloaded 00111 /// by application developer to do anything meaningful. 00112 virtual int init (int argc, ACE_TCHAR *argv[]); 00113 00114 /// Default version does no work and returns -1. Must be overloaded 00115 /// by application developer to do anything meaningful. 00116 virtual int fini (void); 00117 00118 /// Default version does no work and returns -1. Must be overloaded 00119 /// by application developer to do anything meaningful. 00120 virtual int info (ACE_TCHAR **info_string, size_t length) const; 00121 00122 // = Demultiplexing hooks. 00123 00124 /** 00125 * Perform termination activities on the SVC_HANDLER. The default 00126 * behavior is to close down the <peer_> (to avoid descriptor leaks) 00127 * and to <destroy> this object (to avoid memory leaks)! If you 00128 * don't want this behavior make sure you override this method... 00129 */ 00130 virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, 00131 ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); 00132 00133 /// Default behavior when timeouts occur is to close down the 00134 /// <Svc_Handler> by calling <handle_close>. 00135 virtual int handle_timeout (const ACE_Time_Value &time, 00136 const void *); 00137 00138 /// Get the underlying handle associated with the <peer_>. 00139 virtual ACE_HANDLE get_handle (void) const; 00140 00141 /// Set the underlying handle associated with the <peer_>. 00142 virtual void set_handle (ACE_HANDLE); 00143 00144 /// Returns the underlying PEER_STREAM. Used by 00145 /// <ACE_Acceptor::accept> and <ACE_Connector::connect> factories 00146 ACE_PEER_STREAM &peer (void) const; 00147 00148 /// Overloaded new operator. This method unobtrusively records if a 00149 /// <Svc_Handler> is allocated dynamically, which allows it to clean 00150 /// itself up correctly whether or not it's allocated statically or 00151 /// dynamically. 00152 void *operator new (size_t n); 00153 00154 #if defined (ACE_HAS_NEW_NOTHROW) 00155 /// Overloaded new operator, nothrow_t variant. Unobtrusively records if a 00156 /// <Svc_Handler> is allocated dynamically, which allows it to clean 00157 /// itself up correctly whether or not it's allocated statically or 00158 /// dynamically. 00159 void *operator new (size_t n, const ACE_nothrow_t&) throw(); 00160 #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE) 00161 void operator delete (void *p, const ACE_nothrow_t&) throw (); 00162 #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */ 00163 #endif 00164 00165 /// This operator permits "placement new" on a per-object basis. 00166 void * operator new (size_t n, 00167 void *p); 00168 00169 /** 00170 * Call this to free up dynamically allocated <Svc_Handlers> 00171 * (otherwise you will get memory leaks). In general, you should 00172 * call this method rather than <delete> since this method knows 00173 * whether or not the object was allocated dynamically, and can act 00174 * accordingly (i.e., deleting it if it was allocated dynamically). 00175 */ 00176 virtual void destroy (void); 00177 00178 /** 00179 * This really should be private so that users are forced to call 00180 * <destroy>. Unfortunately, the C++ standard doesn't allow there 00181 * to be a public new and a private delete. It is a bad idea to 00182 * call this method directly, so use <destroy> instead, unless you 00183 * know for sure that you've allocated the object dynamically. 00184 */ 00185 void operator delete (void *); 00186 00187 #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE) 00188 /** 00189 * This operator is necessary to complement the class-specific 00190 * operator new above. Unfortunately, it's not portable to all C++ 00191 * compilers... 00192 */ 00193 void operator delete (void *, void *); 00194 #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */ 00195 00196 /// Close down the descriptor and unregister from the Reactor 00197 void shutdown (void); 00198 00199 /// Dump the state of an object. 00200 void dump (void) const; 00201 00202 public: 00203 00204 // = The following methods are not suppose to be public. 00205 00206 // Because friendship is *not* inherited in C++, these methods have 00207 // to be public. 00208 00209 // = Accessors to set/get the connection recycler. 00210 00211 /// Set the recycler and the <recycling_act> that is used during 00212 /// purging and caching. 00213 virtual void recycler (ACE_Connection_Recycling_Strategy *recycler, 00214 const void *recycling_act); 00215 00216 /// Get the recycler. 00217 virtual ACE_Connection_Recycling_Strategy *recycler (void) const; 00218 00219 /// Get the recycling act. 00220 virtual const void *recycling_act (void) const; 00221 00222 /** 00223 * Upcall made by the recycler when it is about to recycle the 00224 * connection. This gives the object a chance to prepare itself for 00225 * recycling. Return 0 if the object is ready for recycling, -1 on 00226 * failures. 00227 */ 00228 virtual int recycle (void * = 0); 00229 00230 protected: 00231 /// Maintain connection with client. 00232 ACE_PEER_STREAM peer_; 00233 00234 /// Have we been dynamically created? 00235 int dynamic_; 00236 00237 /// Keeps track of whether we are in the process of closing (required 00238 /// to avoid circular calls to <handle_close>). 00239 int closing_; 00240 00241 /// Pointer to the connection recycler. 00242 ACE_Connection_Recycling_Strategy *recycler_; 00243 00244 /// Asynchronous Completion Token (ACT) to be used to when talking to 00245 /// the recycler. 00246 const void *recycling_act_; 00247 }; 00248 00249 /** 00250 * @class ACE_Buffered_Svc_Handler 00251 * 00252 * @brief Defines the interface for a service that exchanges data with 00253 * its connected peer and supports buffering. 00254 * 00255 * The buffering feature makes it possible to queue up 00256 * <ACE_Message_Blocks> in an ACE_Message_Queue until (1) the 00257 * queue is "full" or (2) a period of time elapses, at which 00258 * point the queue is "flushed" via <sendv_n> to the peer. 00259 */ 00260 template <ACE_PEER_STREAM_1, ACE_SYNCH_DECL> 00261 class ACE_Buffered_Svc_Handler : public ACE_Svc_Handler<ACE_PEER_STREAM_2, ACE_SYNCH_USE> 00262 { 00263 public: 00264 // = Initialization and termination methods. 00265 /** 00266 * Constructor initializes the <thr_mgr> and <mq> by passing them 00267 * down to the <ACE_Task> base class. The <reactor> is passed to 00268 * the ACE_Event_Handler. The <max_buffer_size> and 00269 * <relative_timeout> are used to determine at what point to flush 00270 * the <mq>. By default, there's no buffering at all. The 00271 * <relative_timeout> value is interpreted to be in a unit that's 00272 * relative to the current time returned by <ACE_OS::gettimeofday>. 00273 */ 00274 ACE_Buffered_Svc_Handler (ACE_Thread_Manager *thr_mgr = 0, 00275 ACE_Message_Queue<ACE_SYNCH_USE> *mq = 0, 00276 ACE_Reactor *reactor = ACE_Reactor::instance (), 00277 size_t max_buffer_size = 0, 00278 ACE_Time_Value *relative_timeout = 0); 00279 00280 /// Destructor, which calls <flush>. 00281 virtual ~ACE_Buffered_Svc_Handler (void); 00282 00283 /** 00284 * Insert the ACE_Message_Block chain rooted at <message_block> 00285 * into the ACE_Message_Queue with the designated <timeout>. The 00286 * <flush> method will be called if this <put> causes the number of 00287 * bytes to exceed the maximum buffer size or if the timeout period 00288 * has elapsed. 00289 */ 00290 virtual int put (ACE_Message_Block *message_block, 00291 ACE_Time_Value *timeout = 0); 00292 00293 /// Flush the ACE_Message_Queue, which writes all the queued 00294 /// ACE_Message_Blocks to the <PEER_STREAM>. 00295 virtual int flush (void); 00296 00297 /// This method is not currently implemented -- this is where the 00298 /// integration with the <Reactor> would occur. 00299 virtual int handle_timeout (const ACE_Time_Value &time, 00300 const void *); 00301 00302 /// Dump the state of an object. 00303 void dump (void) const; 00304 00305 protected: 00306 /// Implement the flush operation on the ACE_Message_Queue, which 00307 /// writes all the queued ACE_Message_Blocks to the <PEER_STREAM>. 00308 /// Assumes that the caller holds the lock. 00309 virtual int flush_i (void); 00310 00311 /// Maximum size the <Message_Queue> can be before we have to flush 00312 /// the buffer. 00313 size_t maximum_buffer_size_; 00314 00315 /// Current size in bytes of the <Message_Queue> contents. 00316 size_t current_buffer_size_; 00317 00318 /// Timeout value used to control when the buffer is flushed. 00319 ACE_Time_Value next_timeout_; 00320 00321 /// Interval of the timeout. 00322 ACE_Time_Value interval_; 00323 00324 /// Timeout pointer. 00325 ACE_Time_Value *timeoutp_; 00326 }; 00327 00328 ACE_END_VERSIONED_NAMESPACE_DECL 00329 00330 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00331 #include "ace/Svc_Handler.cpp" 00332 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00333 00334 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00335 #pragma implementation ("Svc_Handler.cpp") 00336 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00337 00338 #include /**/ "ace/post.h" 00339 00340 #endif /* ACE_SVC_HANDLER_H */