00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Svc_Handler.h 00006 * 00007 * $Id: Svc_Handler.h 80826 2008-03-04 14:51:23Z wotte $ 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, void *p); 00167 00168 /** 00169 * Call this to free up dynamically allocated <Svc_Handlers> 00170 * (otherwise you will get memory leaks). In general, you should 00171 * call this method rather than <delete> since this method knows 00172 * whether or not the object was allocated dynamically, and can act 00173 * accordingly (i.e., deleting it if it was allocated dynamically). 00174 */ 00175 virtual void destroy (void); 00176 00177 /** 00178 * This really should be private so that users are forced to call 00179 * <destroy>. Unfortunately, the C++ standard doesn't allow there 00180 * to be a public new and a private delete. It is a bad idea to 00181 * call this method directly, so use <destroy> instead, unless you 00182 * know for sure that you've allocated the object dynamically. 00183 */ 00184 void operator delete (void *); 00185 00186 #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE) 00187 /** 00188 * This operator is necessary to complement the class-specific 00189 * operator new above. Unfortunately, it's not portable to all C++ 00190 * compilers... 00191 */ 00192 void operator delete (void *, void *); 00193 #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */ 00194 00195 /// Close down the descriptor and unregister from the Reactor 00196 void shutdown (void); 00197 00198 /// Dump the state of an object. 00199 void dump (void) const; 00200 00201 public: 00202 00203 // = The following methods are not suppose to be public. 00204 00205 // Because friendship is *not* inherited in C++, these methods have 00206 // to be public. 00207 00208 // = Accessors to set/get the connection recycler. 00209 00210 /// Set the recycler and the @a recycling_act that is used during 00211 /// purging and caching. 00212 virtual void recycler (ACE_Connection_Recycling_Strategy *recycler, 00213 const void *recycling_act); 00214 00215 /// Get the recycler. 00216 virtual ACE_Connection_Recycling_Strategy *recycler (void) const; 00217 00218 /// Get the recycling act. 00219 virtual const void *recycling_act (void) const; 00220 00221 /** 00222 * Upcall made by the recycler when it is about to recycle the 00223 * connection. This gives the object a chance to prepare itself for 00224 * recycling. Return 0 if the object is ready for recycling, -1 on 00225 * failures. 00226 */ 00227 virtual int recycle (void * = 0); 00228 00229 protected: 00230 /// Maintain connection with client. 00231 ACE_PEER_STREAM peer_; 00232 00233 /// Have we been dynamically created? 00234 bool dynamic_; 00235 00236 /// Keeps track of whether we are in the process of closing (required 00237 /// to avoid circular calls to <handle_close>). 00238 bool closing_; 00239 00240 /// Pointer to the connection recycler. 00241 ACE_Connection_Recycling_Strategy *recycler_; 00242 00243 /// Asynchronous Completion Token (ACT) to be used to when talking to 00244 /// the recycler. 00245 const void *recycling_act_; 00246 }; 00247 00248 /** 00249 * @class ACE_Buffered_Svc_Handler 00250 * 00251 * @brief Defines the interface for a service that exchanges data with 00252 * its connected peer and supports buffering. 00253 * 00254 * The buffering feature makes it possible to queue up 00255 * ACE_Message_Blocks in an ACE_Message_Queue until (1) the 00256 * queue is "full" or (2) a period of time elapses, at which 00257 * point the queue is "flushed" via <sendv_n> to the peer. 00258 */ 00259 template <ACE_PEER_STREAM_1, ACE_SYNCH_DECL> 00260 class ACE_Buffered_Svc_Handler : public ACE_Svc_Handler<ACE_PEER_STREAM_2, ACE_SYNCH_USE> 00261 { 00262 public: 00263 // = Initialization and termination methods. 00264 /** 00265 * Constructor initializes the @a thr_mgr and @a mq by passing them 00266 * down to the ACE_Task base class. The @a reactor is passed to 00267 * the ACE_Event_Handler. The @a max_buffer_size and 00268 * @a relative_timeout are used to determine at what point to flush 00269 * the @a mq. By default, there's no buffering at all. The 00270 * @a relative_timeout value is interpreted to be in a unit that's 00271 * relative to the current time returned by <ACE_OS::gettimeofday>. 00272 */ 00273 ACE_Buffered_Svc_Handler (ACE_Thread_Manager *thr_mgr = 0, 00274 ACE_Message_Queue<ACE_SYNCH_USE> *mq = 0, 00275 ACE_Reactor *reactor = ACE_Reactor::instance (), 00276 size_t max_buffer_size = 0, 00277 ACE_Time_Value *relative_timeout = 0); 00278 00279 /// Destructor, which calls <flush>. 00280 virtual ~ACE_Buffered_Svc_Handler (void); 00281 00282 /** 00283 * Insert the ACE_Message_Block chain rooted at @a message_block 00284 * into the ACE_Message_Queue with the designated @a timeout. The 00285 * <flush> method will be called if this <put> causes the number of 00286 * bytes to exceed the maximum buffer size or if the timeout period 00287 * has elapsed. 00288 */ 00289 virtual int put (ACE_Message_Block *message_block, 00290 ACE_Time_Value *timeout = 0); 00291 00292 /// Flush the ACE_Message_Queue, which writes all the queued 00293 /// ACE_Message_Blocks to the <PEER_STREAM>. 00294 virtual int flush (void); 00295 00296 /// This method is not currently implemented -- this is where the 00297 /// integration with the <Reactor> would occur. 00298 virtual int handle_timeout (const ACE_Time_Value &time, 00299 const void *); 00300 00301 /// Dump the state of an object. 00302 void dump (void) const; 00303 00304 protected: 00305 /// Implement the flush operation on the ACE_Message_Queue, which 00306 /// writes all the queued ACE_Message_Blocks to the <PEER_STREAM>. 00307 /// Assumes that the caller holds the lock. 00308 virtual int flush_i (void); 00309 00310 /// Maximum size the <Message_Queue> can be before we have to flush 00311 /// the buffer. 00312 size_t maximum_buffer_size_; 00313 00314 /// Current size in bytes of the <Message_Queue> contents. 00315 size_t current_buffer_size_; 00316 00317 /// Timeout value used to control when the buffer is flushed. 00318 ACE_Time_Value next_timeout_; 00319 00320 /// Interval of the timeout. 00321 ACE_Time_Value interval_; 00322 00323 /// Timeout pointer. 00324 ACE_Time_Value *timeoutp_; 00325 }; 00326 00327 ACE_END_VERSIONED_NAMESPACE_DECL 00328 00329 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00330 #include "ace/Svc_Handler.cpp" 00331 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00332 00333 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00334 #pragma implementation ("Svc_Handler.cpp") 00335 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00336 00337 #include /**/ "ace/post.h" 00338 00339 #endif /* ACE_SVC_HANDLER_H */