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