Server_Request.cpp

Go to the documentation of this file.
00001 // $Id: Server_Request.cpp 78631 2007-06-28 13:49:10Z johnnyw $
00002 
00003 // Implementation of the Dynamic Server Skeleton Interface.
00004 
00005 #include "tao/DynamicInterface/Server_Request.h"
00006 
00007 ACE_RCSID (DynamicInterface,
00008            Server_Request,
00009            "$Id: Server_Request.cpp 78631 2007-06-28 13:49:10Z johnnyw $")
00010 
00011 #include "tao/AnyTypeCode/NVList.h"
00012 #include "tao/GIOP_Utils.h"
00013 #include "tao/AnyTypeCode/Marshal.h"
00014 #include "tao/AnyTypeCode/TypeCode.h"
00015 #include "tao/AnyTypeCode/Any_Impl.h"
00016 #include "tao/SystemException.h"
00017 
00018 #if !defined (__ACE_INLINE__)
00019 # include "tao/DynamicInterface/Server_Request.inl"
00020 #endif /* ! __ACE_INLINE__ */
00021 
00022 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00023 
00024 // Reference counting for DSI ServerRequest object.
00025 
00026 CORBA::ULong
00027 CORBA::ServerRequest::_incr_refcnt (void)
00028 {
00029   return ++this->refcount_;
00030 }
00031 
00032 CORBA::ULong
00033 CORBA::ServerRequest::_decr_refcnt (void)
00034 {
00035   CORBA::ULong const new_count = --this->refcount_;
00036 
00037   if (new_count == 0)
00038     delete this;
00039 
00040   return new_count;
00041 }
00042 
00043 CORBA::ServerRequest::ServerRequest (TAO_ServerRequest &orb_server_request)
00044   : lazy_evaluation_ (0),
00045     ctx_ (CORBA::Context::_nil ()),
00046     params_ (CORBA::NVList::_nil ()),
00047     retval_ (0),
00048     exception_ (0),
00049     refcount_ (1),
00050     orb_server_request_ (orb_server_request),
00051     sent_gateway_exception_ (false)
00052 {
00053   this->orb_server_request_.is_dsi ();
00054 }
00055 
00056 CORBA::ServerRequest::~ServerRequest (void)
00057 {
00058   if (this->params_ != 0)
00059     {
00060       ::CORBA::release (this->params_);
00061     }
00062 
00063   delete this->retval_;
00064   delete this->exception_;
00065 }
00066 
00067 // Unmarshal in/inout params, and set up to marshal the appropriate
00068 // inout/out/return values later on.
00069 void
00070 CORBA::ServerRequest::arguments (CORBA::NVList_ptr &list)
00071 {
00072   // arguments() must be called before either of these.
00073   if (this->params_ != 0 || this->exception_ != 0)
00074     {
00075       throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 7, CORBA::COMPLETED_NO);
00076     }
00077 
00078   // Save params for later use when marshaling the reply.
00079   this->params_ = list;
00080 
00081   this->params_->_tao_incoming_cdr (*this->orb_server_request_.incoming (),
00082                                     CORBA::ARG_IN | CORBA::ARG_INOUT,
00083                                     this->lazy_evaluation_);
00084 
00085   // Pass this alignment back to the TAO_ServerRequest.
00086   this->orb_server_request_.dsi_nvlist_align (
00087                                 this->params_->_tao_target_alignment ());
00088 }
00089 
00090 // Store the result value.  There's either an exception, or a result,
00091 // but not both of them.  Results can be reported (at most once)
00092 // only after the parameter list has been provided (maybe empty).
00093 void
00094 CORBA::ServerRequest::set_result (const CORBA::Any &value
00095                                   )
00096 {
00097   // Setting a result when another result already exists or if an exception
00098   // exists or before the args have been processeed is an error.
00099   if (this->retval_ != 0 || this->exception_ != 0 || this->params_ == 0)
00100     {
00101       throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 8, CORBA::COMPLETED_NO);
00102     }
00103 
00104   ACE_NEW_THROW_EX (this->retval_,
00105                     CORBA::Any (value),
00106                     CORBA::NO_MEMORY ());
00107 }
00108 
00109   // NOTE: if "" is set, there has been a system exception,
00110   // and it will take precedence over exceptions reported using the
00111   // set_exception() mechanism of the ServerRequest, which we assume
00112   // the application writer will use to report only user exceptions.
00113   // If both types of exception happen on the same invocation, the user
00114   // exception will be lost.
00115 
00116 // Store the exception value.
00117 void
00118 CORBA::ServerRequest::set_exception (const CORBA::Any &value)
00119 {
00120   CORBA::TypeCode_var tc = value.type ();
00121 
00122   CORBA::TCKind const kind = tc->kind ();
00123 
00124   // set_exception() can be called at any time, but the Any arg MUST
00125   // contain an exception.
00126   if (kind != CORBA::tk_except)
00127     {
00128       throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 21, CORBA::COMPLETED_MAYBE);
00129     }
00130 
00131   ACE_NEW_THROW_EX (this->exception_,
00132                     CORBA::Any (value),
00133                     CORBA::NO_MEMORY ());
00134 
00135   this->orb_server_request_.exception_type (TAO_GIOP_USER_EXCEPTION);
00136 }
00137 
00138 // This method will be utilized by the DSI servant to marshal outgoing
00139 // parameters.
00140 void
00141 CORBA::ServerRequest::dsi_marshal (void)
00142 {
00143   // There was a user exception, no need to marshal any parameters.
00144   if (this->sent_gateway_exception_)
00145     {
00146       return;
00147     }
00148 
00149   if (this->orb_server_request_.exception_type () == TAO_GIOP_NO_EXCEPTION)
00150     {
00151       // In DSI, we can't rely on the skeleton to do this.
00152       if (this->retval_ == 0 && this->params_ == 0)
00153         {
00154           this->orb_server_request_.argument_flag (0);
00155         }
00156 
00157       this->orb_server_request_.init_reply ();
00158 
00159       // Send the return value, if any.
00160       if (this->retval_ != 0)
00161         {
00162           this->retval_->impl ()->marshal_value (
00163                                       *this->orb_server_request_.outgoing ());
00164         }
00165 
00166       // Send the "inout" and "out" parameters.
00167       if (this->params_ != 0)
00168         {
00169           this->params_->_tao_encode (
00170                              *this->orb_server_request_.outgoing (),
00171                              CORBA::ARG_INOUT | CORBA::ARG_OUT);
00172         }
00173     }
00174   else
00175     {
00176       // This defaults to 1, but just to be safe...
00177       this->orb_server_request_.argument_flag (1);
00178 
00179       // Write the reply header to the ORB request's outgoing CDR stream.
00180       this->orb_server_request_.init_reply ();
00181 
00182       this->exception_->impl ()->marshal_value (
00183                                      *this->orb_server_request_.outgoing ());
00184     }
00185 
00186   this->orb_server_request_.tao_send_reply ();
00187 }
00188 
00189 void
00190 CORBA::ServerRequest::gateway_exception_reply (ACE_CString &raw_exception)
00191 {
00192   // This defaults to 1, but just to be safe...
00193   this->orb_server_request_.argument_flag (1);
00194 
00195   // This reply path handles only user exceptions.
00196   this->orb_server_request_.exception_type (TAO_GIOP_USER_EXCEPTION);
00197 
00198   this->orb_server_request_.init_reply ();
00199 
00200   // We know nothing about this exception, so we marshal it as a block
00201   // of bytes. The outgoing stream's byte order has already been matched
00202   // to the original source of the reply.
00203   this->orb_server_request_.outgoing ()->write_octet_array (
00204       reinterpret_cast<const CORBA::Octet *> (raw_exception.fast_rep ()),
00205       static_cast<CORBA::ULong> (raw_exception.length () + ACE_CDR::MAX_ALIGNMENT)
00206     );
00207 
00208   // This will prevent the marshaling of any parameters into this reply.
00209   this->sent_gateway_exception_ = true;
00210 
00211   this->orb_server_request_.tao_send_reply ();
00212 }
00213 
00214 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 13:37:31 2008 for TAO_DynamicInterface by doxygen 1.3.6