Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / Stub.h
bloba44c33af78e80040eb88262bda23036101a3d647
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Stub.h
7 * @author Portions Copyright 1994-1995 by Sun Microsystems Inc.
8 * @author Portions Copyright 1997-2002 by Washington University
9 */
10 //=============================================================================
12 #ifndef TAO_STUB_H
13 #define TAO_STUB_H
15 #include /**/ "ace/pre.h"
17 #include "tao/ORB.h"
19 #if !defined (ACE_LACKS_PRAGMA_ONCE)
20 # pragma once
21 #endif /* ACE_LACKS_PRAGMA_ONCE */
23 #include "tao/MProfile.h"
24 #include "tao/ORB_Core_Auto_Ptr.h"
25 #include <atomic>
27 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
29 // Forward declarations.
30 class TAO_Abstract_ServantBase;
31 class TAO_Policy_Set;
32 class TAO_Profile;
34 namespace TAO
36 class ObjectKey;
37 class Object_Proxy_Broker;
38 class Transport_Queueing_Strategy;
41 namespace IOP
43 struct IOR;
46 /**
47 * @class TAO_Stub
49 * @brief TAO_Stub
51 * Per-objref data includes the (protocol-specific) Profile, which
52 * is handled by placing it into a subclass of this type along
53 * with data that may be used in protocol-specific caching
54 * schemes.
55 * The type ID (the data specified by CORBA 2.0 that gets exposed
56 * "on the wire", and in stringified objrefs) is held by this
57 * module.
58 * The stub APIs are member functions of this type.
60 class TAO_Export TAO_Stub
62 public:
63 #if (TAO_HAS_CORBA_MESSAGING == 1)
64 /**
65 * Returns the effective policy if @a type is a known client-exposed
66 * policy type. Returns the effective override for all other policy
67 * types.
69 virtual CORBA::Policy_ptr get_policy (CORBA::PolicyType type);
71 virtual CORBA::Policy_ptr get_cached_policy (TAO_Cached_Policy_Type type);
73 virtual TAO_Stub* set_policy_overrides (const CORBA::PolicyList & policies,
74 CORBA::SetOverrideType set_add);
76 virtual CORBA::PolicyList *get_policy_overrides (
77 const CORBA::PolicyTypeSeq & types);
78 #endif
80 /// Return the queueing strategy to be used in by the transport.
81 /// Selection will be based on the SyncScope policies.
82 TAO::Transport_Queueing_Strategy *transport_queueing_strategy ();
84 /// All objref representations carry around a type ID.
85 CORBA::String_var type_id;
87 /**
88 * All objref representations know how to hash themselves and
89 * compare themselves for equivalence to others. It's easily
90 * possible to have two objrefs that are distinct copies of data
91 * that refers/points to the same remote object (i.e. are
92 * equivalent).
94 CORBA::ULong hash (CORBA::ULong maximum);
96 /// Implement the is_equivalent() method for the CORBA::Object
97 CORBA::Boolean is_equivalent (CORBA::Object_ptr other_obj);
99 // Our Constructors ...
101 /// Construct from a repository ID and a list of profiles.
102 TAO_Stub (const char *repository_id,
103 const TAO_MProfile &profiles,
104 TAO_ORB_Core *orb_core);
106 // = Memory management.
107 void _incr_refcnt ();
108 void _decr_refcnt ();
110 /// Return the Profile lock. This lock can be used at places where
111 /// profiles need to be edited.
112 const TAO_SYNCH_MUTEX& profile_lock () const;
114 /// Manage the base (non-forwarded) profiles.
115 /// Returns a pointer to the profile_in_use object. This object
116 /// retains ownership of this profile.
117 TAO_Profile *profile_in_use ();
119 /// Return the ObjectKey
120 const TAO::ObjectKey &object_key () const;
123 * Copy of the profile list, user must free memory when done.
124 * although the user can call make_profiles() then reorder
125 * the list and give it back to TAO_Stub.
127 TAO_MProfile *make_profiles ();
129 /// Obtain a reference to the basic profile set.
130 const TAO_MProfile& base_profiles () const;
132 /// Obtain a reference to the basic profile set.
133 TAO_MProfile& base_profiles ();
135 /// Obtain a pointer to the forwarded profile set
136 const TAO_MProfile *forward_profiles () const;
138 /// Obtain a pointer to the forwarded profile set
139 TAO_MProfile *forward_profiles ();
141 /// True if permanent location forward occurred, in this case the lock must be set and the
143 // Manage forward and base profiles.
145 * THREAD SAFE. If forward_profiles is null then this will
146 * get the next profile in the base_profiles list. If forward is not null
147 * then this will get the next profile for the list of forwarding
148 * profiles. If all profiles have been tried then 0 is returned and
149 * profile_in_use_ is set to the first profile in the base_profiles
150 * list.
152 TAO_Profile *next_profile ();
155 * THREAD SAFE
156 * This method will reset the base profile list to reference the first
157 * profile and if there are anmy existing forward profiles they are
158 * reset.
160 void reset_profiles ();
162 /// Returns true if the profile in use is
163 /// the same as the profile in use after
164 /// reset_profiles() is called.
165 CORBA::Boolean at_starting_profile () const;
167 /// Returns true if a forward profile has successfully been used.
168 /// profile_success_ && forward_profiles_
169 CORBA::Boolean valid_forward_profile ();
171 /// NON-THREAD-SAFE. Will set profile_success_ to true.
172 void set_valid_profile ();
174 /// Returns true if a connection was successful with at least
175 /// one profile.
176 CORBA::Boolean valid_profile () const;
178 /// Initialize the base_profiles_ and set profile_in_use_ to
179 /// reference the first profile.
180 TAO_Profile *base_profiles (const TAO_MProfile& mprofiles);
183 * THREAD SAFE.
184 * Set the forward_profiles. This object will assume ownership of
185 * this TAO_MProfile object!! if @a permanent_forward is true,
186 * currently used profiles will be replaced permanently, otherwise
187 * stub may fallback to current profiles later. The flag
188 * permanent_forward=true is only valid if currently used profile
189 * set represents a GroupObject (IOGR), otherwise this flag will be
190 * ignored.
192 void add_forward_profiles (const TAO_MProfile &mprofiles,
193 const CORBA::Boolean permanent_forward = false);
196 * THREAD SAFE
197 * Used to get the next profile after the one being used has
198 * failed during the initial connect or send of the message!
200 CORBA::Boolean next_profile_retry ();
202 /// Accessor.
203 TAO_ORB_Core* orb_core () const;
205 /// Is this stub collocated with the servant?
206 CORBA::Boolean is_collocated () const;
208 /// Mutator to mark this stub as being collocated with the servant.
209 void is_collocated (CORBA::Boolean);
211 /// This returns a duplicated ORB pointer.
212 CORBA::ORB_ptr servant_orb_ptr ();
214 /// This returns the ORB var itself (generally for temporary use).
215 CORBA::ORB_var &servant_orb_var ();
218 * Accesor and mutator for the servant ORB. Notice that the mutator
219 * assumes the ownership of the passed in ORB and the accesor does not
220 * return a copy of the orb since the accessing of the ORB is considered
221 * temporary.
223 void servant_orb (CORBA::ORB_ptr orb);
225 /// Mutator for setting the servant in collocated cases.
226 void collocated_servant (TAO_Abstract_ServantBase* servant);
228 /// Accessor for the servant reference in collocated cases.
229 TAO_Abstract_ServantBase* collocated_servant () const;
231 /// Mutator for setting the object proxy broker pointer.
232 /// CORBA::Objects using this stub will use this for standard calls
233 /// like is_a; get_interface; etc...
234 void object_proxy_broker (TAO::Object_Proxy_Broker *proxy_broker);
236 /// Accessor for getting the object proxy broker pointer.
237 /// CORBA::Objects using this stub use this for standard calls
238 /// like is_a; get_interface; etc...
239 TAO::Object_Proxy_Broker *object_proxy_broker () const;
242 * Create the IOP::IOR info. We will create the info at most once.
243 * Get the index of the profile we are using to make the invocation.
245 int create_ior_info (IOP::IOR *&ior_info, CORBA::ULong &index);
247 /// Deallocate the TAO_Stub object.
249 * This method is intended to be used only by the CORBA::Object
250 * class.
252 void destroy ();
254 /// Return the cached value from the ORB_Core.
256 * This flag indicates whether the stub code should make use of the
257 * collocation opportunities that are available to the ORB.
259 CORBA::Boolean optimize_collocation_objects () const;
261 /// Needed to avoid copying forward_profiles for thread safety
262 CORBA::Boolean marshal (TAO_OutputCDR&);
264 void forwarded_on_exception (bool forwarded);
265 bool forwarded_on_exception () const;
267 protected:
268 /// Destructor is to be called only through _decr_refcnt() to
269 /// enforce proper reference counting.
270 virtual ~TAO_Stub ();
272 /// NON-THREAD SAFE version of reset_profiles ();
273 void reset_profiles_i ();
275 /// NON-THREAD SAFE version of next_profile ()
276 TAO_Profile *next_profile_i ();
278 private:
279 /// Makes a copy of the profile and frees the existing profile_in_use.
280 /// NOT THREAD SAFE
281 TAO_Profile *set_profile_in_use_i (TAO_Profile *pfile);
283 /// NON-THREAD-SAFE. Utility method which resets or initializes
284 /// the base_profile list and forward flags.
285 void reset_base ();
287 /// NON-THREAD-SAFE. Utility method which unrolls (removes or pops)
288 /// the top most forwarding profile list.
289 void forward_back_one ();
291 /// NOT THREAD-SAFE. Utility method which pops all forward profile
292 /// lists and resets the forward_profiles_ pointer.
293 void reset_forward ();
295 /// NON-THREAD-SAFE. utility method for next_profile.
296 TAO_Profile *next_forward_profile ();
298 /// THREAD-SAFE Create the IOR info
299 int get_profile_ior_info (TAO_MProfile &profile, IOP::IOR *&ior_info);
301 private:
302 // = Disallow copy construction and assignment.
303 TAO_Stub (const TAO_Stub &);
304 TAO_Stub &operator = (const TAO_Stub &);
306 protected:
307 /// Automatically manage the ORB_Core reference count
309 * The ORB_Core cannot go away until the object references it
310 * creates are destroyed. There are multiple reasons for this, but
311 * in particular, the allocators used for some of the TAO_Profile
312 * objects contained on each TAO_Stub are owned by the TAO_ORB_Core.
314 * This <B>must</B> be the first field of the class, otherwise the
315 * TAO_ORB_Core is destroyed too early!
317 TAO_ORB_Core_Auto_Ptr orb_core_;
319 /// ORB required for reference counting. This will help us keep the
320 /// ORB around until the CORBA::Object we represent dies.
322 * @todo Why do we need both a reference to the ORB_Core and its
323 * ORB? It think the memory management rules for the ORB_Core
324 * changed, in the good old days it was the CORBA::ORB class
325 * who owned the ORB_Core, now it is the other way around....
327 CORBA::ORB_var orb_;
329 /// Flag that indicates that this stub is collocated (and that it
330 /// belongs to an ORB for which collocation optimisation is active).
331 CORBA::Boolean is_collocated_;
334 * If this stub refers to a collocated object then we need to hold on to
335 * the servant's ORB (which may be different from the client ORB) so that,
336 * 1. we know that the ORB will stay alive long enough, and,
337 * 2. we can search for the servant/POA's status starting from
338 * the ORB's RootPOA.
340 CORBA::ORB_var servant_orb_;
342 /// Servant pointer. It is 0 except for collocated objects.
343 TAO_Abstract_ServantBase *collocated_servant_;
345 /// Pointer to the Proxy Broker
347 * This cached pointer instance takes care of routing the call for
348 * standard calls in CORBA::Object like _is_a (), _get_component
349 * () etc.
351 TAO::Object_Proxy_Broker *object_proxy_broker_;
353 /// Ordered list of profiles for this object.
354 TAO_MProfile base_profiles_;
356 /// The list of forwarding profiles. This is actually implemented as a
357 /// linked list of TAO_MProfile objects.
358 TAO_MProfile *forward_profiles_;
360 /// The bookmark indicating permanent forward occurred,
361 /// the pointer is used to identify bottom of stack forward_profiles_
362 TAO_MProfile *forward_profiles_perm_;
364 /// This is the profile that we are currently sending/receiving with.
365 TAO_Profile *profile_in_use_;
367 /// Mutex to protect access to the forwarding profile.
368 TAO_SYNCH_MUTEX profile_lock_;
370 /// Have we successfully talked to the forward profile yet?
371 CORBA::Boolean profile_success_;
373 /// Reference counter.
374 std::atomic<uint32_t> refcount_;
376 /// The policy overrides in this object, if nil then use the default
377 /// policies.
378 TAO_Policy_Set *policies_;
381 * The ior info. This is needed for GIOP 1.2, as the clients could
382 * receive an exception from the server asking for this info. The
383 * exception that the client receives is LOC_NEEDS_ADDRESSING_MODE.
384 * The data is set up here to be passed on to Invocation classes
385 * when they receive an exception. This info is for the base
386 * profiles that this class stores
388 IOP::IOR *ior_info_;
390 /// Forwarded IOR info
391 IOP::IOR *forwarded_ior_info_;
393 /// TRUE if we want to take advantage of collocation optimization in
394 /// this ORB.
396 * This should be the same value as cached in the ORB_Core. The
397 * reason for caching this helps our generated code, notably the
398 * stubs to be decoupled from ORB_Core. Please do not move it away.
400 CORBA::Boolean const collocation_opt_;
402 /// True if forwarding request upon some specific exceptions
403 /// (e.g. OBJECT_NOT_EXIST) already happened.
404 std::atomic<bool> forwarded_on_exception_;
408 * Custom deleter to decrement the refcount when called
410 struct TAO_Export TAO_Stub_Decr_Refcnt
412 void operator()(TAO_Stub* stub) const { if (stub) stub->_decr_refcnt(); }
416 * TAO_Stub_Auto_Ptr will decrement the refcount when going our of scope
417 * using std::unique_ptr and a custom deleter
419 using TAO_Stub_Auto_Ptr = std::unique_ptr<TAO_Stub, TAO_Stub_Decr_Refcnt>;
421 TAO_END_VERSIONED_NAMESPACE_DECL
423 #if defined (__ACE_INLINE__)
424 # include "tao/Stub.inl"
425 #endif /* __ACE_INLINE__ */
427 #include /**/ "ace/post.h"
429 #endif /* TAO_STUB_H */