// -*- C++ -*- #include "tao/PortableServer/Servant_Base.h" #include "tao/PortableServer/Root_POA.h" #include "tao/PortableServer/Operation_Table.h" #include "tao/PortableServer/POA_Current_Impl.h" #include "tao/PortableServer/Direct_Collocation_Upcall_Wrapper.h" #include "tao/PortableInterceptor.h" #include "tao/PortableServer/SUpcall_commands.h" #include "tao/PortableServer/SArg_Traits_T.h" #include "tao/PortableServer/Basic_SArguments.h" #include "tao/PortableServer/Special_Basic_SArguments.h" #include "tao/PortableServer/Fixed_Size_SArgument_T.h" #include "tao/PortableServer/Var_Size_SArgument_T.h" #include "tao/PortableServer/Object_SArg_Traits.h" #include "tao/PortableServer/UB_String_SArguments.h" #include "tao/PortableServer/get_arg.h" #include "tao/Object.h" #include "tao/Timeprobe.h" #include "tao/ORB_Core.h" #include "tao/TSS_Resources.h" #include "tao/Stub.h" #include "tao/TAO_Server_Request.h" #include "tao/IFR_Client_Adapter.h" #include "tao/Basic_Types.h" #include "ace/Dynamic_Service.h" #include "ace/OS_NS_string.h" #if !defined (__ACE_INLINE__) # include "tao/PortableServer/Servant_Base.inl" #endif /* ! __ACE_INLINE__ */ #if defined (ACE_ENABLE_TIMEPROBES) static const char *TAO_ServantBase_Timeprobe_Description[] = { "TAO_ServantBase::_find - start", "TAO_ServantBase::_find - end" }; enum { TAO_SERVANT_BASE_FIND_START = 700, TAO_SERVANT_BASE_FIND_END }; // Setup Timeprobes ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_ServantBase_Timeprobe_Description, TAO_SERVANT_BASE_FIND_START); #endif /* ACE_ENABLE_TIMEPROBES */ TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_ServantBase::TAO_ServantBase (TAO_Operation_Table* optable) : TAO_Abstract_ServantBase () , ref_count_ (1) , optable_ (optable) { } TAO_ServantBase::TAO_ServantBase (const TAO_ServantBase &rhs) : TAO_Abstract_ServantBase () , ref_count_ (1) , optable_ (rhs.optable_) { } TAO_ServantBase & TAO_ServantBase::operator= (const TAO_ServantBase &rhs) { if (this != &rhs) { this->optable_ = rhs.optable_; } return *this; } TAO_ServantBase::~TAO_ServantBase () { } PortableServer::POA_ptr TAO_ServantBase::_default_POA () { CORBA::Object_var object = TAO_ORB_Core_instance ()->root_poa (); return PortableServer::POA::_narrow (object.in ()); } void TAO_ServantBase::_is_a_skel (TAO_ServerRequest & server_request, TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR(servant_upcall), TAO_ServantBase *servant) { #if TAO_HAS_INTERCEPTORS == 1 static ::CORBA::TypeCode_ptr const * const exceptions = 0; static ::CORBA::ULong const nexceptions = 0; #endif /* TAO_HAS_INTERCEPTORS */ TAO::SArg_Traits< ::ACE_InputCDR::to_boolean>::ret_val retval; TAO::SArg_Traits< char *>::in_arg_val _tao_repository_id; TAO::Argument * const args[] = { &retval, &_tao_repository_id }; static size_t const nargs = 2; _is_a_Upcall_Command command ( servant, args); TAO::Upcall_Wrapper upcall_wrapper; upcall_wrapper.upcall (server_request , args , nargs , command #if TAO_HAS_INTERCEPTORS == 1 , servant_upcall , exceptions , nexceptions #endif /* TAO_HAS_INTERCEPTORS == 1 */ ); } void TAO_ServantBase::_is_a_thru_poa_skel (TAO_ServerRequest & server_request, TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall), TAO_ServantBase *servant) { #if TAO_HAS_INTERCEPTORS == 1 static ::CORBA::TypeCode_ptr const * const exceptions = 0; static ::CORBA::ULong const nexceptions = 0; #endif /* TAO_HAS_INTERCEPTORS */ TAO::SArg_Traits< ::ACE_InputCDR::to_boolean>::ret_val retval; TAO::SArg_Traits< char *>::in_arg_val _tao_repository_id; TAO::Argument * const args[] = { &retval, &_tao_repository_id }; static size_t const nargs = 2; _is_a_thru_poa_Upcall_Command command ( servant, server_request.operation_details (), args); TAO::Upcall_Wrapper upcall_wrapper; upcall_wrapper.upcall (server_request , args , nargs , command #if TAO_HAS_INTERCEPTORS == 1 , servant_upcall , exceptions , nexceptions #endif /* TAO_HAS_INTERCEPTORS == 1 */ ); } #if (TAO_HAS_MINIMUM_CORBA == 0) void TAO_ServantBase::_non_existent_skel (TAO_ServerRequest & server_request, TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall), TAO_ServantBase *servant) { #if TAO_HAS_INTERCEPTORS == 1 static ::CORBA::TypeCode_ptr const * const exceptions = 0; static ::CORBA::ULong const nexceptions = 0; #endif /* TAO_HAS_INTERCEPTORS */ TAO::SArg_Traits< ::ACE_InputCDR::to_boolean>::ret_val retval; TAO::Argument * const args[] = { &retval }; static size_t const nargs = 1; _non_existent_Upcall_Command command ( servant, args); TAO::Upcall_Wrapper upcall_wrapper; upcall_wrapper.upcall (server_request , args , nargs , command #if TAO_HAS_INTERCEPTORS == 1 , servant_upcall , exceptions , nexceptions #endif /* TAO_HAS_INTERCEPTORS == 1 */ ); } void TAO_ServantBase::_non_existent_thru_poa_skel (TAO_ServerRequest & server_request, TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall), TAO_ServantBase *servant) { #if TAO_HAS_INTERCEPTORS == 1 static ::CORBA::TypeCode_ptr const * const exceptions = 0; static ::CORBA::ULong const nexceptions = 0; #endif /* TAO_HAS_INTERCEPTORS */ TAO::SArg_Traits< ::ACE_InputCDR::to_boolean>::ret_val retval; TAO::Argument * const args[] = { &retval }; static size_t const nargs = 1; _non_existent_thru_poa_Upcall_Command command ( servant, server_request.operation_details (), args); TAO::Upcall_Wrapper upcall_wrapper; upcall_wrapper.upcall (server_request , args , nargs , command #if TAO_HAS_INTERCEPTORS == 1 , servant_upcall , exceptions , nexceptions #endif /* TAO_HAS_INTERCEPTORS == 1 */ ); } # if !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) void TAO_ServantBase::_interface_skel (TAO_ServerRequest & server_request, TAO::Portable_Server::Servant_Upcall* /* servant_upcall */, TAO_ServantBase *servant) { TAO_IFR_Client_Adapter *_tao_adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::ifr_client_adapter_name ()); if (!_tao_adapter) { throw ::CORBA::INTF_REPOS (::CORBA::OMGVMCID | 1, ::CORBA::COMPLETED_NO); } ::CORBA::InterfaceDef_ptr _tao_retval = servant->_get_interface (); server_request.init_reply (); TAO_OutputCDR &_tao_out = *server_request.outgoing (); ::CORBA::Boolean const _tao_result = _tao_adapter->interfacedef_cdr_insert (_tao_out, _tao_retval); _tao_adapter->dispose (_tao_retval); if (!_tao_result) { throw ::CORBA::MARSHAL (); } } void TAO_ServantBase::_component_skel (TAO_ServerRequest & server_request, TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall), TAO_ServantBase *servant) { #if TAO_HAS_INTERCEPTORS == 1 static ::CORBA::TypeCode_ptr const * const exceptions = 0; static ::CORBA::ULong const nexceptions = 0; #endif /* TAO_HAS_INTERCEPTORS */ TAO::SArg_Traits< ::CORBA::Object>::ret_val retval; TAO::Argument * const args[] = { &retval }; static size_t const nargs = 1; _get_component_Upcall_Command command ( servant, args); TAO::Upcall_Wrapper upcall_wrapper; upcall_wrapper.upcall (server_request , args , nargs , command #if TAO_HAS_INTERCEPTORS == 1 , servant_upcall , exceptions , nexceptions #endif /* TAO_HAS_INTERCEPTORS == 1 */ ); } void TAO_ServantBase::_component_thru_poa_skel (TAO_ServerRequest & server_request, TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall), TAO_ServantBase *servant) { #if TAO_HAS_INTERCEPTORS == 1 static ::CORBA::TypeCode_ptr const * const exceptions = 0; static ::CORBA::ULong const nexceptions = 0; #endif /* TAO_HAS_INTERCEPTORS */ TAO::SArg_Traits< ::CORBA::Object>::ret_val retval; TAO::Argument * const args[] = { &retval }; static size_t const nargs = 1; _get_component_thru_poa_Upcall_Command command ( servant, server_request.operation_details (), args); TAO::Upcall_Wrapper upcall_wrapper; upcall_wrapper.upcall (server_request , args , nargs , command #if TAO_HAS_INTERCEPTORS == 1 , servant_upcall , exceptions , nexceptions #endif /* TAO_HAS_INTERCEPTORS == 1 */ ); } # endif /* !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) */ void TAO_ServantBase::_repository_id_skel (TAO_ServerRequest & server_request, TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall), TAO_ServantBase *servant) { #if TAO_HAS_INTERCEPTORS == 1 static ::CORBA::TypeCode_ptr const * const exceptions = 0; static ::CORBA::ULong const nexceptions = 0; #endif /* TAO_HAS_INTERCEPTORS */ TAO::SArg_Traits< char *>::ret_val retval; TAO::Argument * const args[] = { &retval }; static size_t const nargs = 1; _repository_id_Upcall_Command command ( servant, args); TAO::Upcall_Wrapper upcall_wrapper; upcall_wrapper.upcall (server_request , args , nargs , command #if TAO_HAS_INTERCEPTORS == 1 , servant_upcall , exceptions , nexceptions #endif /* TAO_HAS_INTERCEPTORS == 1 */ ); } void TAO_ServantBase::_repository_id_thru_poa_skel (TAO_ServerRequest & server_request, TAO::Portable_Server::Servant_Upcall* TAO_INTERCEPTOR (servant_upcall), TAO_ServantBase *servant) { #if TAO_HAS_INTERCEPTORS == 1 static ::CORBA::TypeCode_ptr const * const exceptions = 0; static ::CORBA::ULong const nexceptions = 0; #endif /* TAO_HAS_INTERCEPTORS */ TAO::SArg_Traits< char *>::ret_val retval; TAO::Argument * const args[] = { &retval }; static size_t const nargs = 1; _repository_id_thru_poa_Upcall_Command command ( servant, server_request.operation_details (), args); TAO::Upcall_Wrapper upcall_wrapper; upcall_wrapper.upcall (server_request , args , nargs , command #if TAO_HAS_INTERCEPTORS == 1 , servant_upcall , exceptions , nexceptions #endif /* TAO_HAS_INTERCEPTORS == 1 */ ); } #endif /* TAO_HAS_MINIMUM_CORBA */ CORBA::Boolean TAO_ServantBase::_is_a (const char *logical_type_id) { static char const id[] = "IDL:omg.org/CORBA/Object:1.0"; return ACE_OS::strcmp (logical_type_id, id) == 0; } #if (TAO_HAS_MINIMUM_CORBA == 0) CORBA::Boolean TAO_ServantBase::_non_existent () { return false; } CORBA::InterfaceDef_ptr TAO_ServantBase::_get_interface () { TAO_IFR_Client_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::ifr_client_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTF_REPOS (); } // This doesn't take multiple ORBs into account, but it's being // used only to resolve the IFR, so we should be ok. return adapter->get_interface (TAO_ORB_Core_instance ()->orb (), this->_interface_repository_id ()); } #if !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) CORBA::Object_ptr TAO_ServantBase::_get_component () { return CORBA::Object::_nil (); } #endif char * TAO_ServantBase::_repository_id () { return CORBA::string_dup (this->_interface_repository_id ()); } #endif /* TAO_HAS_MINIMUM_CORBA */ int TAO_ServantBase::_find (const char *opname, TAO_Skeleton& skelfunc, const size_t length) { ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_BASE_FIND_START); return this->optable_->find (opname, skelfunc, static_cast (length)); } int TAO_ServantBase::_find (const char *opname, TAO_Collocated_Skeleton& skelfunc, TAO::Collocation_Strategy st, const size_t length) { ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_BASE_FIND_START); return this->optable_->find (opname, skelfunc, st, static_cast (length)); } TAO_Stub * TAO_ServantBase::_create_stub () { TAO_Stub *stub = 0; TAO::Portable_Server::POA_Current_Impl *poa_current_impl = static_cast (TAO_TSS_Resources::instance ()->poa_current_impl_); CORBA::ORB_ptr servant_orb = 0; if (poa_current_impl != 0 && this == poa_current_impl->servant ()) { servant_orb = poa_current_impl->orb_core ().orb () ; stub = poa_current_impl->poa ()->key_to_stub ( poa_current_impl->object_key (), this->_interface_repository_id (), poa_current_impl->priority ()); } else { PortableServer::POA_var poa = this->_default_POA (); CORBA::Object_var object = poa->servant_to_reference (this); // Get the stub object stub = object->_stubobj (); // Increment the reference count since will zap its // stub object on deletion. stub->_incr_refcnt (); servant_orb = stub->orb_core ()->orb (); } stub->servant_orb (servant_orb); return stub; } void TAO_ServantBase::synchronous_upcall_dispatch ( TAO_ServerRequest & req, TAO::Portable_Server::Servant_Upcall* servant_upcall, TAO_ServantBase *derived_this) { TAO_Skeleton skel; char const * const opname = req.operation (); // Handle the one ways that are SYNC_WITH_SERVER and not queued req.sync_after_dispatch (); // Fetch the skeleton for this operation if (this->_find (opname, skel, static_cast (req.operation_length())) == -1) { throw ::CORBA::BAD_OPERATION (); } CORBA::Boolean const send_reply = !req.sync_with_server () && req.response_expected () && !req.deferred_reply (); try { // Invoke the skeleton, it will demarshal the arguments, invoke // the right operation on the skeleton class, and marshal any // results. De/marshaling will only occur in the not collocated // case. skel (req, servant_upcall, derived_this); // It is our job to send the already marshaled reply, but only // send if it is expected and it has not already been sent // We send the reply only if it is NOT a SYNC_WITH_SERVER, a // response is expected and if the reply is not deferred. if (send_reply) { req.tao_send_reply (); } } catch (const ::CORBA::Exception& ex) { // If an exception was raised we should marshal it and send // the appropriate reply to the client if (send_reply) { if (req.collocated ()) { // Report the exception to the collocated client. throw; } else req.tao_send_reply_exception (ex); } } } void TAO_ServantBase::asynchronous_upcall_dispatch ( TAO_ServerRequest &req, TAO::Portable_Server::Servant_Upcall *servant_upcall, TAO_ServantBase *derived_this) { TAO_Skeleton skel; const char *opname = req.operation (); // It seems that I might have missed s/g here. What if // it is a one way that is SYNC_WITH_SERVER. // Add the following line to handle this reply send as well. // Handle the one ways that are SYNC_WITH_SERVER if (req.sync_with_server ()) { req.send_no_exception_reply (); } // Fetch the skeleton for this operation if (this->_find (opname, skel, static_cast (req.operation_length())) == -1) { throw ::CORBA::BAD_OPERATION (); } try { // Invoke the skeleton, it will demarshal the arguments, invoke // the right operation on the skeleton class, and marshal any // results. De/marshaling will only occur in the not collocated // case. skel (req, servant_upcall, derived_this); // It is our job to send the already marshaled reply, but only // send if it is expected and it has not already been sent // Return immediately. Do not send a reply; this is an // asynchronous upcall. (unless, of course there is a system // exception. } catch (const ::CORBA::Exception& ex) { // If an exception was raised we should marshal it and send // the appropriate reply to the client req.tao_send_reply_exception (ex); } } void TAO_ServantBase::_add_ref () { ++this->ref_count_; } void TAO_ServantBase::_remove_ref () { CORBA::ULong const new_count = --this->ref_count_; if (new_count == 0) { delete this; } } CORBA::ULong TAO_ServantBase::_refcount_value () const { return this->ref_count_; } void TAO_ServantBase::_collocated_dispatch (::CORBA::Object_ptr obj, ::CORBA::Object_out forward_obj, bool &is_forwarded, TAO::Argument ** args, int num_args, const char * op, size_t op_len, TAO::Collocation_Strategy strategy) { TAO::Direct_Collocation_Upcall_Wrapper collocation_upcall_wrapper; collocation_upcall_wrapper.upcall ( obj, forward_obj, is_forwarded, args, num_args, op, op_len, strategy); } TAO_END_VERSIONED_NAMESPACE_DECL