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