// -*- C++ -*- //============================================================================= /** * @file Stub.h * * $Id$ * * @author Portions Copyright 1994-1995 by Sun Microsystems Inc. * @author Portions Copyright 1997-2002 by Washington University */ //============================================================================= #ifndef TAO_STUB_H #define TAO_STUB_H #include /**/ "ace/pre.h" #include "tao/ORB.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "tao/MProfile.h" #include "tao/ORB_Core_Auto_Ptr.h" #if defined (HPUX) && defined (IOR) /* HP-UX 11.11 defines IOR in /usr/include/pa/inline.h and we don't want that definition. See IOP_IORC.h. */ # undef IOR #endif /* HPUX && IOR */ // Forward declarations. class TAO_RelativeRoundtripTimeoutPolicy; class TAO_Client_Priority_Policy; class TAO_Sync_Scope_Policy; class TAO_Buffering_Constraint_Policy; class TAO_Sync_Strategy; class TAO_GIOP_Invocation; class TAO_Policy_Set; class TAO_Profile; /// Forward declaration for ObjectKey namespace TAO { class ObjectKey; } namespace IOP { struct IOR; } /** * @class TAO_Stub * * @brief TAO_Stub * * Per-objref data includes the (protocol-specific) Profile, which * is handled by placing it into a subclass of this type along * with data that may be used in protocol-specific caching * schemes. * The type ID (the data specified by CORBA 2.0 that gets exposed * "on the wire", and in stringified objrefs) is held by this * module. * The stub APIs are member functions of this type. */ class TAO_Export TAO_Stub { public: #if (TAO_HAS_CORBA_MESSAGING == 1) /** * Returns the effective policy if @a type is a known client-exposed * policy type. Returns the effective override for all other policy * types. */ virtual CORBA::Policy_ptr get_policy (CORBA::PolicyType type ACE_ENV_ARG_DECL_WITH_DEFAULTS); virtual CORBA::Policy_ptr get_client_policy (CORBA::PolicyType type ACE_ENV_ARG_DECL_WITH_DEFAULTS); virtual TAO_Stub* set_policy_overrides (const CORBA::PolicyList & policies, CORBA::SetOverrideType set_add ACE_ENV_ARG_DECL_WITH_DEFAULTS); virtual CORBA::PolicyList * get_policy_overrides ( const CORBA::PolicyTypeSeq & types ACE_ENV_ARG_DECL_WITH_DEFAULTS); #endif /* TAO_HAS_CORBA_MESSAGING == 1 */ // = Methods for obtaining effective overrides. // // Same functionality as , but more efficient. // Each of the methods below returns effective override for the // corresponding policy. The effective override is obtained by // first checking for an override of the given policy type at the // Object scope, then at the Current scope, then at the ORB scope, // and, finally, ORB default values are checked. #if (TAO_HAS_RELATIVE_ROUNDTRIP_TIMEOUT_POLICY == 1) CORBA::Policy_ptr relative_roundtrip_timeout (void); #endif /* TAO_HAS_RELATIVE_ROUNDTRIP_TIMEOUT_POLICY == 1 */ #if (TAO_HAS_SYNC_SCOPE_POLICY == 1) CORBA::Policy_ptr sync_scope (void); #endif /* TAO_HAS_SYNC_SCOPE_POLICY == 1 */ #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1) CORBA::Policy_ptr buffering_constraint (void); #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */ #if (TAO_HAS_CONNECTION_TIMEOUT_POLICY == 1) CORBA::Policy_ptr connection_timeout (void); #endif /* TAO_HAS_CONNECTION_TIMEOUT_POLICY == 1 */ /// Return the sync strategy to be used in by the transport. /// Selection will be based on the SyncScope policies. TAO_Sync_Strategy &sync_strategy (void); /// All objref representations carry around a type ID. CORBA::String_var type_id; /** * All objref representations know how to hash themselves and * compare themselves for equivalence to others. It's easily * possible to have two objrefs that are distinct copies of data * that refers/points to the same remote object (i.e. are * equivalent). */ CORBA::ULong hash (CORBA::ULong maximum ACE_ENV_ARG_DECL_WITH_DEFAULTS); /// Implement the is_equivalent() method for the CORBA::Object CORBA::Boolean is_equivalent (CORBA::Object_ptr other_obj); // Our Constructors ... /// Construct from a repository ID and a list of profiles. TAO_Stub (const char *repository_id, const TAO_MProfile &profiles, TAO_ORB_Core *orb_core); // = Memory management. CORBA::ULong _incr_refcnt (void); CORBA::ULong _decr_refcnt (void); /// Return the Profile lock. This lock can be used at places where /// profiles need to be edited. ACE_Lock *profile_lock (void) const; // Manage the base (non-forwarded) profiles. /// returns a pointer to the profile_in_use object. This object /// retains ownership of this profile. TAO_Profile *profile_in_use (void); /// Return the ObjectKey const TAO::ObjectKey &object_key (void) const; /** * Copy of the profile list, user must free memory when done. * although the user can call make_profiles() then reorder * the list and give it back to TAO_Stub. */ TAO_MProfile *make_profiles (void); /// Obtain a reference to the basic profile set. const TAO_MProfile& base_profiles (void) const; /// Obtain a reference to the basic profile set. TAO_MProfile& base_profiles (void); /// Obtain a pointer to the forwarded profile set const TAO_MProfile *forward_profiles (void) const; // Manage forward and base profiles. /** * THREAD SAFE. If forward_profiles is null then this will * get the next profile in the base_profiles list. If forward is not null * then this will get the next profile for the list of forwarding * profiles. If all profiles have been tried then 0 is returned and * profile_in_use_ is set to the first profile in the base_profiles * list. */ TAO_Profile *next_profile (void); /// NON-THREAD SAFE version of next_profile (void) TAO_Profile *next_profile_i (void); /** * THREAD SAFE * this method will reset the base profile list to reference the first * profile and if there are anmy existing forward profiles they are * reset. */ void reset_profiles (void); /// NON-THREAD SAFE version of reset_profiles (void); void reset_profiles_i (void); /// Returns 1 if a forward profile has successfully been used. /// profile_success_ && forward_profiles_ CORBA::Boolean valid_forward_profile (void); /// NON-THREAD-SAFE. Will set profile_success_ to 0. void set_valid_profile (void); /// Returns TRUE if a connection was successful with at least /// one profile. CORBA::Boolean valid_profile (void); /// Initialize the base_profiles_ and set profile_in_use_ to /// reference the first profile. TAO_Profile *base_profiles (const TAO_MProfile& mprofiles); /** * THREAD SAFE. * Set the forward_profiles. This object will assume ownership of * this TAO_MProfile object!! */ void add_forward_profiles (const TAO_MProfile &mprofiles); /** * THREAD SAFE * Used to get the next profile after the one being used has * failed during the initial connect or send of the message! */ CORBA::Boolean next_profile_retry (void); /// Accessor. TAO_ORB_Core* orb_core (void) const; /// This returns a duplicated ORB pointer. CORBA::ORB_ptr servant_orb_ptr (void); /// This returns the ORB var itself (generally for temporary use). CORBA::ORB_var &servant_orb_var (void); /** * Accesor and mutator for the servant ORB. Notice that the muatator * assumes the ownership of the passed in ORB and the accesor does not * return a copy of the orb since the accessing of the ORB is considered * temporary. */ void servant_orb (CORBA::ORB_ptr orb); /// Make a call on to services to see whether they have some /// preferences on selecting the right profiles. /** * @deprecated Remove after TAO 1.2.1 is released. */ CORBA::Boolean service_profile_selection (void); /** * Create the IOP::IOR info. We will create the info at most once. * Get the index of the profile we are using to make the invocation. */ int create_ior_info (IOP::IOR *&ior_info, CORBA::ULong &index ACE_ENV_ARG_DECL); /// Return a reference to the reference count lock. /** * This method is meant to be used by the CORBA::Object * implementation to allow it to directly manipulate the reference * count. */ TAO_SYNCH_MUTEX & refcount_lock (void); /// Return number of outstanding references to this object. /** * This method is meant to be used by the CORBA::Object * implementation to allow it to directly manipulate the reference * count. */ CORBA::ULong & refcount (void); /// Deallocate the TAO_Stub object. /** * This method is intended to be used only by the CORBA::Object * class. */ void destroy (void); /// Return the cached value from the ORB_Core. /** * This flag indicates whether the stub code should make use of the * collocation opportunities that are available to the ORB. */ CORBA::Boolean optimize_collocation_objects (void) const; protected: /// Destructor is to be called only through _decr_refcnt() to /// enforce proper reference counting. virtual ~TAO_Stub (void); private: /// Makes a copy of the profile and frees the existing profile_in_use. /// NOT THREAD SAFE TAO_Profile *set_profile_in_use_i (TAO_Profile *pfile); /// NON-THREAD-SAFE. Utility method which resets or initializes /// the base_profile list and forward flags. void reset_base (); /// NON-THREAD-SAFE. Utility method which unrolls (removes or pops) /// the top most forwarding profile list. void forward_back_one (void); /// NOT THREAD-SAFE. Utility method which pops all forward profile /// lists and resets the forward_profiles_ pointer. void reset_forward (); /// NON-THREAD-SAFE. utility method for next_profile. TAO_Profile *next_forward_profile (void); /// THREAD-SAFE Create the IOR info int get_profile_ior_info (TAO_MProfile &profile, IOP::IOR *&ior_info ACE_ENV_ARG_DECL); private: // = Disallow copy construction and assignment. ACE_UNIMPLEMENTED_FUNC (TAO_Stub (const TAO_Stub &)) ACE_UNIMPLEMENTED_FUNC (TAO_Stub &operator = (const TAO_Stub &)) protected: /// Automatically manage the ORB_Core reference count /** * The ORB_Core cannot go away until the object references it * creates are destroyed. There are multiple reasons for this, but * in particular, the allocators used for some of the TAO_Profile * objects contained on each TAO_Stub are owned by the TAO_ORB_Core. * * This must be the first field of the class, otherwise the * TAO_ORB_Core is destroyed too early! * */ TAO_ORB_Core_Auto_Ptr orb_core_; /// ORB required for reference counting. This will help us keep the /// ORB around until the CORBA::Object we represent dies. /** * @todo Why do we need both a reference to the ORB_Core and its * ORB? It think the memory management rules for the ORB_Core * changed, in the good old days it was the CORBA::ORB class * who owned the ORB_Core, now it is the other way around.... */ CORBA::ORB_var orb_; /** * If this stub refers to a collocated object then we need to hold on to * the servant's ORB (which may be different from the client ORB) so that, * 1. we know that the ORB will stay alive long enough, and, * 2. we can search for the servant/POA's status starting from * the ORB's RootPOA. */ CORBA::ORB_var servant_orb_; /// Ordered list of profiles for this object. TAO_MProfile base_profiles_; /// The list of forwarding profiles. This is actually implemented as a /// linked list of TAO_MProfile objects. TAO_MProfile *forward_profiles_; /// This is the profile that we are currently sending/receiving with. TAO_Profile *profile_in_use_; /// Mutex to protect access to the forwarding profile. ACE_Lock* profile_lock_ptr_; /// Have we successfully talked to the forward profile yet? size_t profile_success_; /// Mutex to protect reference count. TAO_SYNCH_MUTEX refcount_lock_; /// Number of outstanding references to this object. CORBA::ULong refcount_; /// The policy overrides in this object, if nil then use the default /// policies. TAO_Policy_Set *policies_; /** * The ior info. This is needed for GIOP 1.2, as the clients could * receive an exception from the server asking for this info. The * exception that the client receives is LOC_NEEDS_ADDRESSING_MODE. * The data is set up here to be passed on to Invocation classes * when they receive an exception. This info is for the base * profiles that this class stores */ IOP::IOR *ior_info_; /// Forwarded IOR info IOP::IOR *forwarded_ior_info_; /// TRUE if we want to take advantage of collocation optimization in /// this ORB. /** * This should be the same value as cached in the ORB_Core. The * reason for caching this helps our generated code, notably the * stubs to be decoubled from ORB_Core. Please do not move it away. */ const CORBA::Boolean collocation_opt_; }; // Define a TAO_Stub auto_ptr class. /** * @class TAO_Stub_Auto_Ptr * * @brief Implements the draft C++ standard auto_ptr abstraction. * This class allows one to work Stub Objects *Only*! */ class TAO_Export TAO_Stub_Auto_Ptr { public: // = Initialization and termination methods. /* explicit */ TAO_Stub_Auto_Ptr (TAO_Stub *p = 0); TAO_Stub_Auto_Ptr (TAO_Stub_Auto_Ptr &ap); TAO_Stub_Auto_Ptr &operator= (TAO_Stub_Auto_Ptr &rhs); ~TAO_Stub_Auto_Ptr (void); // = Accessor methods. TAO_Stub &operator *() const; TAO_Stub *get (void) const; TAO_Stub *release (void); void reset (TAO_Stub *p = 0); TAO_Stub *operator-> () const; protected: TAO_Stub *p_; }; #if defined (__ACE_INLINE__) # include "tao/Stub.i" #endif /* __ACE_INLINE__ */ #include /**/ "ace/post.h" #endif /* TAO_STUB_H */