Stub.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Stub.h
00006  *
00007  *  Stub.h,v 1.114 2006/06/19 19:48:30 jwillemsen Exp
00008  *
00009  *  @author  Portions Copyright 1994-1995 by Sun Microsystems Inc.
00010  *  @author  Portions Copyright 1997-2002 by Washington University
00011  */
00012 //=============================================================================
00013 
00014 #ifndef TAO_STUB_H
00015 #define TAO_STUB_H
00016 
00017 #include /**/ "ace/pre.h"
00018 
00019 #include "tao/ORB.h"
00020 
00021 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00022 # pragma once
00023 #endif /* ACE_LACKS_PRAGMA_ONCE */
00024 
00025 #include "tao/MProfile.h"
00026 #include "tao/ORB_Core_Auto_Ptr.h"
00027 
00028 #include "ace/Atomic_Op.h"
00029 
00030 #if defined (HPUX) && defined (IOR)
00031    /* HP-UX 11.11 defines IOR in /usr/include/pa/inline.h
00032       and we don't want that definition.  See IOP_IORC.h. */
00033 # undef IOR
00034 #endif /* HPUX && IOR */
00035 
00036 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00037 
00038 // Forward declarations.
00039 class TAO_Abstract_ServantBase;
00040 class TAO_Policy_Set;
00041 class TAO_Profile;
00042 
00043 namespace TAO
00044 {
00045   class ObjectKey;
00046   class Object_Proxy_Broker;
00047   class Transport_Queueing_Strategy;
00048 }
00049 
00050 namespace IOP
00051 {
00052   struct IOR;
00053 }
00054 
00055 /**
00056  * @class TAO_Stub
00057  *
00058  * @brief TAO_Stub
00059  *
00060  * Per-objref data includes the (protocol-specific) Profile, which
00061  * is handled by placing it into a subclass of this type along
00062  * with data that may be used in protocol-specific caching
00063  * schemes.
00064  * The type ID (the data specified by CORBA 2.0 that gets exposed
00065  * "on the wire", and in stringified objrefs) is held by this
00066  * module.
00067  * The stub APIs are member functions of this type.
00068  */
00069 class TAO_Export TAO_Stub
00070 {
00071 public:
00072 #if (TAO_HAS_CORBA_MESSAGING == 1)
00073 
00074   /**
00075    * Returns the effective policy if @a type is a known client-exposed
00076    * policy type.  Returns the effective override for all other policy
00077    * types.
00078    */
00079   virtual CORBA::Policy_ptr get_policy (CORBA::PolicyType type
00080                                         ACE_ENV_ARG_DECL);
00081 
00082   virtual CORBA::Policy_ptr get_cached_policy (TAO_Cached_Policy_Type type
00083                                                ACE_ENV_ARG_DECL);
00084 
00085   virtual TAO_Stub* set_policy_overrides (const CORBA::PolicyList & policies,
00086                                           CORBA::SetOverrideType set_add
00087                                           ACE_ENV_ARG_DECL);
00088 
00089   virtual CORBA::PolicyList *get_policy_overrides (
00090     const CORBA::PolicyTypeSeq & types
00091     ACE_ENV_ARG_DECL);
00092 
00093 #endif /* TAO_HAS_CORBA_MESSAGING == 1 */
00094 
00095   /// Return the queueing strategy to be used in by the transport.
00096   /// Selection will be based on the SyncScope policies.
00097   TAO::Transport_Queueing_Strategy &transport_queueing_strategy (void);
00098 
00099   /// All objref representations carry around a type ID.
00100   CORBA::String_var type_id;
00101 
00102   /**
00103    * All objref representations know how to hash themselves and
00104    * compare themselves for equivalence to others.  It's easily
00105    * possible to have two objrefs that are distinct copies of data
00106    * that refers/points to the same remote object (i.e. are
00107    * equivalent).
00108    */
00109   CORBA::ULong hash (CORBA::ULong maximum
00110                      ACE_ENV_ARG_DECL_WITH_DEFAULTS);
00111 
00112   /// Implement the is_equivalent() method for the CORBA::Object
00113   CORBA::Boolean is_equivalent (CORBA::Object_ptr other_obj);
00114 
00115   // Our Constructors ...
00116 
00117   /// Construct from a repository ID and a list of profiles.
00118   TAO_Stub (const char *repository_id,
00119             const TAO_MProfile &profiles,
00120             TAO_ORB_Core *orb_core);
00121 
00122   // = Memory management.
00123   void _incr_refcnt (void);
00124   void _decr_refcnt (void);
00125 
00126   /// Return the Profile lock. This lock can be used at places where
00127   /// profiles need to be edited.
00128   ACE_Lock *profile_lock (void) const;
00129 
00130   // Manage the base (non-forwarded) profiles.
00131   /// returns a pointer to the profile_in_use object.  This object
00132   /// retains ownership of this profile.
00133   TAO_Profile *profile_in_use (void);
00134 
00135   /// Return the ObjectKey
00136   const TAO::ObjectKey &object_key (void) const;
00137 
00138   /**
00139    * Copy of the profile list, user must free memory when done.
00140    * although the user can call make_profiles() then reorder
00141    * the list and give it back to TAO_Stub.
00142    */
00143   TAO_MProfile *make_profiles (void);
00144 
00145   /// Obtain a reference to the basic profile set.
00146   const TAO_MProfile& base_profiles (void) const;
00147 
00148   /// Obtain a reference to the basic profile set.
00149   TAO_MProfile& base_profiles (void);
00150 
00151   /// Obtain a pointer to the forwarded profile set
00152   const TAO_MProfile *forward_profiles (void) const;
00153 
00154   /// True if permanent location forward occured, in this case the lock must be set and the
00155 
00156   // Manage forward and base profiles.
00157   /**
00158    * THREAD SAFE.  If forward_profiles is null then this will
00159    * get the next profile in the base_profiles list.  If forward is not null
00160    * then this will get the next profile for the list of forwarding
00161    * profiles.  If all profiles have been tried then 0 is returned and
00162    * profile_in_use_ is set to the first profile in the base_profiles
00163    * list.
00164    */
00165   TAO_Profile *next_profile (void);
00166 
00167   /**
00168    * THREAD SAFE
00169    * this method will reset the base profile list to reference the first
00170    * profile and if there are anmy existing forward profiles they are
00171    * reset.
00172    */
00173   void reset_profiles (void);
00174 
00175   /// Returns 1 if a forward profile has successfully been used.
00176   /// profile_success_ && forward_profiles_
00177   CORBA::Boolean valid_forward_profile (void);
00178 
00179   /// NON-THREAD-SAFE.  Will set profile_success_ to 0.
00180   void set_valid_profile (void);
00181 
00182   /// Returns TRUE if a connection was successful with at least
00183   /// one profile.
00184   CORBA::Boolean valid_profile (void) const;
00185 
00186   /// Initialize the base_profiles_ and set profile_in_use_ to
00187   /// reference the first profile.
00188   TAO_Profile *base_profiles (const TAO_MProfile& mprofiles);
00189 
00190   /**
00191    * THREAD SAFE.
00192    * Set the forward_profiles.  This object will assume ownership of
00193    * this TAO_MProfile object!!  if permanent_forward is true,
00194    * currently used profiles will be replaced permanently, otherwise
00195    * stub may fallback to current profiles later.  The flag
00196    * permanent_forward=true is only valid if currently used profile
00197    * set represents a GroupObject (IOGR), otherwise this flag will be
00198    * ignored.
00199    */
00200   void add_forward_profiles (const TAO_MProfile &mprofiles,
00201                              const CORBA::Boolean permanent_forward=false);
00202 
00203   /**
00204    * THREAD SAFE
00205    * Used to get the next profile after the one being used has
00206    * failed during the initial connect or send of the message!
00207    */
00208   CORBA::Boolean next_profile_retry (void);
00209 
00210   /// Accessor.
00211   TAO_ORB_Core* orb_core (void) const;
00212 
00213   /// Is this stub collocated with the servant?
00214   CORBA::Boolean is_collocated (void) const;
00215 
00216   /// Mutator to mark this stub as being collocated with the servant.
00217   void is_collocated (CORBA::Boolean);
00218 
00219   /// This returns a duplicated ORB pointer.
00220   CORBA::ORB_ptr servant_orb_ptr (void);
00221 
00222   /// This returns the ORB var itself (generally for temporary use).
00223   CORBA::ORB_var &servant_orb_var (void);
00224 
00225   /**
00226    * Accesor and mutator for the servant ORB.  Notice that the mutator
00227    * assumes the ownership of the passed in ORB and the accesor does not
00228    * return a copy of the orb since the accessing of the ORB is considered
00229    * temporary.
00230    */
00231   void servant_orb (CORBA::ORB_ptr orb);
00232 
00233   /// Mutator for setting the servant in collocated cases.
00234   void collocated_servant (TAO_Abstract_ServantBase* servant);
00235 
00236   /// Accessor for the servant reference in collocated cases.
00237   TAO_Abstract_ServantBase* collocated_servant (void) const;
00238 
00239   /// Mutator for setting the object proxy broker pointer.
00240   /// CORBA::Objects using this stub will use this for standard calls
00241   /// like is_a; get_interface; etc...
00242   void object_proxy_broker (TAO::Object_Proxy_Broker *proxy_broker);
00243 
00244   /// Accessor for getting the object proxy broker pointer.
00245   /// CORBA::Objects using this stub use this for standard calls
00246   /// like is_a; get_interface; etc...
00247   TAO::Object_Proxy_Broker *object_proxy_broker (void) const;
00248 
00249   /**
00250    * Create the IOP::IOR info. We will create the info at most once.
00251    * Get the index of the profile we are using to make the invocation.
00252    */
00253   int create_ior_info (IOP::IOR *&ior_info,
00254                        CORBA::ULong &index
00255                        ACE_ENV_ARG_DECL);
00256 
00257   /// Deallocate the TAO_Stub object.
00258   /**
00259    * This method is intended to be used only by the CORBA::Object
00260    * class.
00261    */
00262   void destroy (void);
00263 
00264   /// Return the cached value from the ORB_Core.
00265   /**
00266    * This flag indicates whether the stub code should make use of the
00267    * collocation opportunities that are available to the ORB.
00268    */
00269   CORBA::Boolean optimize_collocation_objects (void) const;
00270 
00271   /// Needed to avoid copying forward_profiles for thread safety
00272   CORBA::Boolean marshal (TAO_OutputCDR&);
00273 
00274 protected:
00275 
00276   /// Destructor is to be called only through _decr_refcnt() to
00277   /// enforce proper reference counting.
00278   virtual ~TAO_Stub (void);
00279 
00280   /// NON-THREAD SAFE version of reset_profiles (void);
00281   void reset_profiles_i (void);
00282 
00283   /// NON-THREAD SAFE version of next_profile (void)
00284   TAO_Profile *next_profile_i (void);
00285 
00286 private:
00287   /// Makes a copy of the profile and frees the existing profile_in_use.
00288   /// NOT THREAD SAFE
00289   TAO_Profile *set_profile_in_use_i (TAO_Profile *pfile);
00290 
00291   /// NON-THREAD-SAFE.  Utility method which resets or initializes
00292   /// the base_profile list and forward flags.
00293   void reset_base ();
00294 
00295   /// NON-THREAD-SAFE.  Utility method which unrolls (removes or pops)
00296   /// the top most forwarding profile list.
00297   void forward_back_one (void);
00298 
00299    /// NOT THREAD-SAFE.  Utility method which pops all forward profile
00300    /// lists and resets the forward_profiles_ pointer.
00301   void reset_forward ();
00302 
00303   /// NON-THREAD-SAFE.  utility method for next_profile.
00304   TAO_Profile *next_forward_profile (void);
00305 
00306   /// THREAD-SAFE Create the IOR info
00307   int get_profile_ior_info (TAO_MProfile &profile,
00308                             IOP::IOR *&ior_info
00309                             ACE_ENV_ARG_DECL);
00310 
00311 private:
00312 
00313   // = Disallow copy construction and assignment.
00314   TAO_Stub (const TAO_Stub &);
00315   TAO_Stub &operator = (const TAO_Stub &);
00316 
00317 protected:
00318   /// Automatically manage the ORB_Core reference count
00319   /**
00320    * The ORB_Core cannot go away until the object references it
00321    * creates are destroyed.  There are multiple reasons for this, but
00322    * in particular, the allocators used for some of the TAO_Profile
00323    * objects contained on each TAO_Stub are owned by the TAO_ORB_Core.
00324    *
00325    * This <B>must</B> be the first field of the class, otherwise the
00326    * TAO_ORB_Core is destroyed too early!
00327    *
00328    */
00329   TAO_ORB_Core_Auto_Ptr orb_core_;
00330 
00331   /// ORB required for reference counting.  This will help us keep the
00332   /// ORB around until the CORBA::Object we represent dies.
00333   /**
00334    * @todo Why do we need both a reference to the ORB_Core and its
00335    *       ORB? It think the memory management rules for the ORB_Core
00336    *       changed, in the good old days it was the CORBA::ORB class
00337    *       who owned the ORB_Core, now it is the other way around....
00338    */
00339   CORBA::ORB_var orb_;
00340 
00341   /// Flag that indicates that this stub is collocated (and that it
00342   /// belongs to an ORB for which collocation optimisation is active).
00343   CORBA::Boolean is_collocated_;
00344 
00345   /**
00346    * If this stub refers to a collocated object then we need to hold on to
00347    * the servant's ORB (which may be different from the client ORB) so that,
00348    *   1. we know that the ORB will stay alive long enough, and,
00349    *   2. we can search for the servant/POA's status starting from
00350    *      the ORB's RootPOA.
00351    */
00352   CORBA::ORB_var servant_orb_;
00353 
00354   /// Servant pointer.  It is 0 except for collocated objects.
00355   TAO_Abstract_ServantBase *collocated_servant_;
00356 
00357   /// Pointer to the Proxy Broker
00358   /**
00359     * This cached pointer instance takes care of routing the call for
00360     * standard calls in CORBA::Object like _is_a (), _get_component
00361     * () etc.
00362     */
00363   TAO::Object_Proxy_Broker *object_proxy_broker_;
00364 
00365 
00366   /// Ordered list of profiles for this object.
00367   TAO_MProfile base_profiles_;
00368 
00369   /// The list of forwarding profiles.  This is actually implemented as a
00370   /// linked list of TAO_MProfile objects.
00371   TAO_MProfile *forward_profiles_;
00372 
00373   // The bookmark indicating permanent forward occured,
00374   // the pointer is used to indentify bottom of stack forward_profiles_
00375   TAO_MProfile *forward_profiles_perm_;
00376 
00377   /// This is the profile that we are currently sending/receiving with.
00378   TAO_Profile *profile_in_use_;
00379 
00380   /// Mutex to protect access to the forwarding profile.
00381   ACE_Lock* profile_lock_ptr_;
00382 
00383   /// Have we successfully talked to the forward profile yet?
00384   CORBA::Boolean profile_success_;
00385 
00386   /// Reference counter.
00387   ACE_Atomic_Op<TAO_SYNCH_MUTEX, CORBA::ULong> refcount_;
00388 
00389   /// The policy overrides in this object, if nil then use the default
00390   /// policies.
00391   TAO_Policy_Set *policies_;
00392 
00393   /**
00394    * The ior info. This is needed for GIOP 1.2, as the clients could
00395    * receive an exception from the server asking for this info.  The
00396    * exception that the client receives is LOC_NEEDS_ADDRESSING_MODE.
00397    * The data is set up here to be passed on to Invocation classes
00398    * when they receive an exception. This info is for the base
00399    * profiles that this class stores
00400    */
00401   IOP::IOR *ior_info_;
00402 
00403   /// Forwarded IOR info
00404   IOP::IOR *forwarded_ior_info_;
00405 
00406   /// TRUE if we want to take advantage of collocation optimization in
00407   /// this ORB.
00408   /**
00409    * This should be the same value as cached in the ORB_Core. The
00410    * reason for caching this helps our generated code, notably the
00411    * stubs to be decoubled from ORB_Core. Please do not move it away.
00412    */
00413   const CORBA::Boolean collocation_opt_;
00414 };
00415 
00416 // Define a TAO_Stub auto_ptr class.
00417 /**
00418  * @class TAO_Stub_Auto_Ptr
00419  *
00420  * @brief Implements the draft C++ standard auto_ptr abstraction.
00421  * This class allows one to work Stub Objects *Only*!
00422  */
00423 class TAO_Export TAO_Stub_Auto_Ptr
00424 {
00425 public:
00426   // = Initialization and termination methods.
00427   explicit TAO_Stub_Auto_Ptr (TAO_Stub *p = 0);
00428   TAO_Stub_Auto_Ptr (TAO_Stub_Auto_Ptr &ap);
00429   TAO_Stub_Auto_Ptr &operator= (TAO_Stub_Auto_Ptr &rhs);
00430   ~TAO_Stub_Auto_Ptr (void);
00431 
00432   // = Accessor methods.
00433   TAO_Stub &operator *() const;
00434   TAO_Stub *get (void) const;
00435   TAO_Stub *release (void);
00436   void reset (TAO_Stub *p = 0);
00437   TAO_Stub *operator-> () const;
00438 
00439 protected:
00440   TAO_Stub *p_;
00441 
00442 };
00443 
00444 TAO_END_VERSIONED_NAMESPACE_DECL
00445 
00446 #if defined (__ACE_INLINE__)
00447 # include "tao/Stub.i"
00448 #endif /* __ACE_INLINE__ */
00449 
00450 #include /**/ "ace/post.h"
00451 
00452 #endif /* TAO_STUB_H */

Generated on Thu Nov 9 11:54:22 2006 for TAO by doxygen 1.3.6