diff options
author | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:30 +0000 |
---|---|---|
committer | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:30 +0000 |
commit | c44379cc7d9c7aa113989237ab0f56db12aa5219 (patch) | |
tree | 66a84b20d47f2269d8bdc6e0323f338763424d3a /ACE/ace/Svc_Handler.h | |
parent | 3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c (diff) | |
download | ATCD-c44379cc7d9c7aa113989237ab0f56db12aa5219.tar.gz |
Repo restructuring
Diffstat (limited to 'ACE/ace/Svc_Handler.h')
-rw-r--r-- | ACE/ace/Svc_Handler.h | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/ACE/ace/Svc_Handler.h b/ACE/ace/Svc_Handler.h new file mode 100644 index 00000000000..76027b9e409 --- /dev/null +++ b/ACE/ace/Svc_Handler.h @@ -0,0 +1,340 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Svc_Handler.h + * + * $Id$ + * + * @author Douglas Schmidt <schmidt@uci.edu> + * @author Irfan Pyarali <irfan@cs.wustl.edu> + */ +//============================================================================= + +#ifndef ACE_SVC_HANDLER_H +#define ACE_SVC_HANDLER_H + +#include /**/ "ace/pre.h" + +#include "ace/Synch_Options.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Task.h" +#include "ace/Recyclable.h" +#include "ace/Reactor.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +// Forward decls. +class ACE_Connection_Recycling_Strategy; + +/** + * @class ACE_Svc_Handler + * + * @brief Defines the interface for a service that exchanges data with + * its connected peer. + * + * This class provides a well-defined interface that the + * Acceptor and Connector pattern factories use as their target. + * Typically, client applications will subclass ACE_Svc_Handler + * and do all the interesting work in the subclass. One thing + * that the ACE_Svc_Handler does contain is a PEER_STREAM + * endpoint that is initialized by an ACE_Acceptor or + * ACE_Connector when a connection is established successfully. + * This endpoint is used to exchange data between a + * ACE_Svc_Handler and the peer it is connected with. + */ +template <ACE_PEER_STREAM_1, ACE_SYNCH_DECL> +class ACE_Svc_Handler : public ACE_Task<ACE_SYNCH_USE> +{ +public: + + // Useful STL-style traits. + typedef ACE_PEER_STREAM_ADDR addr_type; + typedef ACE_PEER_STREAM stream_type; + + /** + * Constructor initializes the @a thr_mgr and @a mq by passing them + * down to the ACE_Task base class. The @a reactor is passed to + * the ACE_Event_Handler. + */ + ACE_Svc_Handler (ACE_Thread_Manager *thr_mgr = 0, + ACE_Message_Queue<ACE_SYNCH_USE> *mq = 0, + ACE_Reactor *reactor = ACE_Reactor::instance ()); + + /// Destructor. + virtual ~ACE_Svc_Handler (void); + + /// Activate the client handler. This is typically called by the + /// ACE_Acceptor or ACE_Connector. + virtual int open (void * = 0); + + /** + * Object termination hook -- application-specific cleanup code goes + * here. This function is called by the idle() function if the object + * does not have a ACE_Connection_Recycling_Strategy associated with it. + * Also, due to this class's derivation from ACE_Task, close() is + * also called when a thread activated with this object exits. See + * ACE_Task::close() for further details. The default action of this + * function is to call handle_close() with the default arguments. + */ + virtual int close (u_long flags = 0); + + /** + * Call this method if you want to recycling the @c Svc_Handler + * instead of closing it. If the object does not have a recycler, + * it will be closed. + */ + virtual int idle (u_long flags = 0); + + /** + * Call this method if you want to get/set the state of the + * @c Svc_Handler. If the object does not have a recycler, this call + * will have no effect (and the accessor will return + * ACE_RECYCLABLE_UNKNOWN). + */ + virtual ACE_Recyclable_State recycle_state (void) const; + virtual int recycle_state (ACE_Recyclable_State new_state); + + /** + * When the svc_handle is no longer needed around as a hint, call + * this method. In addition, reset @c *act_holder to zero if + * @a act_holder != 0. + */ + virtual void cleanup_hint (void **act_holder = 0); + + // = Dynamic linking hooks. + /// Default version does no work and returns -1. Must be overloaded + /// by application developer to do anything meaningful. + virtual int init (int argc, ACE_TCHAR *argv[]); + + /// Default version does no work and returns -1. Must be overloaded + /// by application developer to do anything meaningful. + virtual int fini (void); + + /// Default version does no work and returns -1. Must be overloaded + /// by application developer to do anything meaningful. + virtual int info (ACE_TCHAR **info_string, size_t length) const; + + // = Demultiplexing hooks. + + /** + * Perform termination activities on the SVC_HANDLER. The default + * behavior is to close down the <peer_> (to avoid descriptor leaks) + * and to <destroy> this object (to avoid memory leaks)! If you + * don't want this behavior make sure you override this method... + */ + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); + + /// Default behavior when timeouts occur is to close down the + /// <Svc_Handler> by calling <handle_close>. + virtual int handle_timeout (const ACE_Time_Value &time, + const void *); + + /// Get the underlying handle associated with the <peer_>. + virtual ACE_HANDLE get_handle (void) const; + + /// Set the underlying handle associated with the <peer_>. + virtual void set_handle (ACE_HANDLE); + + /// Returns the underlying PEER_STREAM. Used by + /// <ACE_Acceptor::accept> and <ACE_Connector::connect> factories + ACE_PEER_STREAM &peer (void) const; + + /// Overloaded new operator. This method unobtrusively records if a + /// <Svc_Handler> is allocated dynamically, which allows it to clean + /// itself up correctly whether or not it's allocated statically or + /// dynamically. + void *operator new (size_t n); + +#if defined (ACE_HAS_NEW_NOTHROW) + /// Overloaded new operator, nothrow_t variant. Unobtrusively records if a + /// <Svc_Handler> is allocated dynamically, which allows it to clean + /// itself up correctly whether or not it's allocated statically or + /// dynamically. + void *operator new (size_t n, const ACE_nothrow_t&) throw(); +#if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE) + void operator delete (void *p, const ACE_nothrow_t&) throw (); +#endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */ +#endif + + /// This operator permits "placement new" on a per-object basis. + void * operator new (size_t n, + void *p); + + /** + * Call this to free up dynamically allocated <Svc_Handlers> + * (otherwise you will get memory leaks). In general, you should + * call this method rather than <delete> since this method knows + * whether or not the object was allocated dynamically, and can act + * accordingly (i.e., deleting it if it was allocated dynamically). + */ + virtual void destroy (void); + + /** + * This really should be private so that users are forced to call + * <destroy>. Unfortunately, the C++ standard doesn't allow there + * to be a public new and a private delete. It is a bad idea to + * call this method directly, so use <destroy> instead, unless you + * know for sure that you've allocated the object dynamically. + */ + void operator delete (void *); + +#if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE) + /** + * This operator is necessary to complement the class-specific + * operator new above. Unfortunately, it's not portable to all C++ + * compilers... + */ + void operator delete (void *, void *); +#endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */ + + /// Close down the descriptor and unregister from the Reactor + void shutdown (void); + + /// Dump the state of an object. + void dump (void) const; + +public: + + // = The following methods are not suppose to be public. + + // Because friendship is *not* inherited in C++, these methods have + // to be public. + + // = Accessors to set/get the connection recycler. + + /// Set the recycler and the <recycling_act> that is used during + /// purging and caching. + virtual void recycler (ACE_Connection_Recycling_Strategy *recycler, + const void *recycling_act); + + /// Get the recycler. + virtual ACE_Connection_Recycling_Strategy *recycler (void) const; + + /// Get the recycling act. + virtual const void *recycling_act (void) const; + + /** + * Upcall made by the recycler when it is about to recycle the + * connection. This gives the object a chance to prepare itself for + * recycling. Return 0 if the object is ready for recycling, -1 on + * failures. + */ + virtual int recycle (void * = 0); + +protected: + /// Maintain connection with client. + ACE_PEER_STREAM peer_; + + /// Have we been dynamically created? + int dynamic_; + + /// Keeps track of whether we are in the process of closing (required + /// to avoid circular calls to <handle_close>). + int closing_; + + /// Pointer to the connection recycler. + ACE_Connection_Recycling_Strategy *recycler_; + + /// Asynchronous Completion Token (ACT) to be used to when talking to + /// the recycler. + const void *recycling_act_; +}; + +/** + * @class ACE_Buffered_Svc_Handler + * + * @brief Defines the interface for a service that exchanges data with + * its connected peer and supports buffering. + * + * The buffering feature makes it possible to queue up + * <ACE_Message_Blocks> in an ACE_Message_Queue until (1) the + * queue is "full" or (2) a period of time elapses, at which + * point the queue is "flushed" via <sendv_n> to the peer. + */ +template <ACE_PEER_STREAM_1, ACE_SYNCH_DECL> +class ACE_Buffered_Svc_Handler : public ACE_Svc_Handler<ACE_PEER_STREAM_2, ACE_SYNCH_USE> +{ +public: + // = Initialization and termination methods. + /** + * Constructor initializes the <thr_mgr> and <mq> by passing them + * down to the <ACE_Task> base class. The <reactor> is passed to + * the ACE_Event_Handler. The <max_buffer_size> and + * <relative_timeout> are used to determine at what point to flush + * the <mq>. By default, there's no buffering at all. The + * <relative_timeout> value is interpreted to be in a unit that's + * relative to the current time returned by <ACE_OS::gettimeofday>. + */ + ACE_Buffered_Svc_Handler (ACE_Thread_Manager *thr_mgr = 0, + ACE_Message_Queue<ACE_SYNCH_USE> *mq = 0, + ACE_Reactor *reactor = ACE_Reactor::instance (), + size_t max_buffer_size = 0, + ACE_Time_Value *relative_timeout = 0); + + /// Destructor, which calls <flush>. + virtual ~ACE_Buffered_Svc_Handler (void); + + /** + * Insert the ACE_Message_Block chain rooted at <message_block> + * into the ACE_Message_Queue with the designated <timeout>. The + * <flush> method will be called if this <put> causes the number of + * bytes to exceed the maximum buffer size or if the timeout period + * has elapsed. + */ + virtual int put (ACE_Message_Block *message_block, + ACE_Time_Value *timeout = 0); + + /// Flush the ACE_Message_Queue, which writes all the queued + /// ACE_Message_Blocks to the <PEER_STREAM>. + virtual int flush (void); + + /// This method is not currently implemented -- this is where the + /// integration with the <Reactor> would occur. + virtual int handle_timeout (const ACE_Time_Value &time, + const void *); + + /// Dump the state of an object. + void dump (void) const; + +protected: + /// Implement the flush operation on the ACE_Message_Queue, which + /// writes all the queued ACE_Message_Blocks to the <PEER_STREAM>. + /// Assumes that the caller holds the lock. + virtual int flush_i (void); + + /// Maximum size the <Message_Queue> can be before we have to flush + /// the buffer. + size_t maximum_buffer_size_; + + /// Current size in bytes of the <Message_Queue> contents. + size_t current_buffer_size_; + + /// Timeout value used to control when the buffer is flushed. + ACE_Time_Value next_timeout_; + + /// Interval of the timeout. + ACE_Time_Value interval_; + + /// Timeout pointer. + ACE_Time_Value *timeoutp_; +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Svc_Handler.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Svc_Handler.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#include /**/ "ace/post.h" + +#endif /* ACE_SVC_HANDLER_H */ |