summaryrefslogtreecommitdiff
path: root/TAO/tao/DynamicInterface/Server_Request.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/DynamicInterface/Server_Request.cpp')
-rw-r--r--TAO/tao/DynamicInterface/Server_Request.cpp229
1 files changed, 229 insertions, 0 deletions
diff --git a/TAO/tao/DynamicInterface/Server_Request.cpp b/TAO/tao/DynamicInterface/Server_Request.cpp
new file mode 100644
index 00000000000..a34ce8e1fe2
--- /dev/null
+++ b/TAO/tao/DynamicInterface/Server_Request.cpp
@@ -0,0 +1,229 @@
+// $Id$
+
+// Implementation of the Dynamic Server Skeleton Interface.
+
+#include "tao/DynamicInterface/Server_Request.h"
+
+ACE_RCSID (DynamicInterface,
+ Server_Request,
+ "$Id$")
+
+#include "tao/AnyTypeCode/NVList.h"
+#include "tao/GIOP_Utils.h"
+#include "tao/AnyTypeCode/Marshal.h"
+#include "tao/AnyTypeCode/TypeCode.h"
+#include "tao/AnyTypeCode/Any_Impl.h"
+#include "tao/SystemException.h"
+
+#if !defined (__ACE_INLINE__)
+# include "tao/DynamicInterface/Server_Request.inl"
+#endif /* ! __ACE_INLINE__ */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+// Reference counting for DSI ServerRequest object.
+
+CORBA::ULong
+CORBA::ServerRequest::_incr_refcnt (void)
+{
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ ace_mon,
+ this->lock_,
+ 0);
+
+ return ++this->refcount_;
+}
+
+CORBA::ULong
+CORBA::ServerRequest::_decr_refcnt (void)
+{
+ {
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
+ ace_mon,
+ this->lock_,
+ 0);
+
+ --this->refcount_;
+
+ if (this->refcount_ != 0)
+ {
+ return this->refcount_;
+ }
+ }
+
+ delete this;
+ return 0;
+}
+
+CORBA::ServerRequest::ServerRequest (TAO_ServerRequest &orb_server_request)
+ : lazy_evaluation_ (0),
+ ctx_ (CORBA::Context::_nil ()),
+ params_ (CORBA::NVList::_nil ()),
+ retval_ (0),
+ exception_ (0),
+ refcount_ (1),
+ orb_server_request_ (orb_server_request),
+ sent_gateway_exception_ (false)
+{
+ this->orb_server_request_.is_dsi ();
+}
+
+CORBA::ServerRequest::~ServerRequest (void)
+{
+ if (this->params_ != 0)
+ {
+ ::CORBA::release (this->params_);
+ }
+
+ delete this->retval_;
+ delete this->exception_;
+}
+
+// Unmarshal in/inout params, and set up to marshal the appropriate
+// inout/out/return values later on.
+void
+CORBA::ServerRequest::arguments (CORBA::NVList_ptr &list)
+{
+ // arguments() must be called before either of these.
+ if (this->params_ != 0 || this->exception_ != 0)
+ {
+ throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 7, CORBA::COMPLETED_NO);
+ }
+
+ // Save params for later use when marshaling the reply.
+ this->params_ = list;
+
+ this->params_->_tao_incoming_cdr (*this->orb_server_request_.incoming (),
+ CORBA::ARG_IN | CORBA::ARG_INOUT,
+ this->lazy_evaluation_);
+
+ // Pass this alignment back to the TAO_ServerRequest.
+ this->orb_server_request_.dsi_nvlist_align (
+ this->params_->_tao_target_alignment ());
+}
+
+// Store the result value. There's either an exception, or a result,
+// but not both of them. Results can be reported (at most once)
+// only after the parameter list has been provided (maybe empty).
+void
+CORBA::ServerRequest::set_result (const CORBA::Any &value
+ )
+{
+ // Setting a result when another result already exists or if an exception
+ // exists or before the args have been processeed is an error.
+ if (this->retval_ != 0 || this->exception_ != 0 || this->params_ == 0)
+ {
+ throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 8, CORBA::COMPLETED_NO);
+ }
+
+ ACE_NEW_THROW_EX (this->retval_,
+ CORBA::Any (value),
+ CORBA::NO_MEMORY ());
+}
+
+ // NOTE: if "" is set, there has been a system exception,
+ // and it will take precedence over exceptions reported using the
+ // set_exception() mechanism of the ServerRequest, which we assume
+ // the application writer will use to report only user exceptions.
+ // If both types of exception happen on the same invocation, the user
+ // exception will be lost.
+
+// Store the exception value.
+void
+CORBA::ServerRequest::set_exception (const CORBA::Any &value)
+{
+ CORBA::TypeCode_var tc = value.type ();
+
+ CORBA::TCKind const kind = tc->kind ();
+
+ // set_exception() can be called at any time, but the Any arg MUST
+ // contain an exception.
+ if (kind != CORBA::tk_except)
+ {
+ throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 21, CORBA::COMPLETED_MAYBE);
+ }
+
+ ACE_NEW_THROW_EX (this->exception_,
+ CORBA::Any (value),
+ CORBA::NO_MEMORY ());
+
+ this->orb_server_request_.exception_type (TAO_GIOP_USER_EXCEPTION);
+}
+
+// This method will be utilized by the DSI servant to marshal outgoing
+// parameters.
+void
+CORBA::ServerRequest::dsi_marshal (void)
+{
+ // There was a user exception, no need to marshal any parameters.
+ if (this->sent_gateway_exception_)
+ {
+ return;
+ }
+
+ if (this->orb_server_request_.exception_type () == TAO_GIOP_NO_EXCEPTION)
+ {
+ // In DSI, we can't rely on the skeleton to do this.
+ if (this->retval_ == 0 && this->params_ == 0)
+ {
+ this->orb_server_request_.argument_flag (0);
+ }
+
+ this->orb_server_request_.init_reply ();
+
+ // Send the return value, if any.
+ if (this->retval_ != 0)
+ {
+ this->retval_->impl ()->marshal_value (
+ *this->orb_server_request_.outgoing ());
+ }
+
+ // Send the "inout" and "out" parameters.
+ if (this->params_ != 0)
+ {
+ this->params_->_tao_encode (
+ *this->orb_server_request_.outgoing (),
+ CORBA::ARG_INOUT | CORBA::ARG_OUT);
+ }
+ }
+ else
+ {
+ // This defaults to 1, but just to be safe...
+ this->orb_server_request_.argument_flag (1);
+
+ // Write the reply header to the ORB request's outgoing CDR stream.
+ this->orb_server_request_.init_reply ();
+
+ this->exception_->impl ()->marshal_value (
+ *this->orb_server_request_.outgoing ());
+ }
+
+ this->orb_server_request_.tao_send_reply ();
+}
+
+void
+CORBA::ServerRequest::gateway_exception_reply (ACE_CString &raw_exception)
+{
+ // This defaults to 1, but just to be safe...
+ this->orb_server_request_.argument_flag (1);
+
+ // This reply path handles only user exceptions.
+ this->orb_server_request_.exception_type (TAO_GIOP_USER_EXCEPTION);
+
+ this->orb_server_request_.init_reply ();
+
+ // We know nothing about this exception, so we marshal it as a block
+ // of bytes. The outgoing stream's byte order has already been matched
+ // to the original source of the reply.
+ this->orb_server_request_.outgoing ()->write_octet_array (
+ reinterpret_cast<const CORBA::Octet *> (raw_exception.fast_rep ()),
+ static_cast<CORBA::ULong> (raw_exception.length () + ACE_CDR::MAX_ALIGNMENT)
+ );
+
+ // This will prevent the marshaling of any parameters into this reply.
+ this->sent_gateway_exception_ = true;
+
+ this->orb_server_request_.tao_send_reply ();
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL