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