Svc_Handler.h

Go to the documentation of this file.
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 */

Generated on Thu Nov 9 09:42:06 2006 for ACE by doxygen 1.3.6