diff options
Diffstat (limited to 'trunk/TAO/tao/Object.cpp')
-rw-r--r-- | trunk/TAO/tao/Object.cpp | 1041 |
1 files changed, 1041 insertions, 0 deletions
diff --git a/trunk/TAO/tao/Object.cpp b/trunk/TAO/tao/Object.cpp new file mode 100644 index 00000000000..08d10c311ef --- /dev/null +++ b/trunk/TAO/tao/Object.cpp @@ -0,0 +1,1041 @@ +// @(#) $Id$ +// +// Copyright 1994-1995 by Sun Microsystems Inc. +// Copyright 1997-2002 by Washington University +// All Rights Reserved +// +// ORB: CORBA::Object operations + +#include "tao/Object.h" +#include "tao/Stub.h" +#include "tao/Profile.h" +#include "tao/ORB_Core.h" +#include "tao/Connector_Registry.h" +#include "tao/LocateRequest_Invocation_Adapter.h" +#include "tao/debug.h" +#include "tao/Dynamic_Adapter.h" +#include "tao/IFR_Client_Adapter.h" +#include "tao/Remote_Object_Proxy_Broker.h" +#include "tao/CDR.h" +#include "tao/SystemException.h" +#include "tao/PolicyC.h" + +#include "ace/Dynamic_Service.h" +#include "ace/OS_NS_string.h" + +#if !defined (__ACE_INLINE__) +# include "tao/Object.inl" +#endif /* ! __ACE_INLINE__ */ + + +ACE_RCSID (tao, + Object, + "$Id$") + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +CORBA::Object::~Object (void) +{ + if (this->protocol_proxy_) + (void) this->protocol_proxy_->_decr_refcnt (); + + delete this->object_init_lock_; +} + +CORBA::Object::Object (TAO_Stub * protocol_proxy, + CORBA::Boolean collocated, + TAO_Abstract_ServantBase * servant, + TAO_ORB_Core *orb_core) + : is_local_ (false) + , is_evaluated_ (true) + , ior_ (0) + , orb_core_ (orb_core) + , protocol_proxy_ (protocol_proxy) + , refcount_ () + , object_init_lock_ (0) +{ + /// This constructor should not be called when the protocol proxy is + /// null ie. when the object is a LocalObject. Assert that + /// requirement. + ACE_ASSERT (this->protocol_proxy_ != 0); + + if (this->orb_core_ == 0) + this->orb_core_ = this->protocol_proxy_->orb_core (); + + this->object_init_lock_ = + this->orb_core_->resource_factory ()->create_corba_object_lock (); + + this->refcount_ = + this->orb_core_->resource_factory ()->create_corba_object_refcount (); + + // Set the collocation marker on the stub. This may not be news to it. + // This may also change the stub's object proxy broker. + this->protocol_proxy_->is_collocated (collocated); + + // Set the collocated servant pointer (null if not collocated) on the stub. + this->protocol_proxy_->collocated_servant (servant); +} + +CORBA::Object::Object (IOP::IOR *ior, + TAO_ORB_Core *orb_core) + : is_local_ (false) + , is_evaluated_ (false) + , ior_ (ior) + , orb_core_ (orb_core) + , protocol_proxy_ (0) + , refcount_ () + , object_init_lock_ (0) +{ + this->object_init_lock_ = + this->orb_core_->resource_factory ()->create_corba_object_lock (); + + this->refcount_ = + this->orb_core_->resource_factory ()->create_corba_object_refcount (); +} + +// Too lazy to do this check in every method properly! This is useful +// only for lazily evaluated IOR's +#define TAO_OBJECT_IOR_EVALUATE \ +if (!this->is_evaluated_) \ + { \ + ACE_GUARD (ACE_Lock , mon, *this->object_init_lock_); \ + if (!this->is_evaluated_) \ + CORBA::Object::tao_object_initialize (this); \ + } + +#define TAO_OBJECT_IOR_EVALUATE_RETURN \ +if (!this->is_evaluated_) \ + { \ + ACE_GUARD_RETURN (ACE_Lock , mon, *this->object_init_lock_, 0); \ + if (!this->is_evaluated_) \ + CORBA::Object::tao_object_initialize (this); \ + } + +void +CORBA::Object::_add_ref (void) +{ + if (this->is_local_) + return; + + this->refcount_.increment (); +} + +void +CORBA::Object::_remove_ref (void) +{ + if (this->is_local_) + return; + + if (this->refcount_.decrement () != 0) + return; + + delete this; +} + +void +CORBA::Object::_tao_any_destructor (void *x) +{ + CORBA::Object_ptr tmp = static_cast<CORBA::Object_ptr> (x); + ::CORBA::release (tmp); +} + +// virtual -- do not inline +CORBA::Boolean +CORBA::Object::marshal (TAO_OutputCDR &cdr) +{ + return (cdr << this); +} + +/*static*/ CORBA::Boolean +CORBA::Object::marshal (const CORBA::Object_ptr x, + TAO_OutputCDR &cdr) +{ + if (x == 0) + { + // NIL objrefs ... marshal as empty type hint, no elements. + cdr.write_ulong (1); + cdr.write_char ('\0'); + cdr.write_ulong (0); + return (CORBA::Boolean) cdr.good_bit (); + } + + return x->marshal (cdr); +} + +bool +CORBA::Object::can_convert_to_ior (void) const +{ + // By default, objects can not be stringified if they are local + return !this->_is_local (); +} + +char* +CORBA::Object::convert_to_ior (bool, + const char*) const +{ + return 0; +} + +TAO_Abstract_ServantBase* +CORBA::Object::_servant (void) const +{ + if (this->protocol_proxy_ == 0) + { + // No stub set. Should not happen. + return 0; + } + + return this->protocol_proxy_->collocated_servant (); +} + +// IS_A ... ask the object if it's an instance of the type whose +// logical type ID is passed as a parameter. + +CORBA::Boolean +CORBA::Object::_is_a (const char *type_id + ACE_ENV_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + + // NOTE: if istub->type_id is nonzero and we have local knowledge of + // it, we can answer this question without a costly remote call. + // + // That "local knowledge" could come from stubs or skeletons linked + // into this process in the best case, or a "near" repository in a + // slightly worse case. Or in a trivial case, if the ID being asked + // about is the ID we have recorded, we don't need to ask about the + // inheritance relationships at all! + // + // In real systems having local knowledge will be common, though as + // the systems built atop ORBs become richer it'll also become + // common to have the "real type ID" not be directly understood + // because it's more deeply derived than any locally known types. + // + // XXX if type_id is that of CORBA::Object, "yes, we comply" :-) + + if (this->protocol_proxy_ == 0) + ACE_THROW_RETURN (CORBA::NO_IMPLEMENT (), false); + + if (this->_stubobj ()->type_id.in () != 0 + && ACE_OS::strcmp (type_id, + this->_stubobj ()->type_id.in ()) == 0) + return true; + + return this->proxy_broker ()->_is_a (this, + type_id + ACE_ENV_ARG_PARAMETER); +} + +const char* +CORBA::Object::_interface_repository_id (void) const +{ + return "IDL:omg.org/CORBA/Object:1.0"; +} + +CORBA::Boolean +CORBA::Object::_is_collocated (void) const +{ + if (this->protocol_proxy_) + { + return this->protocol_proxy_->is_collocated (); + } + + return false; +} + +void +CORBA::Object::set_collocated_servant (TAO_Abstract_ServantBase *b) +{ + this->protocol_proxy_->collocated_servant (b); + this->protocol_proxy_->is_collocated (true); +} + +CORBA::Boolean +CORBA::Object::_is_local (void) const +{ + return this->is_local_; +} + +TAO_Stub * +CORBA::Object::_stubobj (void) const +{ + return this->protocol_proxy_; +} + +TAO_Stub * +CORBA::Object::_stubobj (void) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + return this->protocol_proxy_; +} + +CORBA::ULong +CORBA::Object::_hash (CORBA::ULong maximum + ACE_ENV_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + + if (this->protocol_proxy_ != 0) + return this->protocol_proxy_->hash (maximum ACE_ENV_ARG_PARAMETER); + else + { + // Locality-constrained object. + + // Note that we reinterpret_cast to an "unsigned long" instead + // of CORBA::ULong since we need to first cast to an integer + // large enough to hold an address to avoid compile-time + // warnings on some 64-bit platforms. + const CORBA::ULong hash = + static_cast<CORBA::ULong> (reinterpret_cast<ptrdiff_t> (this)); + + return hash % maximum; + } +} + +CORBA::Boolean +CORBA::Object::_is_equivalent (CORBA::Object_ptr other_obj + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (()) +{ + if (other_obj == this) + { + return true; + } + + TAO_OBJECT_IOR_EVALUATE_RETURN; + + if (this->protocol_proxy_ != 0) + return this->protocol_proxy_->is_equivalent (other_obj); + + return false; +} + +// TAO's extensions + +TAO::ObjectKey * +CORBA::Object::_key (ACE_ENV_SINGLE_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + + if (this->_stubobj () && this->_stubobj ()->profile_in_use ()) + return this->_stubobj ()->profile_in_use ()->_key (); + + if (TAO_debug_level > 2) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) Null object key return from ") + ACE_TEXT ("profile in use\n"))); + } + + ACE_THROW_RETURN (CORBA::INTERNAL ( + CORBA::SystemException::_tao_minor_code ( + 0, + EINVAL), + CORBA::COMPLETED_NO), + 0); +} + +void +CORBA::Object::_proxy_broker (TAO::Object_Proxy_Broker *proxy_broker) +{ + this->protocol_proxy_->object_proxy_broker (proxy_broker); +} + +CORBA::Boolean +CORBA::Object::is_nil_i (CORBA::Object_ptr obj) +{ + // If the profile length is zero for a non-evaluted IOR it is a + // null-object. + if ((!obj->is_evaluated ()) && + obj->ior ().profiles.length () == 0) + return true; + + // To accomodate new definitions. + if (obj->orb_core_) + { + return obj->orb_core_->object_is_nil (obj); + } + + return false; +} + + + +#if (TAO_HAS_MINIMUM_CORBA == 0) + +#if !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) +void +CORBA::Object::_create_request (CORBA::Context_ptr ctx, + const char *operation, + CORBA::NVList_ptr arg_list, + CORBA::NamedValue_ptr result, + CORBA::Request_ptr &request, + CORBA::Flags req_flags + ACE_ENV_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE; + + // Since we don't really support Context, anything but a null pointer + // is a no-no. + // Neither can we create a request object from locality constrained + // object references. + if (ctx != 0 || this->protocol_proxy_ == 0) + { + ACE_THROW (CORBA::NO_IMPLEMENT ()); + } + + TAO_Dynamic_Adapter *dynamic_adapter = + ACE_Dynamic_Service<TAO_Dynamic_Adapter>::instance ( + TAO_ORB_Core::dynamic_adapter_name () + ); + + dynamic_adapter->create_request ( + this, + this->protocol_proxy_->orb_core ()-> orb (), + operation, + arg_list, + result, + 0, + request, + req_flags + ACE_ENV_ARG_PARAMETER + ); +} +#endif + +#if !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) +void +CORBA::Object::_create_request (CORBA::Context_ptr ctx, + const char *operation, + CORBA::NVList_ptr arg_list, + CORBA::NamedValue_ptr result, + CORBA::ExceptionList_ptr exceptions, + CORBA::ContextList_ptr, + CORBA::Request_ptr &request, + CORBA::Flags req_flags + ACE_ENV_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE; + + // Since we don't really support Context, anything but a null pointer + // is a no-no. + // Neither can we create a request object from locality constrained + // object references. + if (ctx != 0 || this->protocol_proxy_ == 0) + { + ACE_THROW (CORBA::NO_IMPLEMENT ()); + } + + TAO_Dynamic_Adapter *dynamic_adapter = + ACE_Dynamic_Service<TAO_Dynamic_Adapter>::instance ( + TAO_ORB_Core::dynamic_adapter_name () + ); + + dynamic_adapter->create_request ( + this, + this->protocol_proxy_->orb_core ()-> orb (), + operation, + arg_list, + result, + exceptions, + request, + req_flags + ACE_ENV_ARG_PARAMETER + ); +} +#endif + +CORBA::Request_ptr +CORBA::Object::_request (const char *operation + ACE_ENV_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + if (this->protocol_proxy_) + { + TAO_Dynamic_Adapter *dynamic_adapter = + ACE_Dynamic_Service<TAO_Dynamic_Adapter>::instance ( + TAO_ORB_Core::dynamic_adapter_name () + ); + + return dynamic_adapter->request ( + this, + this->protocol_proxy_->orb_core ()->orb (), + operation + ACE_ENV_ARG_PARAMETER + ); + } + else + { + ACE_THROW_RETURN (CORBA::NO_IMPLEMENT (), + 0); + } +} + +// NON_EXISTENT ... send a simple call to the object, which will +// either elicit a false response or a OBJECT_NOT_EXIST exception. In +// the latter case, return true. + +CORBA::Boolean +CORBA::Object::_non_existent (ACE_ENV_SINGLE_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + + CORBA::Boolean retval = false; + + ACE_TRY + { + retval = this->proxy_broker ()->_non_existent (this + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCH (CORBA::OBJECT_NOT_EXIST, ex) + { + retval = true; + } + ACE_CATCHANY + { + ACE_RE_THROW; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (retval); + + return retval; +} + + +CORBA::InterfaceDef_ptr +CORBA::Object::_get_interface (ACE_ENV_SINGLE_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + return this->proxy_broker ()->_get_interface (this + ACE_ENV_ARG_PARAMETER); +} + +CORBA::ImplementationDef_ptr +CORBA::Object::_get_implementation (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ + return 0; +} + +CORBA::Object_ptr +CORBA::Object::_get_component (ACE_ENV_SINGLE_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + return this->proxy_broker ()->_get_component (this + ACE_ENV_ARG_PARAMETER); +} + +char* +CORBA::Object::_repository_id (ACE_ENV_SINGLE_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + return this->proxy_broker ()->_repository_id (this + ACE_ENV_ARG_PARAMETER); +} + +#endif /* TAO_HAS_MINIMUM_CORBA */ + +// **************************************************************** + +// @@ Does it make sense to support policy stuff for locality constrained +// objects? Also, does it make sense to bind policies with stub object? +// - nw. + +#if (TAO_HAS_CORBA_MESSAGING == 1) + +CORBA::Policy_ptr +CORBA::Object::_get_policy ( + CORBA::PolicyType type + ACE_ENV_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + + if (this->protocol_proxy_) + return this->protocol_proxy_->get_policy (type + ACE_ENV_ARG_PARAMETER); + else + ACE_THROW_RETURN (CORBA::NO_IMPLEMENT (), CORBA::Policy::_nil ()); +} + +CORBA::Policy_ptr +CORBA::Object::_get_cached_policy ( + TAO_Cached_Policy_Type type + ACE_ENV_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + + if (this->protocol_proxy_) + return this->protocol_proxy_->get_cached_policy (type + ACE_ENV_ARG_PARAMETER); + else + ACE_THROW_RETURN (CORBA::NO_IMPLEMENT (), CORBA::Policy::_nil ()); +} + +CORBA::Object_ptr +CORBA::Object::_set_policy_overrides ( + const CORBA::PolicyList & policies, + CORBA::SetOverrideType set_add + ACE_ENV_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + + if (!this->protocol_proxy_) + ACE_THROW_RETURN (CORBA::NO_IMPLEMENT (), CORBA::Policy::_nil ()); + + TAO_Stub* stub = + this->protocol_proxy_->set_policy_overrides (policies, + set_add + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + TAO_Stub_Auto_Ptr safe_stub (stub); + + CORBA::Object_ptr obj = CORBA::Object::_nil (); + + ACE_NEW_THROW_EX (obj, + CORBA::Object (stub, + this->_is_collocated ()), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + 0, + ENOMEM), + CORBA::COMPLETED_MAYBE)); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + // If the stub is collocated and we don't have a collocated server we need + // to reinitialize it to get it. + if (stub->is_collocated () && stub->collocated_servant () == 0) + { + obj->orb_core ()->reinitialize_object (stub); + } + + (void) safe_stub.release (); + + return obj; +} + +CORBA::PolicyList * +CORBA::Object::_get_policy_overrides (const CORBA::PolicyTypeSeq & types + ACE_ENV_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + if (this->protocol_proxy_) + return this->protocol_proxy_->get_policy_overrides (types + ACE_ENV_ARG_PARAMETER); + else + ACE_THROW_RETURN (CORBA::NO_IMPLEMENT (), 0); +} + +CORBA::Boolean +CORBA::Object::_validate_connection ( + CORBA::PolicyList_out inconsistent_policies + ACE_ENV_ARG_DECL) +{ + TAO_OBJECT_IOR_EVALUATE_RETURN; + + inconsistent_policies = 0; + + CORBA::Boolean retval = 0; + +#if (TAO_HAS_MINIMUM_CORBA == 1) + + ACE_ENV_ARG_NOT_USED; // FUZZ: ignore check_for_ace_check + + retval = false; +#else + + // If the object is collocated then use non_existent to see whether + // it's there. + if (this->_is_collocated ()) + return !(this->_non_existent (ACE_ENV_SINGLE_ARG_PARAMETER)); + + TAO::LocateRequest_Invocation_Adapter tao_call (this); + ACE_TRY + { + tao_call.invoke (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCH (CORBA::INV_POLICY, ex) + { + inconsistent_policies = + tao_call.get_inconsistent_policies (); + retval = false; + } + ACE_CATCHANY + { + ACE_RE_THROW; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (false); + + retval = true; +#endif /* TAO_HAS_MINIMUM_CORBA */ + + return retval; +} + +#endif /* TAO_HAS_CORBA_MESSAGING == 1 */ + + +CORBA::ORB_ptr +CORBA::Object::_get_orb (ACE_ENV_SINGLE_ARG_DECL) +{ + if (this->orb_core_ != 0) + { + return CORBA::ORB::_duplicate (this->orb_core_->orb ()); + } + else + { + TAO_OBJECT_IOR_EVALUATE_RETURN; + if (this->protocol_proxy_) + return CORBA::ORB::_duplicate (this->protocol_proxy_->orb_core ()->orb ()); + else + ACE_THROW_RETURN (CORBA::INTERNAL (), CORBA::ORB::_nil()); + } +} + +TAO::Object_Proxy_Broker * +CORBA::Object::proxy_broker (void) const +{ + // Paranoid check. We *should* never access the proxy_broker + // when the object has not been initialised so there *should* + // alway be a stub, but just in case... + + if (this->protocol_proxy_) + { + return this->protocol_proxy_->object_proxy_broker (); + } + + // We have no stub. We cannot be collocated. + return the_tao_remote_object_proxy_broker (); +} + +/***************************************************************** + * Global Functions + ****************************************************************/ + +CORBA::Boolean +operator<< (TAO_OutputCDR& cdr, const CORBA::Object* x) +{ + if (x == 0) + { + // NIL objrefs ... marshal as empty type hint, no elements. + cdr.write_ulong (1); + cdr.write_char ('\0'); + cdr.write_ulong (0); + return (CORBA::Boolean) cdr.good_bit (); + } + + if (!x->is_evaluated ()) + { + // @@ This is too inefficient. Need to speed this up if this is + // a bottle neck. + cdr << const_cast<IOP::IOR &> (x->ior ()); + return cdr.good_bit (); + } + + TAO_Stub *stubobj = x->_stubobj (); + + if (stubobj == 0) + return false; + + return (stubobj->marshal (cdr)); +} + +/*static*/ void +CORBA::Object::tao_object_initialize (CORBA::Object *obj) +{ + CORBA::ULong const profile_count = + obj->ior_->profiles.length (); + + // Assumption is that after calling this method, folks should test + // for protocol_proxy_ or whatever to make sure that things have + // been initialized! + if (profile_count == 0) + return; + + // get a profile container to store all profiles in the IOR. + TAO_MProfile mp (profile_count); + + TAO_ORB_Core *&orb_core = obj->orb_core_; + if (orb_core == 0) + { + orb_core = TAO_ORB_Core_instance (); + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_WARNING, + ACE_TEXT ("TAO (%P|%t) - Object::tao_object_initialize ") + ACE_TEXT ("WARNING: extracting object from ") + ACE_TEXT ("default ORB_Core\n"))); + } + } + + TAO_Stub *objdata = 0; + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + TAO_Connector_Registry *connector_registry = + orb_core->connector_registry (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + for (CORBA::ULong i = 0; i != profile_count; ++i) + { + IOP::TaggedProfile &tpfile = + obj->ior_->profiles[i]; + + // NOTE: This is a place for optimizations. Here we have an + // 2 allocations and 2 copies. Future optimizations should + // target this place. + TAO_OutputCDR o_cdr; + + o_cdr << tpfile; + + TAO_InputCDR cdr (o_cdr, + orb_core->input_cdr_buffer_allocator (), + orb_core->input_cdr_dblock_allocator (), + orb_core->input_cdr_msgblock_allocator (), + orb_core); + + TAO_Profile *pfile = + connector_registry->create_profile (cdr); + + if (pfile != 0) + mp.give_profile (pfile); + } + + // Make sure we got some profiles! + if (mp.profile_count () != profile_count) + { + // @@ This occurs when profile creation fails when decoding the + // profile from the IOR. + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) ERROR: XXXXX Could not create all ") + ACE_TEXT ("profiles while extracting object\n") + ACE_TEXT ("TAO (%P|%t) ERROR: reference from the ") + ACE_TEXT ("CDR stream.\n"))); + } + + + objdata = + orb_core->create_stub (obj->ior_->type_id.in (), + mp + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + if (TAO_debug_level > 0) + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("TAO - ERROR creating stub ") + ACE_TEXT ("object when demarshaling object ") + ACE_TEXT ("reference.")); + + return; + } + ACE_ENDTRY; + ACE_CHECK; + + TAO_Stub_Auto_Ptr safe_objdata (objdata); + + // This call will set the stub proxy broker if necessary + if (orb_core->initialize_object (safe_objdata.get (), + obj) == -1) + return; + + obj->protocol_proxy_ = objdata; + + obj->is_evaluated_ = true; + + // Release the contents of the ior to keep memory consumption down. + obj->ior_ = 0; + + // Transfer ownership to the CORBA::Object + (void) safe_objdata.release (); + return; +} + +CORBA::Boolean +operator>> (TAO_InputCDR& cdr, CORBA::Object*& x) +{ + bool lazy_strategy = false; + TAO_ORB_Core *orb_core = cdr.orb_core (); + + if (orb_core == 0) + { + orb_core = TAO_ORB_Core_instance (); + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_WARNING, + ACE_TEXT ("TAO (%P|%t) WARNING: extracting object from ") + ACE_TEXT ("default ORB_Core\n"))); + } + } + else + { + if (orb_core->resource_factory ()->resource_usage_strategy () == + TAO_Resource_Factory::TAO_LAZY) + lazy_strategy = true; + } + + if (!lazy_strategy) + { + // If the user has set up a eager strategy.. + CORBA::String_var type_hint; + + if ((cdr >> type_hint.inout ()) == 0) + return 0; + + CORBA::ULong profile_count; + if ((cdr >> profile_count) == 0) + return 0; + + if (profile_count == 0) + { + x = CORBA::Object::_nil (); + return (CORBA::Boolean) cdr.good_bit (); + } + + // get a profile container to store all profiles in the IOR. + TAO_MProfile mp (profile_count); + + TAO_ORB_Core *orb_core = cdr.orb_core (); + if (orb_core == 0) + { + orb_core = TAO_ORB_Core_instance (); + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_WARNING, + ACE_TEXT ("TAO (%P|%t) - Object::tao_object_initialize ") + ACE_TEXT ("WARNING: extracting object from ") + ACE_TEXT ("default ORB_Core\n"))); + } + } + + // Ownership of type_hint is given to TAO_Stub + // TAO_Stub will make a copy of mp! + + TAO_Stub *objdata = 0; + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + TAO_Connector_Registry *connector_registry = + orb_core->connector_registry (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + for (CORBA::ULong i = 0; i != profile_count && cdr.good_bit (); ++i) + { + TAO_Profile *pfile = + connector_registry->create_profile (cdr); + if (pfile != 0) + mp.give_profile (pfile); + } + + // Make sure we got some profiles! + if (mp.profile_count () != profile_count) + { + // @@ This occurs when profile creation fails when decoding the + // profile from the IOR. + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) ERROR: Could not create all ") + ACE_TEXT ("profiles while extracting object\n") + ACE_TEXT ("TAO (%P|%t) ERROR: reference from the ") + ACE_TEXT ("CDR stream.\n")), + 0); + } + + + objdata = orb_core->create_stub (type_hint.in (), + mp + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + if (TAO_debug_level > 0) + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("TAO - ERROR creating stub ") + ACE_TEXT ("object when demarshaling object ") + ACE_TEXT ("reference.\n")); + + return 0; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (0); + + TAO_Stub_Auto_Ptr safe_objdata (objdata); + + x = orb_core->create_object (safe_objdata.get ()); + if (x == 0) + return 0; + + // Transfer ownership to the CORBA::Object + (void) safe_objdata.release (); + } + else + { + // Lazy strategy! + IOP::IOR *ior = 0; + + ACE_NEW_RETURN (ior, + IOP::IOR (), + 0); + + cdr >> *ior; + ACE_NEW_RETURN (x, + CORBA::Object (ior, + orb_core), + 0); + } + + return (CORBA::Boolean) cdr.good_bit (); +} + + +// ========================================================= +// Traits specializations for CORBA::Object. +namespace TAO +{ + + void In_Object_Argument_Cloner_T<CORBA::InterfaceDef_ptr>::duplicate + (CORBA::InterfaceDef_ptr) + { + } + + void In_Object_Argument_Cloner_T<CORBA::InterfaceDef_ptr>::release + (CORBA::InterfaceDef_ptr) + { + } + + CORBA::Object_ptr + Objref_Traits<CORBA::Object>::duplicate (CORBA::Object_ptr p) + { + return CORBA::Object::_duplicate (p); + } + + void + Objref_Traits<CORBA::Object>::release (CORBA::Object_ptr p) + { + ::CORBA::release (p); + } + + CORBA::Object_ptr + Objref_Traits<CORBA::Object>::nil (void) + { + return CORBA::Object::_nil (); + } + + CORBA::Boolean + Objref_Traits<CORBA::Object>::marshal (const CORBA::Object_ptr p, + TAO_OutputCDR & cdr) + { + return p->marshal (cdr); + } +} // close TAO namespace + + +TAO::Object_Proxy_Broker * (*_TAO_Object_Proxy_Broker_Factory_function_pointer) (void) = 0; + + +TAO_END_VERSIONED_NAMESPACE_DECL |