diff options
Diffstat (limited to 'TAO/tao/Object.cpp')
-rw-r--r-- | TAO/tao/Object.cpp | 417 |
1 files changed, 330 insertions, 87 deletions
diff --git a/TAO/tao/Object.cpp b/TAO/tao/Object.cpp index fb555fca38e..2b869257fee 100644 --- a/TAO/tao/Object.cpp +++ b/TAO/tao/Object.cpp @@ -16,7 +16,6 @@ #include "tao/Remote_Object_Proxy_Broker.h" #include "tao/Dynamic_Adapter.h" #include "tao/IFR_Client_Adapter.h" - #include "ace/Dynamic_Service.h" #if !defined (__ACE_INLINE__) @@ -39,62 +38,112 @@ CORBA::Object::~Object (void) CORBA::Object::Object (TAO_Stub * protocol_proxy, CORBA::Boolean collocated, - TAO_Abstract_ServantBase * servant) - : is_collocated_ (collocated), - servant_ (servant), - is_local_ (protocol_proxy == 0 ? 1 : 0), - proxy_broker_ (0), - protocol_proxy_ (protocol_proxy), - refcount_ (1), - refcount_lock_ (0) -{ - if (protocol_proxy != 0) - { - // Only instantiate a lock if the object is unconstrained. - // Locality-constrained objects have no-op reference counting by - // default. Furthermore locality-constrained objects may be - // instantiated in the critical path. Instantiating a lock for - // unconstrained objects alone optimizes instantiation of such - // locality-constrained objects. - ACE_NEW (this->refcount_lock_, TAO_SYNCH_MUTEX); - - // If the object is collocated then set the broker using the - // factory otherwise use the remote proxy broker. - if (this->is_collocated_ && - _TAO_collocation_Object_Proxy_Broker_Factory_function_pointer != 0) - this->proxy_broker_ = _TAO_collocation_Object_Proxy_Broker_Factory_function_pointer (this); - else - this->proxy_broker_ = the_tao_remote_object_proxy_broker (); - } -} + TAO_Abstract_ServantBase * servant, + TAO_ORB_Core *orb_core) + : servant_ (servant) + , is_collocated_ (collocated) + , is_local_ (0) + , proxy_broker_ (0) + , is_evaluated_ (1) + , ior_ (0) + , orb_core_ (orb_core) + , protocol_proxy_ (protocol_proxy) + , refcount_ (1) + , refcount_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->refcount_lock_ = + this->orb_core_->resource_factory ()->create_corba_object_lock (); + + // If the object is collocated then set the broker using the + // factory otherwise use the remote proxy broker. + if (this->is_collocated_ && + _TAO_collocation_Object_Proxy_Broker_Factory_function_pointer != 0) + this->proxy_broker_ = + _TAO_collocation_Object_Proxy_Broker_Factory_function_pointer (this); + else + this->proxy_broker_ = + the_tao_remote_object_proxy_broker (); +} + +CORBA::Object::Object (IOP::IOR *ior, + TAO_ORB_Core *orb_core) + : servant_ (0) + , is_collocated_ (0) + , is_local_ (0) + , proxy_broker_ (0) + , is_evaluated_ (0) + , ior_ (ior) + , orb_core_ (orb_core) + , protocol_proxy_ (0) + , refcount_ (1) + , refcount_lock_ (0) +{ + this->refcount_lock_ = + this->orb_core_->resource_factory ()->create_corba_object_lock (); +} + +// 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->refcount_lock_); \ + CORBA::Object::tao_object_initialize (this); \ + } + +#define TAO_OBJECT_IOR_EVALUATE_RETURN \ +if (!this->is_evaluated_) \ + { \ + ACE_GUARD_RETURN (ACE_Lock , mon, *this->refcount_lock_, 0); \ + if (!this->is_evaluated_) \ + CORBA::Object::tao_object_initialize (this); \ + } void CORBA::Object::_add_ref (void) { - if (this->refcount_lock_ != 0) - { - ACE_GUARD (TAO_SYNCH_MUTEX, mon, *this->refcount_lock_); + if (this->is_local_) + return; - this->refcount_++; - } + ACE_ASSERT (this->refcount_lock_ != 0); + + ACE_GUARD (ACE_Lock , + mon, + *this->refcount_lock_); + + this->refcount_++; } void CORBA::Object::_remove_ref (void) { - if (this->refcount_lock_ != 0) - { - { - ACE_GUARD (TAO_SYNCH_MUTEX, mon, *this->refcount_lock_); + if (this->is_local_) + return; - this->refcount_--; + ACE_ASSERT (this->refcount_lock_ != 0); - if (this->refcount_ != 0) - return; - } + { + ACE_GUARD (ACE_Lock, + mon, + *this->refcount_lock_); - delete this; - } + this->refcount_--; + + if (this->refcount_ != 0) + return; + } + + ACE_ASSERT (this->refcount_ == 0); + + delete this; } void @@ -134,6 +183,8 @@ 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. // @@ -190,10 +241,19 @@ CORBA::Object::_is_local (void) const return this->is_local_; } +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 @@ -220,6 +280,8 @@ CORBA::Object::_is_equivalent (CORBA::Object_ptr other_obj return 1; } + TAO_OBJECT_IOR_EVALUATE_RETURN; + if (this->protocol_proxy_ != 0) return this->protocol_proxy_->is_equivalent (other_obj); @@ -231,6 +293,8 @@ CORBA::Object::_is_equivalent (CORBA::Object_ptr other_obj 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 (); @@ -247,12 +311,6 @@ CORBA::Object::_key (ACE_ENV_SINGLE_ARG_DECL) 0); } -const TAO::ObjectKey & -CORBA::Object::_object_key (void) -{ - return this->_stubobj ()->profile_in_use ()->object_key (); -} - void * CORBA::Object::_tao_QueryInterface (ptr_arith_t type) { @@ -284,14 +342,16 @@ CORBA::Boolean CORBA::Object::is_nil_i (CORBA::Object_ptr obj) { // To accomodate new definitions. - if (obj->_stubobj ()) + if (obj->orb_core_) { - return obj->_stubobj ()->orb_core ()->object_is_nil (obj); + return obj->orb_core_->object_is_nil (obj); } return 0; } + + #if (TAO_HAS_MINIMUM_CORBA == 0) void @@ -303,6 +363,8 @@ CORBA::Object::_create_request (CORBA::Context_ptr ctx, 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 @@ -341,6 +403,8 @@ CORBA::Object::_create_request (CORBA::Context_ptr ctx, 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 @@ -372,6 +436,7 @@ 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 = @@ -400,6 +465,8 @@ CORBA::Object::_request (const char *operation CORBA::Boolean CORBA::Object::_non_existent (ACE_ENV_SINGLE_ARG_DECL) { + TAO_OBJECT_IOR_EVALUATE_RETURN; + CORBA::Boolean _tao_retval = 0; // Get the right Proxy. @@ -420,6 +487,8 @@ CORBA::Object::_non_existent (ACE_ENV_SINGLE_ARG_DECL) CORBA::InterfaceDef_ptr CORBA::Object::_get_interface (ACE_ENV_SINGLE_ARG_DECL) { + TAO_OBJECT_IOR_EVALUATE_RETURN; + // Get the right Proxy. TAO_Object_Proxy_Impl &the_proxy = this->proxy_broker_->select_proxy (this @@ -440,6 +509,8 @@ CORBA::Object::_get_implementation (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) CORBA::Object_ptr CORBA::Object::_get_component (ACE_ENV_SINGLE_ARG_DECL) { + TAO_OBJECT_IOR_EVALUATE_RETURN; + // Get the right Proxy. TAO_Object_Proxy_Impl &the_proxy = this->proxy_broker_->select_proxy (this @@ -467,6 +538,8 @@ 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); @@ -479,6 +552,8 @@ CORBA::Object::_get_client_policy ( CORBA::PolicyType type ACE_ENV_ARG_DECL) { + TAO_OBJECT_IOR_EVALUATE_RETURN; + if (this->protocol_proxy_) return this->_stubobj ()->get_client_policy (type ACE_ENV_ARG_PARAMETER); @@ -492,6 +567,8 @@ CORBA::Object::_set_policy_overrides ( 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 ()); @@ -524,6 +601,7 @@ 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); @@ -536,6 +614,8 @@ CORBA::Object::_validate_connection ( CORBA::PolicyList_out inconsistent_policies ACE_ENV_ARG_DECL) { + TAO_OBJECT_IOR_EVALUATE_RETURN; + inconsistent_policies = 0; #if (TAO_HAS_MINIMUM_CORBA == 1) @@ -560,7 +640,9 @@ CORBA::Object::_validate_connection ( #endif /* TAO_HAS_CORBA_MESSAGING == 1 */ -// **************************************************************** +/***************************************************************** + * Global Functions + ****************************************************************/ CORBA::Boolean operator<< (TAO_OutputCDR& cdr, const CORBA::Object* x) @@ -600,42 +682,34 @@ operator<< (TAO_OutputCDR& cdr, const CORBA::Object* x) return (CORBA::Boolean) cdr.good_bit (); } -CORBA::Boolean -operator>> (TAO_InputCDR& cdr, CORBA::Object*& x) +/*static*/ void +CORBA::Object::tao_object_initialize (CORBA::Object *obj) { - CORBA::String_var type_hint; - - if ((cdr >> type_hint.inout ()) == 0) - return 0; - - CORBA::ULong profile_count; - if ((cdr >> profile_count) == 0) - return 0; + CORBA::ULong 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) - { - x = CORBA::Object::_nil (); - return (CORBA::Boolean) cdr.good_bit (); - } + return; // get a profile container to store all profiles in the IOR. TAO_MProfile mp (profile_count); - TAO_ORB_Core *orb_core = cdr.orb_core (); + 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_LIB_TEXT ("TAO (%P|%t) WARNING: extracting object from ") + ACE_LIB_TEXT ("TAO (%P|%t) - Object::tao_object_initialize ") + ACE_LIB_TEXT ("WARNING: extracting object from ") ACE_LIB_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; @@ -645,10 +719,27 @@ operator>> (TAO_InputCDR& cdr, CORBA::Object*& x) orb_core->connector_registry (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; - for (CORBA::ULong i = 0; i != profile_count && cdr.good_bit (); ++i) + 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); } @@ -658,18 +749,18 @@ operator>> (TAO_InputCDR& cdr, CORBA::Object*& x) { // @@ This occurs when profile creation fails when decoding the // profile from the IOR. - ACE_ERROR_RETURN ((LM_ERROR, - ACE_LIB_TEXT ("TAO (%P|%t) ERROR: Could not create all ") - ACE_LIB_TEXT ("profiles while extracting object\n") - ACE_LIB_TEXT ("TAO (%P|%t) ERROR: reference from the ") - ACE_LIB_TEXT ("CDR stream.\n")), - 0); + ACE_ERROR ((LM_ERROR, + ACE_LIB_TEXT ("TAO (%P|%t) ERROR: XXXXX Could not create all ") + ACE_LIB_TEXT ("profiles while extracting object\n") + ACE_LIB_TEXT ("TAO (%P|%t) ERROR: reference from the ") + ACE_LIB_TEXT ("CDR stream.\n"))); } - objdata = orb_core->create_stub (type_hint.in (), - mp - ACE_ENV_ARG_PARAMETER); + objdata = + orb_core->create_stub (obj->ior_->type_id.in (), + mp + ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } ACE_CATCHANY @@ -680,19 +771,171 @@ operator>> (TAO_InputCDR& cdr, CORBA::Object*& x) ACE_LIB_TEXT ("object when demarshaling object ") ACE_LIB_TEXT ("reference.\n")); - return 0; + return; } ACE_ENDTRY; - ACE_CHECK_RETURN (0); + ACE_CHECK; TAO_Stub_Auto_Ptr safe_objdata (objdata); - x = orb_core->create_object (safe_objdata.get ()); - if (x == 0) - return 0; + if (orb_core->initialize_object (safe_objdata.get (), + obj) == -1) + return; + + obj->protocol_proxy_ = objdata; + + // If the object is collocated then set the broker using the + // factory otherwise use the remote proxy broker. + if (obj->is_collocated_ && + _TAO_collocation_Object_Proxy_Broker_Factory_function_pointer != 0) + obj->proxy_broker_ = + _TAO_collocation_Object_Proxy_Broker_Factory_function_pointer (obj); + else + obj->proxy_broker_ = the_tao_remote_object_proxy_broker (); + + obj->is_evaluated_ = 1; + + // 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) +{ + int lazy_strategy = 0; + 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_LIB_TEXT ("TAO (%P|%t) WARNING: extracting object from ") + ACE_LIB_TEXT ("default ORB_Core\n"))); + } + } + else + { + if (orb_core->resource_factory ()->resource_usage_strategy () == + TAO_Resource_Factory::TAO_LAZY) + lazy_strategy = 1; + } + + 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_LIB_TEXT ("TAO (%P|%t) - Object::tao_object_initialize ") + ACE_LIB_TEXT ("WARNING: extracting object from ") + ACE_LIB_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_LIB_TEXT ("TAO (%P|%t) ERROR: Could not create all ") + ACE_LIB_TEXT ("profiles while extracting object\n") + ACE_LIB_TEXT ("TAO (%P|%t) ERROR: reference from the ") + ACE_LIB_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_LIB_TEXT ("TAO (%P|%t) ERROR creating stub ") + ACE_LIB_TEXT ("object when demarshaling object ") + ACE_LIB_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 (); } |