Server_Request.cpp

Go to the documentation of this file.
00001 // Server_Request.cpp,v 1.31 2006/04/19 09:40:15 jwillemsen Exp
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            "Server_Request.cpp,v 1.31 2006/04/19 09:40:15 jwillemsen Exp")
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   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00030                     ace_mon,
00031                     this->lock_,
00032                     0);
00033 
00034   return ++this->refcount_;
00035 }
00036 
00037 CORBA::ULong
00038 CORBA::ServerRequest::_decr_refcnt (void)
00039 {
00040   {
00041     ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00042                       ace_mon,
00043                       this->lock_,
00044                       0);
00045 
00046     --this->refcount_;
00047 
00048     if (this->refcount_ != 0)
00049       {
00050         return this->refcount_;
00051       }
00052   }
00053 
00054   delete this;
00055   return 0;
00056 }
00057 
00058 CORBA::ServerRequest::ServerRequest (TAO_ServerRequest &orb_server_request)
00059   : lazy_evaluation_ (0),
00060     ctx_ (CORBA::Context::_nil ()),
00061     params_ (CORBA::NVList::_nil ()),
00062     retval_ (0),
00063     exception_ (0),
00064     refcount_ (1),
00065     orb_server_request_ (orb_server_request),
00066     sent_gateway_exception_ (0)
00067 {
00068   this->orb_server_request_.is_dsi ();
00069 }
00070 
00071 CORBA::ServerRequest::~ServerRequest (void)
00072 {
00073   if (this->params_ != 0)
00074     {
00075       ::CORBA::release (this->params_);
00076     }
00077 
00078   delete this->retval_;
00079   delete this->exception_;
00080 }
00081 
00082 // Unmarshal in/inout params, and set up to marshal the appropriate
00083 // inout/out/return values later on.
00084 void
00085 CORBA::ServerRequest::arguments (CORBA::NVList_ptr &list
00086                                  ACE_ENV_ARG_DECL)
00087 {
00088   // arguments() must be called before either of these.
00089   if (this->params_ != 0 || this->exception_ != 0)
00090     {
00091       ACE_THROW (CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 7, CORBA::COMPLETED_NO));
00092     }
00093 
00094   // Save params for later use when marshaling the reply.
00095   this->params_ = list;
00096 
00097   this->params_->_tao_incoming_cdr (*this->orb_server_request_.incoming (),
00098                                     CORBA::ARG_IN | CORBA::ARG_INOUT,
00099                                     this->lazy_evaluation_
00100                                     ACE_ENV_ARG_PARAMETER);
00101   ACE_CHECK;
00102 
00103   // Pass this alignment back to the TAO_ServerRequest.
00104   this->orb_server_request_.dsi_nvlist_align (
00105                                 this->params_->_tao_target_alignment ()
00106                               );
00107 }
00108 
00109 // Store the result value.  There's either an exception, or a result,
00110 // but not both of them.  Results can be reported (at most once)
00111 // only after the parameter list has been provided (maybe empty).
00112 void
00113 CORBA::ServerRequest::set_result (const CORBA::Any &value
00114                                   ACE_ENV_ARG_DECL)
00115 {
00116   // Setting a result when another result already exists or if an exception
00117   // exists or before the args have been processeed is an error.
00118   if (this->retval_ != 0 || this->exception_ != 0 || this->params_ == 0)
00119     {
00120       ACE_THROW (CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 8, CORBA::COMPLETED_NO));
00121     }
00122 
00123   ACE_NEW_THROW_EX (this->retval_,
00124                     CORBA::Any (value),
00125                     CORBA::NO_MEMORY ());
00126   ACE_CHECK;
00127 }
00128 
00129   // NOTE: if "ACE_ENV_SINGLE_ARG_PARAMETER" is set, there has been a system exception,
00130   // and it will take precedence over exceptions reported using the
00131   // set_exception() mechanism of the ServerRequest, which we assume
00132   // the application writer will use to report only user exceptions.
00133   // If both types of exception happen on the same invocation, the user
00134   // exception will be lost.
00135 
00136 // Store the exception value.
00137 void
00138 CORBA::ServerRequest::set_exception (const CORBA::Any &value
00139                                      ACE_ENV_ARG_DECL)
00140 {
00141   CORBA::TypeCode_var tc = value.type ();
00142 
00143   CORBA::TCKind const kind = tc->kind (ACE_ENV_SINGLE_ARG_PARAMETER);
00144   ACE_CHECK;
00145 
00146   // set_exception() can be called at any time, but the Any arg MUST
00147   // contain an exception.
00148   if (kind != CORBA::tk_except)
00149     {
00150       ACE_THROW (CORBA::BAD_PARAM (CORBA::OMGVMCID | 21,
00151                                    CORBA::COMPLETED_MAYBE));
00152     }
00153 
00154   ACE_NEW_THROW_EX (this->exception_,
00155                     CORBA::Any (value),
00156                     CORBA::NO_MEMORY ());
00157   ACE_CHECK;
00158 
00159   this->orb_server_request_.exception_type (TAO_GIOP_USER_EXCEPTION);
00160 }
00161 
00162 // This method will be utilized by the DSI servant to marshal outgoing
00163 // parameters.
00164 void
00165 CORBA::ServerRequest::dsi_marshal (ACE_ENV_SINGLE_ARG_DECL)
00166 {
00167   // There was a user exception, no need to marshal any parameters.
00168   if (this->sent_gateway_exception_)
00169     {
00170       return;
00171     }
00172 
00173   if (this->orb_server_request_.exception_type () == TAO_GIOP_NO_EXCEPTION)
00174     {
00175       // In DSI, we can't rely on the skeleton to do this.
00176       if (this->retval_ == 0 && this->params_ == 0)
00177         {
00178           this->orb_server_request_.argument_flag (0);
00179         }
00180 
00181       this->orb_server_request_.init_reply ();
00182 
00183       // Send the return value, if any.
00184       if (this->retval_ != 0)
00185         {
00186           this->retval_->impl ()->marshal_value (
00187                                       *this->orb_server_request_.outgoing ()
00188                                     );
00189         }
00190 
00191       // Send the "inout" and "out" parameters.
00192       if (this->params_ != 0)
00193         {
00194           this->params_->_tao_encode (
00195                              *this->orb_server_request_.outgoing (),
00196                              CORBA::ARG_INOUT | CORBA::ARG_OUT
00197                              ACE_ENV_ARG_PARAMETER
00198                            );
00199           ACE_CHECK;
00200         }
00201     }
00202   else
00203     {
00204       // This defaults to 1, but just to be safe...
00205       this->orb_server_request_.argument_flag (1);
00206 
00207       // Write the reply header to the ORB request's outgoing CDR stream.
00208       this->orb_server_request_.init_reply ();
00209 
00210       this->exception_->impl ()->marshal_value (
00211                                      *this->orb_server_request_.outgoing ()
00212                                    );
00213     }
00214 
00215   this->orb_server_request_.tao_send_reply ();
00216 }
00217 
00218 void
00219 CORBA::ServerRequest::gateway_exception_reply (ACE_CString &raw_exception)
00220 {
00221   // This defaults to 1, but just to be safe...
00222   this->orb_server_request_.argument_flag (1);
00223 
00224   // This reply path handles only user exceptions.
00225   this->orb_server_request_.exception_type (TAO_GIOP_USER_EXCEPTION);
00226 
00227   this->orb_server_request_.init_reply ();
00228 
00229   // We know nothing about this exception, so we marshal it as a block
00230   // of bytes. The outgoing stream's byte order has already been matched
00231   // to the original source of the reply.
00232   this->orb_server_request_.outgoing ()->write_octet_array (
00233       reinterpret_cast<const CORBA::Octet *> (raw_exception.fast_rep ()),
00234       static_cast<CORBA::ULong> (raw_exception.length () + ACE_CDR::MAX_ALIGNMENT)
00235     );
00236 
00237   // This will prevent the marshaling of any parameters into this reply.
00238   this->sent_gateway_exception_ = 1;
00239 
00240   this->orb_server_request_.tao_send_reply ();
00241 }
00242 
00243 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 13:04:21 2006 for TAO_DynamicInterface by doxygen 1.3.6