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 */