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