Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / PortableServer / Object_Adapter.cpp
blob5669bbd2065cd7370542ce1b497d272e98bf060d
1 // -- PortableServer Include --
2 #include "tao/PortableServer/Object_Adapter.h"
3 #include "tao/PortableServer/Non_Servant_Upcall.h"
4 #include "tao/PortableServer/Servant_Upcall.h"
5 #include "tao/PortableServer/Root_POA.h"
6 #include "tao/PortableServer/Regular_POA.h"
7 #include "tao/PortableServer/Creation_Time.h"
8 #include "tao/PortableServer/POA_Guard.h"
9 #include "tao/PortableServer/Default_Servant_Dispatcher.h"
10 #include "tao/PortableServer/Collocated_Object_Proxy_Broker.h"
11 #include "tao/PortableServer/POAManager.h"
12 #include "tao/PortableServer/POAManagerFactory.h"
13 #include "tao/PortableServer/Servant_Base.h"
15 // -- ACE Include --
16 #include <memory>
17 #include "ace/Log_Msg.h"
18 #include "ace/OS_NS_string.h"
20 // -- TAO Include --
21 #include "tao/PortableInterceptorC.h"
22 #include "tao/ORB.h"
23 #include "tao/ORB_Core.h"
24 #include "tao/TSS_Resources.h"
25 #include "tao/TAO_Server_Request.h"
26 #include "tao/Stub.h"
27 #include "tao/Profile.h"
28 #include "tao/MProfile.h"
29 #include "tao/debug.h"
30 #include "tao/PortableInterceptor.h"
31 #include "tao/ORBInitializer_Registry.h"
32 #include "tao/Thread_Lane_Resources_Manager.h"
33 #include "tao/Thread_Lane_Resources.h"
34 #include "tao/Protocols_Hooks.h"
35 #include "tao/ServerRequestInterceptor_Adapter.h"
37 #if !defined (__ACE_INLINE__)
38 # include "tao/PortableServer/Object_Adapter.inl"
39 #endif /* __ACE_INLINE__ */
41 #include "tao/PortableServer/ThreadPolicy.h"
42 #include "tao/PortableServer/LifespanPolicy.h"
43 #include "tao/PortableServer/IdAssignmentPolicy.h"
44 #include "tao/PortableServer/IdUniquenessPolicy.h"
45 #include "tao/PortableServer/ImplicitActivationPolicy.h"
46 #include "tao/PortableServer/RequestProcessingPolicy.h"
47 #include "tao/PortableServer/ServantRetentionPolicy.h"
49 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
50 namespace PortableServer
52 class POAManagerFactory;
53 typedef POAManagerFactory *POAManagerFactory_ptr;
55 #endif
57 // Timeprobes class
58 #include "tao/Timeprobe.h"
60 #if defined (ACE_ENABLE_TIMEPROBES)
62 static const char *TAO_Object_Adapter_Timeprobe_Description[] =
64 "Object_Adapter::dispatch_servant - start",
65 "Object_Adapter::dispatch_servant - end",
67 "POA::parse_key - start",
68 "POA::parse_key - end",
70 "Object_Adapter::find_poa - start",
71 "Object_Adapter::find_poa - end",
73 "POA::locate_servant - start",
74 "POA::locate_servant - end",
76 "Servant::_dispatch - start",
77 "Servant::_dispatch - end",
80 enum
82 // Timeprobe description table start key
83 TAO_OBJECT_ADAPTER_DISPATCH_SERVANT_START = 200,
84 TAO_OBJECT_ADAPTER_DISPATCH_SERVANT_END,
86 TAO_POA_PARSE_KEY_START,
87 TAO_POA_PARSE_KEY_END,
89 TAO_OBJECT_ADAPTER_FIND_POA_START,
90 TAO_OBJECT_ADAPTER_FIND_POA_END,
92 TAO_POA_LOCATE_SERVANT_START,
93 TAO_POA_LOCATE_SERVANT_END,
95 TAO_SERVANT_DISPATCH_START,
96 TAO_SERVANT_DISPATCH_END
99 // Setup Timeprobes
100 ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Object_Adapter_Timeprobe_Description,
101 TAO_OBJECT_ADAPTER_DISPATCH_SERVANT_START);
103 #endif /* ACE_ENABLE_TIMEPROBES */
105 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
107 /* static */
108 CORBA::ULong TAO_Object_Adapter::transient_poa_name_size_ = 0;
110 void
111 TAO_Object_Adapter::set_transient_poa_name_size (const TAO_Server_Strategy_Factory::Active_Object_Map_Creation_Parameters &creation_parameters)
113 if (TAO_Object_Adapter::transient_poa_name_size_ == 0)
115 switch (creation_parameters.poa_lookup_strategy_for_transient_id_policy_)
117 #if (TAO_HAS_MINIMUM_POA_MAPS == 0)
118 case TAO_LINEAR:
119 TAO_Object_Adapter::transient_poa_name_size_ =
120 sizeof (CORBA::ULong);
121 break;
122 case TAO_DYNAMIC_HASH:
123 TAO_Object_Adapter::transient_poa_name_size_ =
124 sizeof (CORBA::ULong);
125 break;
126 #endif /* TAO_HAS_MINIMUM_POA_MAPS == 0 */
127 case TAO_ACTIVE_DEMUX:
128 default:
129 TAO_Object_Adapter::transient_poa_name_size_ =
130 static_cast <CORBA::ULong>(
131 ACE_Active_Map_Manager_Key::size ());
132 break;
137 TAO_Object_Adapter::TAO_Object_Adapter (const TAO_Server_Strategy_Factory::Active_Object_Map_Creation_Parameters &creation_parameters,
138 TAO_ORB_Core &orb_core)
139 : hint_strategy_ (0),
140 servant_dispatcher_ (0),
141 persistent_poa_name_map_ (0),
142 transient_poa_map_ (0),
143 orb_core_ (orb_core),
144 thread_lock_ (),
145 lock_ (TAO_Object_Adapter::create_lock (thread_lock_)),
146 reverse_lock_ (*lock_),
147 non_servant_upcall_condition_ (thread_lock_),
148 non_servant_upcall_in_progress_ (0),
149 non_servant_upcall_nesting_level_ (0),
150 non_servant_upcall_thread_ (ACE_OS::NULL_thread),
151 root_ (0),
152 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
153 poa_manager_factory_ (0),
154 #endif
155 default_validator_ (orb_core),
156 default_poa_policies_ ()
158 TAO_Object_Adapter::set_transient_poa_name_size (creation_parameters);
160 Hint_Strategy *hint_strategy = 0;
161 if (creation_parameters.use_active_hint_in_poa_names_)
162 ACE_NEW (hint_strategy,
163 Active_Hint_Strategy (creation_parameters.poa_map_size_));
164 else
165 ACE_NEW (hint_strategy,
166 No_Hint_Strategy);
168 // Give ownership to the unique pointer.
169 std::unique_ptr<Hint_Strategy> new_hint_strategy (hint_strategy);
171 new_hint_strategy->object_adapter (this);
173 persistent_poa_name_map *ppnm = 0;
174 switch (creation_parameters.poa_lookup_strategy_for_persistent_id_policy_)
176 case TAO_LINEAR:
177 #if (TAO_HAS_MINIMUM_POA_MAPS == 0)
178 ACE_NEW (ppnm,
179 persistent_poa_name_linear_map (creation_parameters.poa_map_size_));
181 break;
182 #else
183 TAOLIB_ERROR ((LM_ERROR,
184 "linear option for -ORBPersistentidPolicyDemuxStrategy "
185 "not supported with minimum POA maps. "
186 "Ignoring option to use default...\n"));
187 /* FALL THROUGH */
188 #endif /* TAO_HAS_MINIMUM_POA_MAPS == 0 */
189 case TAO_DYNAMIC_HASH:
190 default:
191 ACE_NEW (ppnm,
192 persistent_poa_name_hash_map (creation_parameters.poa_map_size_));
193 break;
195 // Give ownership to the unique pointer.
196 std::unique_ptr<persistent_poa_name_map> new_persistent_poa_name_map (ppnm);
198 transient_poa_map *tpm = 0;
199 switch (creation_parameters.poa_lookup_strategy_for_transient_id_policy_)
201 #if (TAO_HAS_MINIMUM_POA_MAPS == 0)
202 case TAO_LINEAR:
203 ACE_NEW (tpm,
204 transient_poa_linear_map (creation_parameters.poa_map_size_));
205 break;
206 case TAO_DYNAMIC_HASH:
207 ACE_NEW (tpm,
208 transient_poa_hash_map (creation_parameters.poa_map_size_));
209 break;
210 #else
211 case TAO_LINEAR:
212 case TAO_DYNAMIC_HASH:
213 TAOLIB_ERROR ((LM_ERROR,
214 "linear and dynamic options for -ORBTransientidPolicyDemuxStrategy "
215 "are not supported with minimum POA maps. "
216 "Ignoring option to use default...\n"));
217 /* FALL THROUGH */
218 #endif /* TAO_HAS_MINIMUM_POA_MAPS == 0 */
219 case TAO_ACTIVE_DEMUX:
220 default:
221 ACE_NEW (tpm,
222 transient_poa_active_map (creation_parameters.poa_map_size_));
223 break;
225 // Give ownership to the unique pointer.
226 std::unique_ptr<transient_poa_map> new_transient_poa_map (tpm);
228 this->hint_strategy_ = new_hint_strategy.release ();
229 this->persistent_poa_name_map_ = new_persistent_poa_name_map.release ();
230 this->transient_poa_map_ = new_transient_poa_map.release ();
233 void
234 TAO_Object_Adapter::init_default_policies (TAO_POA_Policy_Set &policies)
236 // Initialize the default policies.
237 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
239 TAO::Portable_Server::ThreadPolicy thread_policy (PortableServer::ORB_CTRL_MODEL);
240 policies.merge_policy (&thread_policy);
242 #endif /* TAO_HAS_MINIMUM_POA == 0 */
244 #if !defined (CORBA_E_MICRO)
245 // Lifespan policy.
246 TAO::Portable_Server::LifespanPolicy lifespan_policy (PortableServer::TRANSIENT);
247 policies.merge_policy (&lifespan_policy);
248 #endif
250 #if !defined (CORBA_E_MICRO)
251 // ID uniqueness policy.
252 TAO::Portable_Server::IdUniquenessPolicy id_uniqueness_policy (PortableServer::UNIQUE_ID);
253 policies.merge_policy (&id_uniqueness_policy);
254 #endif
256 #if !defined (CORBA_E_MICRO)
257 // ID assignment policy.
258 TAO::Portable_Server::IdAssignmentPolicy id_assignment_policy (PortableServer::SYSTEM_ID);
259 policies.merge_policy (&id_assignment_policy);
260 #endif
262 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
263 // Implicit activation policy.
264 TAO::Portable_Server::ImplicitActivationPolicy implicit_activation_policy
265 (PortableServer::NO_IMPLICIT_ACTIVATION);
266 policies.merge_policy (&implicit_activation_policy);
268 // Servant retention policy.
269 TAO::Portable_Server::ServantRetentionPolicy servant_retention_policy
270 (PortableServer::RETAIN);
271 policies.merge_policy (&servant_retention_policy);
273 // Request processing policy.
274 TAO::Portable_Server::RequestProcessingPolicy request_processing_policy
275 (PortableServer::USE_ACTIVE_OBJECT_MAP_ONLY);
276 policies.merge_policy (&request_processing_policy);
277 #endif /* TAO_HAS_MINIMUM_POA == 0 */
278 #if defined (CORBA_E_MICRO)
279 ACE_UNUSED_ARG (policies);
280 #endif
283 TAO_Object_Adapter::~TAO_Object_Adapter ()
285 delete this->hint_strategy_;
286 delete this->persistent_poa_name_map_;
287 delete this->transient_poa_map_;
288 delete this->lock_;
290 delete this->servant_dispatcher_;
292 // This cleanup may have already occurred in the close() method. If
293 // that is the case then this won't cause any harm since root_ and
294 // poa_manager_factory_ would have been set to zero. But, if close
295 // wasn't called, then these would be leaked. It may be better if
296 // these pointers had a corresponding _var version so that this cleanup
297 // could be automatic.
298 ::CORBA::release (this->root_);
299 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
300 release_poa_manager_factory (this->poa_manager_factory_);
301 #endif
304 /* static */
305 ACE_Lock *
306 TAO_Object_Adapter::create_lock (TAO_SYNCH_MUTEX &thread_lock)
308 ACE_Lock *the_lock = 0;
309 ACE_NEW_RETURN (the_lock,
310 ACE_Lock_Adapter<TAO_SYNCH_MUTEX> (thread_lock),
312 return the_lock;
316 TAO_Object_Adapter::dispatch_servant (const TAO::ObjectKey &key,
317 TAO_ServerRequest &req,
318 CORBA::Object_out forward_to)
320 ACE_FUNCTION_TIMEPROBE (TAO_OBJECT_ADAPTER_DISPATCH_SERVANT_START);
322 // This object is magical, i.e., it has a non-trivial constructor
323 // and destructor.
324 TAO::Portable_Server::Servant_Upcall servant_upcall (&this->orb_core_);
326 // Set up state in the POA et al (including the POA Current), so
327 // that we know that this servant is currently in an upcall.
328 const char *operation = req.operation ();
329 int result = servant_upcall.prepare_for_upcall (key, operation, forward_to);
331 if (result != TAO_Adapter::DS_OK)
332 return result;
334 // Preprocess request.
335 if (req.collocated ())
337 servant_upcall.pre_invoke_collocated_request ();
339 else
341 servant_upcall.pre_invoke_remote_request (req);
344 // Servant dispatch.
346 ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_DISPATCH_START);
348 do_dispatch (req, servant_upcall);
351 #if TAO_HAS_INTERCEPTORS == 1
352 // ServerInterceptor might have raised ForwardRequest. In case of
353 // remote calls invocations the LocationForwardReply would have been
354 // sent in earlier stage, but in colocal scenario no message is sent
355 // and the LocationForward object must be passed over here to
356 // calling operation's mem-space.
357 if (req.collocated() && req.pi_reply_status () == PortableInterceptor::LOCATION_FORWARD)
359 forward_to = req.forward_location ();
360 result = TAO_Adapter::DS_FORWARD;
362 #endif
364 return result;
367 void
368 TAO_Object_Adapter::locate_poa (const TAO::ObjectKey &key,
369 PortableServer::ObjectId &system_id,
370 TAO_Root_POA *&poa)
372 TAO_Object_Adapter::poa_name poa_system_name;
373 CORBA::Boolean is_root = false;
374 CORBA::Boolean is_persistent = false;
375 CORBA::Boolean is_system_id = false;
376 TAO::Portable_Server::Temporary_Creation_Time poa_creation_time;
378 int result = 0;
381 ACE_FUNCTION_TIMEPROBE (TAO_POA_PARSE_KEY_START);
383 result = TAO_Root_POA::parse_key (key,
384 poa_system_name,
385 system_id,
386 is_root,
387 is_persistent,
388 is_system_id,
389 poa_creation_time);
392 if (result != 0)
393 throw ::CORBA::OBJ_ADAPTER ();
396 ACE_FUNCTION_TIMEPROBE (TAO_OBJECT_ADAPTER_FIND_POA_START);
398 result = this->find_poa (poa_system_name,
399 is_persistent,
400 is_root,
401 poa_creation_time,
402 poa);
405 if (result != 0)
406 throw ::CORBA::OBJECT_NOT_EXIST (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
410 TAO_Object_Adapter::activate_poa (const poa_name &folded_name,
411 TAO_Root_POA *&poa)
413 int result = -1;
415 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_MICRO)
417 iteratable_poa_name ipn (folded_name);
418 iteratable_poa_name::iterator iterator = ipn.begin ();
419 iteratable_poa_name::iterator end = ipn.end ();
421 TAO_Root_POA *parent = this->root_;
422 if (parent == 0 || parent->name () != *iterator)
423 throw ::CORBA::OBJ_ADAPTER ();
424 else
425 ++iterator;
427 for (;
428 iterator != end;
429 ++iterator)
431 TAO_Root_POA *current = 0;
435 current = parent->find_POA_i (*iterator, 1);
437 catch (const PortableServer::POA::AdapterNonExistent&)
439 return -1;
442 parent = current;
445 poa = parent;
446 result = 0;
447 #else
448 ACE_UNUSED_ARG (folded_name);
449 ACE_UNUSED_ARG (poa);
450 #endif /* TAO_HAS_MINIMUM_POA == 0 */
452 return result;
456 TAO_Object_Adapter::find_transient_poa (const poa_name &system_name,
457 CORBA::Boolean root,
458 const TAO::Portable_Server::Temporary_Creation_Time &poa_creation_time,
459 TAO_Root_POA *&poa)
461 int result = 0;
463 if (root)
465 poa = this->root_;
467 else
469 result = this->transient_poa_map_->find (system_name, poa);
472 if (poa == 0
473 || (result == 0 && !poa->validate_lifespan (false, poa_creation_time)))
474 result = -1;
476 return result;
480 TAO_Object_Adapter::bind_poa (const poa_name &folded_name,
481 TAO_Root_POA *poa,
482 poa_name_out system_name)
484 if (poa->persistent ())
485 return this->bind_persistent_poa (folded_name, poa, system_name);
486 else
487 return this->bind_transient_poa (poa, system_name);
491 TAO_Object_Adapter::unbind_poa (TAO_Root_POA *poa,
492 const poa_name &folded_name,
493 const poa_name &system_name)
495 if (poa->persistent ())
496 return this->unbind_persistent_poa (folded_name, system_name);
497 else
498 return this->unbind_transient_poa (system_name);
502 TAO_Object_Adapter::locate_servant_i (const TAO::ObjectKey &key)
504 ACE_FUNCTION_TIMEPROBE (TAO_POA_LOCATE_SERVANT_START);
506 PortableServer::ObjectId id;
507 TAO_Root_POA *poa = 0;
509 this->locate_poa (key, id, poa);
511 PortableServer::Servant servant = 0;
512 TAO_Servant_Location const servant_location =
513 poa->locate_servant_i (id, servant);
515 switch (servant_location)
517 case TAO_Servant_Location::Found:
518 // Optimistic attitude
519 case TAO_Servant_Location::Default_Servant:
520 case TAO_Servant_Location::Servant_Manager:
521 return 0;
523 case TAO_Servant_Location::Not_Found:
524 return -1;
527 return -1;
530 TAO_Servant_Location
531 TAO_Object_Adapter::find_servant_i (const TAO::ObjectKey &key,
532 PortableServer::Servant &servant)
534 PortableServer::ObjectId id;
535 TAO_Root_POA *poa = nullptr;
537 this->locate_poa (key, id, poa);
539 return poa->locate_servant_i (id, servant);
542 void
543 TAO_Object_Adapter::open ()
545 // Add in the default POA policies to the default list.
546 this->init_default_policies (this->default_poa_policies ());
548 // If a POA extension hasn't changed the servant dispatcher, initialize the
549 // default one.
550 if (!this->servant_dispatcher_)
552 ACE_NEW (this->servant_dispatcher_,
553 TAO_Default_Servant_Dispatcher);
556 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
557 ACE_NEW_THROW_EX (this->poa_manager_factory_,
558 TAO_POAManager_Factory (*this),
559 CORBA::NO_MEMORY ());
561 ::CORBA::PolicyList policy;
562 PortableServer::POAManager_var poa_manager
563 = poa_manager_factory_->create_POAManager (TAO_DEFAULT_ROOTPOAMANAGER_NAME, policy);
564 #else
565 PortableServer::POAManager_ptr poa_manager_ptr;
566 ::CORBA::PolicyList policy_list;
567 ACE_NEW_THROW_EX (poa_manager_ptr,
568 TAO_POA_Manager (*this, TAO_DEFAULT_ROOTPOAMANAGER_NAME),
569 CORBA::NO_MEMORY
570 (CORBA::SystemException::_tao_minor_code (0, ENOMEM),
571 CORBA::COMPLETED_NO));
573 PortableServer::POAManager_var poa_manager = poa_manager_ptr;
574 // Keep reference of POAManager in TAO_Object_Adapter so the POAManager
575 // object is destructed after RootPOA is destructed.
576 the_poa_manager_ = poa_manager;
578 #endif
580 // This makes sure that the default resources are open when the Root
581 // POA is created.
582 this->orb_core_.thread_lane_resources_manager ().open_default_resources ();
584 TAO_POA_Policy_Set policies (this->default_poa_policies ());
586 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
587 // Specify the implicit activation policy since it should
588 // be different from the default. Note that merge_policy
589 // takes a const reference and makes its own copy of the
590 // policy. (Otherwise, we'd have to allocate the policy
591 // on the heap.)
592 // Implicit activation policy.
593 TAO::Portable_Server::ImplicitActivationPolicy implicit_activation_policy
594 (PortableServer::IMPLICIT_ACTIVATION);
595 policies.merge_policy (&implicit_activation_policy);
596 #endif /* TAO_HAS_MINIMUM_POA == 0 */
598 // Merge policies from the ORB level.
599 this->validator ().merge_policies (policies.policies ());
601 // If any of the policy objects specified are not valid for the ORB
602 // implementation, if conflicting policy objects are specified, or
603 // if any of the specified policy objects require prior
604 // administrative action that has not been performed, an
605 // InvalidPolicy exception is raised containing the index in the
606 // policies parameter value of the first offending policy object.
607 policies.validate_policies (this->validator (), this->orb_core_);
609 // Construct a new POA
610 TAO_Root_POA::String root_poa_name (TAO_DEFAULT_ROOTPOA_NAME);
611 this->root_ =
612 this->servant_dispatcher_->create_Root_POA (root_poa_name,
613 poa_manager.in (),
614 policies,
615 this->lock (),
616 this->thread_lock (),
617 this->orb_core_,
618 this);
620 // The Object_Adapter will keep a reference to the Root POA so that
621 // on its destruction, it can check whether the Root POA has been
622 // destroyed yet or not.
623 this->root_->_add_ref ();
625 // Lock access for the duration of this transaction.
626 TAO::Portable_Server::POA_Guard poa_guard (*this->root_);
628 // Iterate over the registered IOR interceptors so that they may be
629 // given the opportunity to add tagged components to the profiles
630 // for this servant.
631 this->root_->establish_components ();
634 void
635 TAO_Object_Adapter::close (int wait_for_completion)
637 this->check_close (wait_for_completion);
639 // Shutting down the ORB causes all object adapters to be destroyed,
640 // since they cannot exist in the absence of an ORB. Shut down is
641 // complete when all ORB processing (including request processing
642 // and object deactivation or other operations associated with
643 // object adapters) has completed and the object adapters have been
644 // destroyed. In the case of the POA, this means that all object
645 // etherealizations have finished and root POA has been destroyed
646 // (implying that all descendent POAs have also been destroyed).
647 TAO_Root_POA *root = 0;
648 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
649 TAO_POAManager_Factory* factory = 0;
650 #endif
652 ACE_GUARD (ACE_Lock, ace_mon, this->lock ());
653 if (this->root_ == 0)
654 return;
655 root = this->root_;
656 this->root_ = 0;
658 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
659 if (this->poa_manager_factory_ == 0)
660 return;
661 factory = this->poa_manager_factory_;
662 this->poa_manager_factory_ = 0;
663 #endif
665 CORBA::Boolean etherealize_objects = true;
666 root->destroy (etherealize_objects, wait_for_completion);
667 ::CORBA::release (root);
668 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
669 release_poa_manager_factory (factory);
670 #endif
673 void
674 TAO_Object_Adapter::check_close (int wait_for_completion)
676 TAO_Root_POA::check_for_valid_wait_for_completions (this->orb_core (),
677 wait_for_completion);
681 TAO_Object_Adapter::priority () const
683 return 0;
687 TAO_Object_Adapter::dispatch (TAO::ObjectKey &key,
688 TAO_ServerRequest &request,
689 CORBA::Object_out forward_to)
691 if (key.length() < TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE
692 || ACE_OS::memcmp (key.get_buffer (),
693 &TAO_Root_POA::objectkey_prefix[0],
694 TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE) != 0)
696 return TAO_Adapter::DS_MISMATCHED_KEY;
699 int result = 0;
701 #if TAO_HAS_INTERCEPTORS == 1
702 TAO::ServerRequestInterceptor_Adapter *sri_adapter =
703 orb_core_.serverrequestinterceptor_adapter ();
707 if (sri_adapter != 0)
709 #if TAO_HAS_EXTENDED_FT_INTERCEPTORS == 1
710 CORBA::OctetSeq_var ocs;
711 sri_adapter->tao_ft_interception_point (request,
712 0, // args
713 0, // nargs
714 0, // servant_upcall
715 0, // exceptions
716 0, // nexceptions
717 ocs.out ());
719 /// If we have a cached result, just go ahead and send the reply
720 /// and let us return
721 if (ocs.ptr () != 0)
723 // request.result_seq (
724 request.send_cached_reply (ocs.inout ());
726 return TAO_Adapter::DS_OK;
729 // If a PortableInterceptor::ForwardRequest exception was
730 // thrown, then set the forward_to object reference and return
731 // with the appropriate return status.
732 forward_to.ptr () = request.forward_location ();
733 if (request.is_forwarded ())
735 return TAO_Adapter::DS_FORWARD;
737 #endif /*TAO_HAS_EXTENDED_FT_INTERCEPTORS*/
739 // The receive_request_service_contexts() interception point
740 // must be invoked before the operation is dispatched to the
741 // servant.
742 sri_adapter->receive_request_service_contexts (request,
743 0, // args
744 0, // nargs
745 0, // servant_upcall
746 0, // exceptions
747 0); // nexceptions
749 // If a PortableInterceptor::ForwardRequest exception was
750 // thrown, then set the forward_to object reference and return
751 // with the appropriate return status.
752 forward_to.ptr () = request.forward_location ();
753 if (request.is_forwarded ())
755 return TAO_Adapter::DS_FORWARD;
758 #endif /* TAO_HAS_INTERCEPTORS == 1 */
760 result = this->dispatch_servant (key, request, forward_to);
762 #if TAO_HAS_INTERCEPTORS == 1
764 if (result == TAO_Adapter::DS_FORWARD)
766 request.reply_status (GIOP::LOCATION_FORWARD);
767 request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
768 request.forward_location (forward_to.ptr ());
769 if (sri_adapter != 0)
771 sri_adapter->send_other (request,
772 0, // args
773 0, // nargs
774 0, // servant_upcall
775 0, // exceptions
776 0); // nexceptions
780 catch ( ::CORBA::Exception& ex)
782 // Just assume the current exception is a system exception, the
783 // status can only change when the interceptor changes this
784 // and this is only done when the sri_adapter is available. If we
785 // don't have an sri_adapter we just rethrow the exception
786 PortableInterceptor::ReplyStatus status =
787 PortableInterceptor::SYSTEM_EXCEPTION;
789 if (sri_adapter != 0)
791 request.caught_exception (&ex);
793 sri_adapter->send_exception (request,
794 0, // args
795 0, // nargs
796 0, // servant_upcall
797 0, // exceptions
798 0); // nexceptions
800 status = request.pi_reply_status ();
803 // Only re-throw the exception if it hasn't been transformed by
804 // the send_exception() interception point (e.g. to a
805 // LOCATION_FORWARD).
806 if (status == PortableInterceptor::SYSTEM_EXCEPTION
807 || status == PortableInterceptor::USER_EXCEPTION)
809 throw;
812 #endif /* TAO_HAS_INTERCEPTORS == 1 */
814 return result;
817 const char *
818 TAO_Object_Adapter::name () const
820 return TAO_OBJID_ROOTPOA;
823 CORBA::Object_ptr
824 TAO_Object_Adapter::root ()
826 return CORBA::Object::_duplicate (this->root_);
829 CORBA::Object_ptr
830 TAO_Object_Adapter::create_collocated_object (TAO_Stub *stub,
831 const TAO_MProfile &mp)
833 TAO_ServantBase *sb = this->get_collocated_servant (mp);
835 // Set the servant ORB. Do not duplicate the ORB here since
836 // TAO_Stub::servant_orb() duplicates it.
837 stub->servant_orb (this->orb_core_.orb ());
839 // It is ok to create a collocated object even when <sb> is
840 // zero. This constructor will set the stub collocated indicator and
841 // the strategized proxy broker if required.
842 CORBA::Object_ptr x;
843 ACE_NEW_RETURN (x,
844 CORBA::Object (stub,
846 sb),
847 CORBA::Object::_nil ());
849 // Success.
850 return x;
853 CORBA::Long
854 TAO_Object_Adapter::initialize_collocated_object (TAO_Stub *stub)
856 // If we have been forwarded: use the forwarded profiles
857 const TAO_MProfile &mp = stub->forward_profiles () ? *(stub->forward_profiles ())
858 : stub->base_profiles ();
860 TAO_ServantBase *sb = this->get_collocated_servant (mp);
862 // Set the servant ORB. Do not duplicate the ORB here since
863 // TAO_Stub::servant_orb() duplicates it.
864 stub->servant_orb (this->orb_core_.orb ());
866 // It is ok to set the object as a collocated object even when
867 // <sb> is zero.
868 stub->collocated_servant (sb);
870 // Mark the stub as collocated. This will set the strategized object
871 // proxy broker if required.
872 stub->is_collocated (true);
874 // Return 0 (success) if we found a servant.
875 return ! sb;
878 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
879 void
880 TAO_Object_Adapter::release_poa_manager_factory (
881 TAO_POAManager_Factory *factory)
883 if (factory != 0)
885 factory->remove_all_poamanagers ();
886 ::CORBA::release (factory);
889 #endif
891 TAO_ServantBase *
892 TAO_Object_Adapter::get_collocated_servant (const TAO_MProfile &mp)
894 for (TAO_PHandle j = 0;
895 j != mp.profile_count ();
896 ++j)
898 const TAO_Profile *profile = mp.get_profile (j);
899 TAO::ObjectKey_var objkey = profile->_key ();
901 if (objkey->length() < TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE
902 || ACE_OS::memcmp (objkey->get_buffer (),
903 &TAO_Root_POA::objectkey_prefix[0],
904 TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE) != 0)
905 continue;
907 TAO_ServantBase *servant = 0;
911 this->find_servant (objkey.in (), servant);
913 catch (const ::CORBA::Exception&)
917 return servant;
920 return 0;
923 // ****************************************************************
925 TAO_Object_Adapter::Hint_Strategy::~Hint_Strategy ()
929 void
930 TAO_Object_Adapter::Hint_Strategy::object_adapter (TAO_Object_Adapter *oa)
932 this->object_adapter_ = oa;
935 TAO_Object_Adapter::Active_Hint_Strategy::Active_Hint_Strategy (CORBA::ULong map_size)
936 : persistent_poa_system_map_ (map_size)
940 TAO_Object_Adapter::Active_Hint_Strategy::~Active_Hint_Strategy ()
945 TAO_Object_Adapter::Active_Hint_Strategy::find_persistent_poa (
946 const poa_name &system_name,
947 TAO_Root_POA *&poa)
949 poa_name folded_name;
950 int result = this->persistent_poa_system_map_.recover_key (system_name,
951 folded_name);
953 if (result == 0)
955 result = this->persistent_poa_system_map_.find (system_name, poa);
956 if (result != 0
957 || folded_name != poa->folded_name ())
959 result =
960 this->object_adapter_->persistent_poa_name_map_->find (folded_name,
961 poa);
962 if (result != 0)
964 result = this->object_adapter_->activate_poa (folded_name, poa);
969 return result;
973 TAO_Object_Adapter::Active_Hint_Strategy::bind_persistent_poa (
974 const poa_name &folded_name,
975 TAO_Root_POA *poa,
976 poa_name_out system_name)
978 poa_name name = folded_name;
979 int result = this->persistent_poa_system_map_.bind_modify_key (poa,
980 name);
982 if (result == 0)
984 result =
985 this->object_adapter_->persistent_poa_name_map_->bind (folded_name,
986 poa);
988 if (result != 0)
989 this->persistent_poa_system_map_.unbind (name);
990 else
991 ACE_NEW_RETURN (system_name,
992 poa_name (name),
993 -1);
996 return result;
1000 TAO_Object_Adapter::Active_Hint_Strategy::unbind_persistent_poa (
1001 const poa_name &folded_name,
1002 const poa_name &system_name)
1004 int result = this->persistent_poa_system_map_.unbind (system_name);
1006 if (result == 0)
1007 result =
1008 this->object_adapter_->persistent_poa_name_map_->unbind (folded_name);
1010 return result;
1013 TAO_Object_Adapter::No_Hint_Strategy::~No_Hint_Strategy ()
1018 TAO_Object_Adapter::No_Hint_Strategy::find_persistent_poa (
1019 const poa_name &system_name,
1020 TAO_Root_POA *&poa)
1022 int result =
1023 this->object_adapter_->persistent_poa_name_map_->find (system_name,
1024 poa);
1025 if (result != 0)
1027 result =
1028 this->object_adapter_->activate_poa (system_name, poa);
1031 return result;
1035 TAO_Object_Adapter::No_Hint_Strategy::bind_persistent_poa (
1036 const poa_name &folded_name,
1037 TAO_Root_POA *poa,
1038 poa_name_out system_name)
1040 int result =
1041 this->object_adapter_->persistent_poa_name_map_->bind (folded_name, poa);
1042 if (result == 0)
1043 ACE_NEW_RETURN (system_name,
1044 poa_name (folded_name),
1045 -1);
1046 return result;
1050 TAO_Object_Adapter::No_Hint_Strategy::unbind_persistent_poa (
1051 const poa_name & folded_name,
1052 const poa_name & /* system_name */)
1054 return this->object_adapter_->persistent_poa_name_map_->unbind (folded_name);
1057 TAO_Object_Adapter::poa_name_iterator::poa_name_iterator (
1058 int begin,
1059 CORBA::ULong size,
1060 const CORBA::Octet *folded_buffer)
1061 : size_ (size),
1062 folded_buffer_ (folded_buffer),
1063 last_separator_ ((CORBA::ULong) ~0)
1065 if (begin)
1067 this->position_ = (CORBA::ULong) ~0;
1068 this->operator++ ();
1070 else
1071 this->position_ = this->size_;
1074 bool
1075 TAO_Object_Adapter::poa_name_iterator::operator== (const poa_name_iterator &rhs) const
1077 return this->position_ == rhs.position_;
1080 bool
1081 TAO_Object_Adapter::poa_name_iterator::operator!= (const poa_name_iterator &rhs) const
1083 return !this->operator== (rhs);
1086 ACE_CString
1087 TAO_Object_Adapter::poa_name_iterator::operator* () const
1089 CORBA::ULong start_at =
1090 this->last_separator_ +
1091 TAO_Root_POA::name_separator_length ();
1093 CORBA::ULong how_many =
1094 this->position_
1095 - this->last_separator_
1096 - TAO_Root_POA::name_separator_length ();
1098 return ACE_CString (reinterpret_cast <const char *>
1099 (&this->folded_buffer_[start_at]),
1100 how_many);
1103 TAO_Object_Adapter::poa_name_iterator &
1104 TAO_Object_Adapter::poa_name_iterator::operator++ ()
1106 for (this->last_separator_ = this->position_;
1110 ++this->position_;
1111 if (this->position_ < this->size_)
1113 if (this->folded_buffer_[this->position_] == TAO_Root_POA::name_separator ())
1114 break;
1116 else
1117 break;
1120 return *this;
1123 TAO_Object_Adapter::iteratable_poa_name::iteratable_poa_name (
1124 const poa_name &folded_name)
1125 : folded_name_ (folded_name)
1129 TAO_Object_Adapter::iteratable_poa_name::iterator
1130 TAO_Object_Adapter::iteratable_poa_name::begin () const
1132 return iterator (1,
1133 this->folded_name_.length (),
1134 this->folded_name_.get_buffer ());
1137 TAO_Object_Adapter::iteratable_poa_name::iterator
1138 TAO_Object_Adapter::iteratable_poa_name::end () const
1140 return iterator (0,
1141 this->folded_name_.length (),
1142 this->folded_name_.get_buffer ());
1145 void
1146 TAO_Object_Adapter::wait_for_non_servant_upcalls_to_complete ()
1148 // Check if a non-servant upcall is in progress. If a non-servant
1149 // upcall is in progress, wait for it to complete. Unless of
1150 // course, the thread making the non-servant upcall is this thread.
1151 while (this->non_servant_upcall_in_progress_ &&
1152 ! ACE_OS::thr_equal (this->non_servant_upcall_thread_,
1153 ACE_OS::thr_self ()))
1155 // If so wait...
1156 int const result = this->non_servant_upcall_condition_.wait ();
1157 if (result == -1)
1158 throw ::CORBA::OBJ_ADAPTER ();
1162 void
1163 TAO_Object_Adapter::wait_for_non_servant_upcalls_to_complete_no_throw ()
1165 // Non-exception throwing version.
1168 this->wait_for_non_servant_upcalls_to_complete ();
1170 catch (const ::CORBA::Exception&)
1172 TAOLIB_ERROR ((LM_ERROR,
1173 "TAO_Object_Adapter::wait_for_non_servant_upcalls_to_complete "
1174 "threw exception it should not have!\n"));
1178 void
1179 TAO_Object_Adapter::servant_dispatcher (TAO_Servant_Dispatcher *dispatcher)
1181 if (this->servant_dispatcher_)
1182 delete this->servant_dispatcher_;
1184 this->servant_dispatcher_ = dispatcher;
1187 void
1188 TAO_Object_Adapter::do_dispatch (TAO_ServerRequest& req,
1189 TAO::Portable_Server::Servant_Upcall& upcall)
1191 upcall.servant ()->_dispatch(req, &upcall);
1194 TAO_END_VERSIONED_NAMESPACE_DECL