summaryrefslogtreecommitdiff
path: root/TAO/tao/PortableServer/AMH_Response_Handler.h
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/PortableServer/AMH_Response_Handler.h')
-rw-r--r--TAO/tao/PortableServer/AMH_Response_Handler.h216
1 files changed, 216 insertions, 0 deletions
diff --git a/TAO/tao/PortableServer/AMH_Response_Handler.h b/TAO/tao/PortableServer/AMH_Response_Handler.h
new file mode 100644
index 00000000000..cd94fbab058
--- /dev/null
+++ b/TAO/tao/PortableServer/AMH_Response_Handler.h
@@ -0,0 +1,216 @@
+// -*- C++ -*-
+
+// =========================================================================
+/**
+ * @file AMH_Response_Handler.h
+ *
+ * $Id$
+ *
+ * @author Mayur Deshpande <mayur@ics.uci.edu>
+ *
+ */
+// =========================================================================
+
+#ifndef TAO_AMH_RESPONSE_HANDLER_H
+#define TAO_AMH_RESPONSE_HANDLER_H
+
+#include "portableserver_export.h"
+
+#include "tao/Allocator.h"
+#include "tao/Service_Context.h"
+#include "tao/CDR.h"
+#include "tao/LocalObject.h"
+#include "tao/Buffer_Allocator_T.h"
+#include "ace/Synch_Traits.h"
+#include "ace/Thread_Mutex.h"
+#include "ace/Null_Mutex.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class TAO_Transport;
+class TAO_Pluggable_Messaging;
+class TAO_Output_CDR;
+class TAO_ORB_Core;
+class TAO_ServerRequest;
+class ACE_Allocator;
+
+typedef ACE_Allocator TAO_AMH_BUFFER_ALLOCATOR;
+
+/**
+ * @class TAO_AMH_Response_Handler
+ *
+ * @brief Class representing an Asynchronous-Method-Handling (AMH)
+ * ResponseHandler (RH) object.
+ *
+ * Class encapsulates state required to send a response back to the
+ * client independent of the thread that originally created the state
+ * on the activation-record. Thus the required state (copied from
+ * TAO_Server_Request) is 'stored' on the heap.
+ *
+ * One RH is created for every client request and the RH can be used
+ * only once i.e., the asynchronous method can be called only once.
+ * This class also encapsulates various initialisation and
+ * response-sending functionality that is common to all RHs (generated
+ * by the IDL compiler). Thus the IDL-compiler has to generate less
+ * code which in turn reduces the overall code size for an
+ * application.
+ */
+class TAO_PortableServer_Export TAO_AMH_Response_Handler
+// @@ Mayur, this is not the correct way to use
+// TAO_LocalRefCounted_Object. Application code is supposed to use
+// it when necessary. You're forcing applications to use a
+// reference counted version of their AMH_Response_Handler. This
+// isn't consistent with the specified semantics detailed in the
+// CCM spec. Please remove this and place it where appropriate in
+// your AMH tests and examples.
+ : virtual public TAO_Local_RefCounted_Object
+{
+public:
+
+ /// Constructor
+ TAO_AMH_Response_Handler ();
+
+ /// Destructor
+ /**
+ * Releases the transport and in case of an error, sends the appropriate
+ * exception back to the client
+ */
+ virtual ~TAO_AMH_Response_Handler (void);
+
+ /**
+ * Stores necessary information from a TAO_Server_Request onto the heap
+ */
+ virtual void init(TAO_ServerRequest &server_request,
+ TAO_AMH_BUFFER_ALLOCATOR* allocator);
+
+ /// @name Mutators for refcount
+ //@{
+ virtual void _remove_ref (void);
+ //@}
+
+protected:
+
+ /// Sets up the various parameters in anticipation of returning a reply
+ /// to the client. return/OUT/INOUT arguments are marshalled into the
+ /// Output stream after this method has been called.
+ void _tao_rh_init_reply (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Sends the marshalled reply back to the client.
+ void _tao_rh_send_reply (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Send back an exception to the client.
+ void _tao_rh_send_exception (CORBA::Exception &ex
+ ACE_ENV_ARG_DECL);
+
+protected:
+
+ /// The outgoing CDR stream
+ /**
+ * The IDL-generated ResponseHandler implementations used this field
+ * to marshal the response.
+ * Making it a field instead of a public accessor makes the code in
+ * the generated ResponseHandler implementation a lot more readable.
+ */
+ TAO_OutputCDR _tao_out;
+
+private:
+
+ // Private and undefined, standard C++ idiom to prohibit copying.
+ ACE_UNIMPLEMENTED_FUNC (TAO_AMH_Response_Handler (const TAO_AMH_Response_Handler&))
+ ACE_UNIMPLEMENTED_FUNC (TAO_AMH_Response_Handler& operator= (const TAO_AMH_Response_Handler&))
+
+private:
+ /// Pointer to the original message-base
+ TAO_Pluggable_Messaging *mesg_base_;
+
+ /// Copy of the request-id of the original Server-Request
+ CORBA::ULong request_id_;
+
+ CORBA::Boolean response_expected_;
+
+ /// Handle to transport through which the reply will be sent
+ /// Copy of transport in original Server_Request
+ TAO_Transport *transport_;
+
+ /// A pointer to the ORB Core for the context where the request was
+ /// created.
+ TAO_ORB_Core *orb_core_;
+
+ /// The reply service context
+ TAO_Service_Context reply_service_context_;
+
+ /// Alwyas set to true (we always have something to return to the
+ /// client
+ // @@ Mayur: I think not! This is used to generate padding in GIOP
+ // 1.2 messages (where the payload must start on an 8-byte
+ // boundary. But some replys have no payload (only header), in
+ // those cases you cannot insert the padding. We need the
+ // ResponseHandler to set this field correctly!
+ CORBA::Boolean argument_flag_;
+
+ // TAO_GIOP_ReplyStatusType exception_type_;
+ /// Exception type (will be NO_EXCEPTION in the majority of the
+ /// cases).
+ // @@ Mayur: I do not think we need this one, we can deduce the type
+ // of reply depending on the _tao_rh_*() method called.
+ CORBA::ULong exception_type_;
+
+ /**
+ * Various states the ResponseHandler can be in.
+ *
+ * These states represent various states the RH can be in and
+ * the states are used not only in implementing the 'once-only semantics of
+ * RHs, but in making sure well the call thread-safe as well.
+ */
+ enum Reply_Status
+ {
+ TAO_RS_UNINITIALIZED,
+ TAO_RS_INITIALIZED,
+ TAO_RS_SENDING,
+ TAO_RS_SENT
+ };
+ Reply_Status reply_status_;
+ // I would use the "state pattern"..
+ // Carlos, Isn't that an overkill?
+ // @@ Mayur: it depends on what form of the "State Pattern" you
+ // use. The more generic form, as described in GoF, uses a class
+ // for each state, super-elegant but indeed a bit heavy handed.
+ // The lighter-weight form (using a state variable
+
+ /// Mutex to ensure the AMH-RH method call is thread-safe.
+ ACE_SYNCH_MUTEX mutex_;
+
+ /// Allocator used to allocate this object. If zero then we are allocated
+ /// from the heap
+ TAO_AMH_BUFFER_ALLOCATOR* allocator_;
+};
+
+namespace TAO
+{
+ /**
+ * @class ARH_Refcount_Functor
+ *
+ * @brief Functor for refcounting of TAO_AMH_Response_Handler
+ *
+ * This is used to safely handle the destruction of
+ * TAO_AMH_Response_Handler objects which are created on the
+ * heap. We cannot use auto_ptr <> since it calls delete on the
+ * pointer, and calling delete on TAO_AMH_Response_Handler *
+ * will not work. Hence this functor will be used with Auto_Functor
+ * class to handle the memory safely.
+ *
+ * @todo Ideally, this class can be a generic class. But that
+ * requires quite a bit of cleanup within TAO to be more useful.
+ */
+ class TAO_PortableServer_Export ARH_Refcount_Functor
+ {
+ public:
+ void operator() (TAO_AMH_Response_Handler *arh)
+ ACE_THROW_SPEC (());
+ };
+
+}
+
+#endif /* TAO_AMH_RESPONSE_HANDLER_H */