diff options
Diffstat (limited to 'TAO/tao/DynamicInterface/Dynamic_Implementation.cpp')
-rw-r--r-- | TAO/tao/DynamicInterface/Dynamic_Implementation.cpp | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/TAO/tao/DynamicInterface/Dynamic_Implementation.cpp b/TAO/tao/DynamicInterface/Dynamic_Implementation.cpp new file mode 100644 index 00000000000..6e09d9ff5fa --- /dev/null +++ b/TAO/tao/DynamicInterface/Dynamic_Implementation.cpp @@ -0,0 +1,221 @@ +#include "tao/DynamicInterface/Dynamic_Implementation.h" + +ACE_RCSID (DynamicInterface, + Dynamic_Implementation, + "$Id$") + + +#include "tao/DynamicInterface/Server_Request.h" +#include "tao/ORB_Core.h" +#include "tao/TSS_Resources.h" +#include "tao/IFR_Client_Adapter.h" +#include "tao/PortableServer/Root_POA.h" +#include "tao/PortableServer/POA_Current_Impl.h" + +#include "ace/Dynamic_Service.h" +#include "ace/OS_NS_string.h" + + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +CORBA::Boolean +TAO_DynamicImplementation::_is_a (const char *logical_type_id + ACE_ENV_ARG_DECL) +{ + CORBA::RepositoryId_var id = + this->get_id_from_primary_interface (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return ACE_OS::strcmp (logical_type_id, id.in ()) == 0; +} + +CORBA::Object_ptr +TAO_DynamicImplementation::_this (ACE_ENV_SINGLE_ARG_DECL) +{ + // The _this() function returns a CORBA::Object_ptr for the target + // object. Unlike _this() for static skeletons, its return type is + // not interface-specific because a DSI servant may very well + // incarnate multiple CORBA objects of different types. + TAO_Stub *stub = this->_create_stub (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + // Create a object. + CORBA::Object_ptr retval = CORBA::Object::_nil (); + ACE_NEW_RETURN (retval, + CORBA::Object (stub, + 1, + this), + CORBA::Object::_nil ()); + + return retval; +} + +CORBA::InterfaceDef_ptr +TAO_DynamicImplementation::_get_interface (ACE_ENV_SINGLE_ARG_DECL) +{ + TAO_IFR_Client_Adapter *adapter = + ACE_Dynamic_Service<TAO_IFR_Client_Adapter>::instance ( + TAO_ORB_Core::ifr_client_adapter_name () + ); + + if (adapter == 0) + { + ACE_THROW_RETURN (CORBA::INTF_REPOS (), + 0); + } + + CORBA::RepositoryId_var id = + this->get_id_from_primary_interface (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + // 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 (), + id.in () + ACE_ENV_ARG_PARAMETER); +} + +const char * +TAO_DynamicImplementation::_interface_repository_id (void) const +{ + // This should never be called. + return 0; +} + +void * +TAO_DynamicImplementation::_downcast (const char *repository_id) +{ + ACE_UNUSED_ARG (repository_id); + + // Don't know enough to do better. + return this; +} + +TAO_Stub * +TAO_DynamicImplementation::_create_stub (ACE_ENV_SINGLE_ARG_DECL) +{ + // If DynamicImplementation::_this() is invoked outside of the + // context of a request invocation on a target object being served + // by the DSI servant, it raises the PortableServer::WrongPolicy + // exception. See the CORBA C++ mapping, section 1.38.3. + TAO::Portable_Server::POA_Current_Impl *poa_current_impl = + static_cast <TAO::Portable_Server::POA_Current_Impl *> + (TAO_TSS_Resources::instance ()->poa_current_impl_); + + if (poa_current_impl == 0 + || this != poa_current_impl->servant ()) + { + ACE_THROW_RETURN (PortableServer::POA::WrongPolicy (), + 0); + } + + PortableServer::POA_var poa = + poa_current_impl->get_POA (); + + CORBA::PolicyList_var client_exposed_policies = + poa_current_impl->poa ()->client_exposed_policies ( + poa_current_impl->priority () + ACE_ENV_ARG_PARAMETER + ); + ACE_CHECK_RETURN (0); + + CORBA::RepositoryId_var pinterface = + this->_primary_interface (poa_current_impl->object_id (), + poa.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return + poa_current_impl->poa ()->key_to_stub (poa_current_impl->object_key (), + pinterface.in (), + poa_current_impl->priority () + ACE_ENV_ARG_PARAMETER); +} + +void +TAO_DynamicImplementation::_dispatch (TAO_ServerRequest &request, + void * /* context */ + ACE_ENV_ARG_DECL) +{ + // No need to do any of this if the client isn't waiting. + if (request.response_expected ()) + { + if (!CORBA::is_nil (request.forward_location ())) + { + request.init_reply (); + request.tao_send_reply (); + + // No need to invoke in this case. + return; + } + else if (request.sync_with_server ()) + { + // The last line before the call to this function + // was an ACE_CHECK_RETURN, so if we're here, we + // know there is no exception so far, and that's all + // a SYNC_WITH_SERVER client request cares about. + request.send_no_exception_reply (); + } + } + + // Create DSI request object. + CORBA::ServerRequest *dsi_request = 0; + ACE_NEW (dsi_request, + CORBA::ServerRequest (request)); + + ACE_TRY + { + // Delegate to user. + this->invoke (dsi_request + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Only if the client is waiting. + if (request.response_expected () && !request.sync_with_server ()) + { + dsi_request->dsi_marshal (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + } + ACE_CATCH (CORBA::Exception, ex) + { + // Only if the client is waiting. + if (request.response_expected () && !request.sync_with_server ()) + { + request.tao_send_reply_exception (ex); + } + } + ACE_ENDTRY; + + ::CORBA::release (dsi_request); +} + +CORBA::RepositoryId +TAO_DynamicImplementation::get_id_from_primary_interface ( + ACE_ENV_SINGLE_ARG_DECL + ) +{ + // If this method is called outside of the + // context of a request invocation on a target object being served + // by the DSI servant, it raises the PortableServer::WrongPolicy + // exception. See the CORBA C++ mapping, section 1.38.3. + TAO::Portable_Server::POA_Current_Impl *poa_current_impl = + static_cast <TAO::Portable_Server::POA_Current_Impl *> + (TAO_TSS_Resources::instance ()->poa_current_impl_); + + if (poa_current_impl == 0 + || this != poa_current_impl->servant ()) + { + ACE_THROW_RETURN (PortableServer::POA::WrongPolicy (), + 0); + } + + PortableServer::POA_var poa = + poa_current_impl->get_POA (); + + return this->_primary_interface (poa_current_impl->object_id (), + poa.in () + ACE_ENV_ARG_PARAMETER); +} + +TAO_END_VERSIONED_NAMESPACE_DECL |