Major cleanup in PortableServer library
[ACE_TAO.git] / TAO / tao / PortableServer / Root_POA.cpp
blob049f891a4bfb7a0a053f02c86891bf0121e220f5
1 #include "tao/PortableServer/Root_POA.h"
2 #include "tao/PortableServer/Regular_POA.h"
4 #include "tao/PortableServer/ThreadPolicy.h"
5 #include "tao/PortableServer/LifespanPolicy.h"
6 #include "tao/PortableServer/IdAssignmentPolicy.h"
7 #include "tao/PortableServer/IdUniquenessPolicy.h"
8 #include "tao/PortableServer/ImplicitActivationPolicy.h"
9 #include "tao/PortableServer/RequestProcessingPolicy.h"
10 #include "tao/PortableServer/ServantRetentionPolicy.h"
11 #include "tao/PortableServer/Active_Object_Map.h"
12 #include "tao/PortableServer/Default_Acceptor_Filter.h"
13 #include "tao/PortableServer/ORT_Adapter.h"
14 #include "tao/PortableServer/ORT_Adapter_Factory.h"
15 #include "tao/PortableServer/POA_Current_Impl.h"
16 #include "tao/PortableServer/Servant_Upcall.h"
17 #include "tao/PortableServer/AdapterActivatorC.h"
18 #include "tao/PortableServer/Non_Servant_Upcall.h"
19 #include "tao/PortableServer/POAManager.h"
20 #include "tao/PortableServer/POAManagerFactory.h"
21 #include "tao/PortableServer/ServantManagerC.h"
22 #include "tao/PortableServer/poa_macros.h"
23 #include "tao/PortableServer/POA_Guard.h"
24 #include "tao/PortableServer/Creation_Time.h"
25 #include "tao/PortableServer/RequestProcessingStrategy.h"
26 #include "tao/PortableServer/LifespanStrategy.h"
27 #include "tao/PortableServer/IdUniquenessStrategy.h"
28 #include "tao/PortableServer/IdAssignmentStrategy.h"
29 #include "tao/PortableServer/ServantRetentionStrategy.h"
30 #include "tao/PortableServer/ImplicitActivationStrategy.h"
31 #include "tao/PortableServer/ThreadStrategy.h"
32 #include "tao/PortableServer/Acceptor_Filter_Factory.h"
33 #include "tao/PortableServer/Network_Priority_Hook.h"
35 #include "tao/StringSeqC.h"
36 #include "tao/PortableInterceptorC.h"
37 #include "tao/PolicyC.h"
38 #include "tao/ORB_Core.h"
39 #include "tao/ORB.h"
40 #include "tao/Server_Strategy_Factory.h"
41 #include "tao/Acceptor_Registry.h"
42 #include "tao/Thread_Lane_Resources.h"
43 #include "tao/Exception.h"
44 #include "tao/Stub.h"
45 #include "tao/Profile.h"
46 #include "tao/TSS_Resources.h"
47 #include "tao/IORInterceptor_Adapter.h"
48 #include "tao/debug.h"
50 // auto_ptr class
51 #include "ace/Auto_Ptr.h"
52 #include "ace/Dynamic_Service.h"
53 #include "ace/OS_NS_netdb.h"
54 #include "ace/OS_NS_string.h"
55 #include "ace/OS_NS_unistd.h"
56 #include "ace/Log_Msg.h"
58 #if !defined (__ACE_INLINE__)
59 # include "tao/PortableServer/Root_POA.inl"
60 #endif /* ! __ACE_INLINE__ */
62 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
64 // This is the TAO_Object_key-prefix that is appended to all TAO Object keys.
65 // It's an array of octets representing ^t^a^o/0 in octal.
66 CORBA::Octet const
67 TAO_Root_POA::objectkey_prefix [TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE] = {
68 024, // octal for ^t
69 001, // octal for ^a
70 017, // octal for ^o
71 000
74 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
76 PortableServer::ThreadPolicy_ptr
77 TAO_Root_POA::create_thread_policy (PortableServer::ThreadPolicyValue value)
79 TAO::Portable_Server::ThreadPolicy *policy = 0;
80 ACE_NEW_THROW_EX (policy,
81 TAO::Portable_Server::ThreadPolicy (value),
82 CORBA::NO_MEMORY ());
84 return policy;
87 #endif /* TAO_HAS_MINIMUM_POA == 0 && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) */
89 #if !defined (CORBA_E_MICRO)
91 PortableServer::LifespanPolicy_ptr
92 TAO_Root_POA::create_lifespan_policy (PortableServer::LifespanPolicyValue value)
94 TAO::Portable_Server::LifespanPolicy *policy = 0;
95 ACE_NEW_THROW_EX (policy,
96 TAO::Portable_Server::LifespanPolicy (value),
97 CORBA::NO_MEMORY ());
99 return policy;
102 #endif
104 #if !defined (CORBA_E_MICRO)
105 PortableServer::IdUniquenessPolicy_ptr
106 TAO_Root_POA::create_id_uniqueness_policy (PortableServer::IdUniquenessPolicyValue value)
108 TAO::Portable_Server::IdUniquenessPolicy *policy = 0;
109 ACE_NEW_THROW_EX (policy,
110 TAO::Portable_Server::IdUniquenessPolicy (value),
111 CORBA::NO_MEMORY ());
113 return policy;
115 #endif
117 #if !defined (CORBA_E_MICRO)
118 PortableServer::IdAssignmentPolicy_ptr
119 TAO_Root_POA::create_id_assignment_policy (PortableServer::IdAssignmentPolicyValue value)
121 TAO::Portable_Server::IdAssignmentPolicy *policy = 0;
122 ACE_NEW_THROW_EX (policy,
123 TAO::Portable_Server::IdAssignmentPolicy (value),
124 CORBA::NO_MEMORY ());
126 return policy;
128 #endif
130 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
132 PortableServer::ImplicitActivationPolicy_ptr
133 TAO_Root_POA::create_implicit_activation_policy (PortableServer::ImplicitActivationPolicyValue value)
135 TAO::Portable_Server::ImplicitActivationPolicy *policy = 0;
136 ACE_NEW_THROW_EX (policy,
137 TAO::Portable_Server::ImplicitActivationPolicy (value),
138 CORBA::NO_MEMORY ());
140 return policy;
143 PortableServer::ServantRetentionPolicy_ptr
144 TAO_Root_POA::create_servant_retention_policy (PortableServer::ServantRetentionPolicyValue value)
146 TAO::Portable_Server::ServantRetentionPolicy *policy = 0;
147 ACE_NEW_THROW_EX (policy,
148 TAO::Portable_Server::ServantRetentionPolicy (value),
149 CORBA::NO_MEMORY ());
151 return policy;
154 PortableServer::RequestProcessingPolicy_ptr
155 TAO_Root_POA::create_request_processing_policy (PortableServer::RequestProcessingPolicyValue value)
157 TAO::Portable_Server::RequestProcessingPolicy *policy = 0;
158 ACE_NEW_THROW_EX (policy,
159 TAO::Portable_Server::RequestProcessingPolicy (value),
160 CORBA::NO_MEMORY ());
162 return policy;
165 #endif /* TAO_HAS_MINIMUM_POA == 0 */
167 void
168 TAO_Root_POA::set_obj_ref_factory (
169 PortableInterceptor::ObjectReferenceFactory *current_factory)
171 TAO::ORT_Adapter *adapter = this->ORT_adapter ();
173 if (adapter)
175 // Activate a different factory
176 this->ort_adapter_->set_obj_ref_factory (current_factory);
180 TAO_Root_POA::TAO_Root_POA (const TAO_Root_POA::String &name,
181 PortableServer::POAManager_ptr poa_manager,
182 const TAO_POA_Policy_Set &policies,
183 TAO_Root_POA *parent,
184 ACE_Lock &lock,
185 TAO_SYNCH_MUTEX &thread_lock,
186 TAO_ORB_Core &orb_core,
187 TAO_Object_Adapter *object_adapter)
188 : name_ (name),
189 poa_manager_ (* (dynamic_cast <TAO_POA_Manager*> (poa_manager))),
191 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
192 poa_manager_factory_ (* (object_adapter->poa_manager_factory_)),
193 #endif
195 tagged_component_ (),
196 tagged_component_id_ (),
197 profile_id_array_ (0),
198 policies_ (policies),
199 ort_adapter_ (0),
200 ort_adapter_factory_ (0),
201 adapter_state_ (PortableInterceptor::HOLDING),
202 network_priority_hook_ (0),
203 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
204 adapter_activator_ (),
205 #endif /* TAO_HAS_MINIMUM_POA == 0 */
206 children_ (),
207 lock_ (lock),
208 orb_core_ (orb_core),
209 object_adapter_ (object_adapter),
210 cleanup_in_progress_ (false),
211 outstanding_requests_ (0),
212 outstanding_requests_condition_ (thread_lock),
213 wait_for_completion_pending_ (0),
214 waiting_destruction_ (false),
215 servant_deactivation_condition_ (thread_lock),
216 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
217 filter_factory_ (0),
218 #endif
219 caller_key_to_object_ (0),
220 servant_for_key_to_object_ (0)
222 // Since we are keeping a reference to a POAManager, we need to
223 // increment the reference count but we do this safely.
224 PortableServer::POAManager_var pm_guard (
225 PortableServer::POAManager::_duplicate(&this->poa_manager_));
227 // Parse the policies that are used in the critical path in
228 // a cache.
229 this->cached_policies_.update (this->policies_);
231 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
232 this->filter_factory_
233 = ACE_Dynamic_Service<TAO_Acceptor_Filter_Factory>::instance (
234 "TAO_Acceptor_Filter_Factory");
235 #endif
237 this->network_priority_hook_
238 = ACE_Dynamic_Service<TAO_Network_Priority_Hook>::instance (
239 "TAO_Network_Priority_Hook");
241 if (this->network_priority_hook_ != 0)
243 this->network_priority_hook_->update_network_priority (
244 *this, this->policies_);
247 // Cache ort adapter factory
248 this->ort_adapter_factory_
249 = ACE_Dynamic_Service<TAO::ORT_Adapter_Factory>::instance
250 (orb_core_.configuration (), TAO_Root_POA::ort_adapter_factory_name ());
252 #if (TAO_HAS_MINIMUM_POA == 1)
253 // If this is the RootPOA, set the value of the ImplicitActivationPolicy
254 // to IMPLICIT_ACTIVATION since it is impossible to pass the policy
255 // as it is not compiled into the library.
257 // If the ImplicitActivationPolicy policy is ever compiled in the
258 // minimum POA builds, remove this code and remove the guards
259 // in Object_Adapter.cpp when changing the default policy for the
260 // RootPOA.
261 if (ACE_OS::strcmp (this->name_.c_str (), TAO_DEFAULT_ROOTPOA_NAME) == 0)
263 this->cached_policies_.implicit_activation (PortableServer::IMPLICIT_ACTIVATION);
265 #endif /* TAO_HAS_MINIMUM_POA == 1 */
267 // Set the active strategies to be used by this POA
268 this->active_policy_strategies_.update (this->cached_policies_,
269 this);
270 TAO::Portable_Server::Active_Policy_Strategies_Cleanup_Guard aps_cleanup_guard (
271 std::addressof(this->active_policy_strategies_));
273 // Set the folded name of this POA.
274 this->set_folded_name (parent);
276 // Register self with manager.
277 int result = this->poa_manager_.register_poa (this);
278 if (result != 0)
280 throw ::CORBA::OBJ_ADAPTER ();
283 // Add self to Object Adapter class.
284 result =
285 this->object_adapter ().bind_poa (this->folded_name_,
286 this,
287 this->system_name_.out ());
288 if (result != 0)
290 // Remove from POA Manager in case of errors. No checks of
291 // further errors...
292 this->poa_manager_.remove_poa (this);
294 throw ::CORBA::OBJ_ADAPTER ();
297 // Set the id for this POA.
298 this->set_id (parent);
300 // Notify the Lifespan strategy of our startup
303 this->active_policy_strategies_.lifespan_strategy()->notify_startup ();
305 catch (const ::CORBA::Exception&)
307 this->poa_manager_.remove_poa (this);
308 this->object_adapter ().unbind_poa (this,
309 this->folded_name_,
310 this->system_name_.in ());
311 throw;
314 // Now when everything is fine we can release the quards.
315 pm_guard._retn ();
316 aps_cleanup_guard._retn ();
319 TAO_Root_POA::~TAO_Root_POA ()
321 this->poa_manager_._remove_ref();
324 void
325 TAO_Root_POA::complete_destruction_i ()
327 bool doing_complete_destruction =
328 this->waiting_destruction_ != false;
330 // No longer awaiting destruction.
331 this->waiting_destruction_ = false;
333 PortableServer::POA_var poa;
334 TAO::ORT_Array my_array_obj_ref_template;
335 TAO::ORT_Adapter *ort_adapter = 0;
336 if (doing_complete_destruction)
338 ort_adapter =
339 this->ORT_adapter_i ();
341 // In case no ORT library is linked we get zero.
342 if (ort_adapter != 0)
344 // Get the ObjectReferenceTemplate.
345 PortableInterceptor::ObjectReferenceTemplate * const ort =
346 ort_adapter->get_adapter_template ();
348 // Add it to the sequence of object reference templates, we
349 // just notify for ourselves that we are now non_existent,
350 // our childs will do it for themselves.
351 my_array_obj_ref_template.size (1);
352 my_array_obj_ref_template[0] = ort;
355 poa = PortableServer::POA::_duplicate (this);
358 // Remove POA from the POAManager.
359 if (this->poa_manager_.remove_poa (this) != 0)
360 throw ::CORBA::OBJ_ADAPTER ();
362 // Remove POA from the Object Adapter.
363 int result = this->object_adapter ().unbind_poa (this,
364 this->folded_name_,
365 this->system_name_.in ());
366 if (result != 0)
367 throw ::CORBA::OBJ_ADAPTER ();
369 // Cleanup all strategies
370 this->active_policy_strategies_.cleanup ();
372 // Forced cleanup. The new memory management scheme is evil and can
373 // lead to reference deadlock, i.e., POA holds object A, but POA
374 // cannot die because object A hold POA.
377 // If new things are added to this cleanup code, make sure to move
378 // the minimum CORBA #define after the declaration of
379 // <non_servant_upcall>.
382 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
384 // ATTENTION: Trick locking here, see class header for details
385 TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*this);
386 ACE_UNUSED_ARG (non_servant_upcall);
388 this->adapter_activator_ = PortableServer::AdapterActivator::_nil ();
390 #endif /* TAO_HAS_MINIMUM_POA == 0 */
394 ::CORBA::release (this);
396 if (doing_complete_destruction)
398 this->adapter_state_ = PortableInterceptor::NON_EXISTENT;
400 this->adapter_state_changed (my_array_obj_ref_template,
401 this->adapter_state_);
403 if (ort_adapter != 0)
405 ort_adapter->release (my_array_obj_ref_template[0]);
407 if (this->ort_adapter_factory_)
409 this->ort_adapter_factory_->destroy (ort_adapter);
412 this->ort_adapter_ = 0;
417 #if ! defined (CORBA_E_MICRO)
418 PortableServer::POA_ptr
419 TAO_Root_POA::create_POA_i (const char *adapter_name,
420 PortableServer::POAManager_ptr poa_manager,
421 const CORBA::PolicyList &policies)
423 // Initialize a TAO_POA_Policy_Set instance so that it contains the
424 // default POA policies.
425 TAO_POA_Policy_Set tao_policies (this->object_adapter ().default_poa_policies ());
427 // Merge policies from the ORB level.
428 this->object_adapter ().validator ().merge_policies (tao_policies.policies ());
430 // Merge in any policies that the user may have specified.
431 tao_policies.merge_policies (policies);
433 // If any of the policy objects specified are not valid for the ORB
434 // implementation, if conflicting policy objects are specified, or
435 // if any of the specified policy objects require prior
436 // administrative action that has not been performed, an
437 // InvalidPolicy exception is raised containing the index in the
438 // policies parameter value of the first offending policy object.
439 tao_policies.validate_policies (this->object_adapter ().validator (),
440 this->orb_core_);
442 // If the poa_manager parameter is null, a new POAManager object is
443 // created and associated with the new POA. Otherwise, the specified
444 // POAManager object is associated with the new POA. The POAManager
445 // object can be obtained using the attribute name the_POAManager.
447 PortableServer::POAManager_var the_poa_manager;
449 if (CORBA::is_nil (poa_manager))
451 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT)
453 PortableServer::POA_var poa = PortableServer::POA::_duplicate (this);
454 PortableServer::POA_var root_poa;
456 // Find the RootPOA by traversing the POA hierarchy until the
457 // RootPOA is reached. The RootPOA has no parent.
458 while (!CORBA::is_nil (poa.in ()))
460 root_poa = poa;
461 poa = poa->the_parent ();
464 // Get the POAManagerFactory instance owned by RootPOA.
465 PortableServer::POAManagerFactory_var tao_poa_manager_factory
466 = root_poa->the_POAManagerFactory ();
468 CORBA::PolicyList empty_policies;
470 // The POAManager name will be generated when the POAManager instance
471 // is created.
472 the_poa_manager
473 = tao_poa_manager_factory->create_POAManager (0, empty_policies);
474 #else
476 PortableServer::POAManager_ptr the_poa_manager_ptr;
477 ACE_NEW_THROW_EX (the_poa_manager_ptr,
478 TAO_POA_Manager (this->object_adapter (), 0),
479 CORBA::NO_MEMORY ());
480 the_poa_manager = the_poa_manager_ptr;
481 #endif /* TAO_HAS_MINIMUM_POA == 0 && ! CORBA_E_COMPACT) */
484 else
486 the_poa_manager = PortableServer::POAManager::_duplicate (poa_manager);
489 PortableServer::POA_var poa = this->create_POA_i (adapter_name,
490 the_poa_manager.in (),
491 tao_policies);
493 return poa._retn ();
495 #endif /* !CORBA_E_MICRO */
497 #if ! defined (CORBA_E_MICRO)
498 TAO_Root_POA *
499 TAO_Root_POA::new_POA (const String &name,
500 PortableServer::POAManager_ptr poa_manager,
501 const TAO_POA_Policy_Set &policies,
502 TAO_Root_POA *parent,
503 ACE_Lock &lock,
504 TAO_SYNCH_MUTEX &thread_lock,
505 TAO_ORB_Core &orb_core,
506 TAO_Object_Adapter *object_adapter)
508 TAO_Regular_POA *poa = 0;
510 ACE_NEW_THROW_EX (poa,
511 TAO_Regular_POA (name,
512 poa_manager,
513 policies,
514 parent,
515 lock,
516 thread_lock,
517 orb_core,
518 object_adapter),
519 CORBA::NO_MEMORY ());
521 return poa;
524 PortableServer::POA_ptr
525 TAO_Root_POA::create_POA_i (const TAO_Root_POA::String &adapter_name,
526 PortableServer::POAManager_ptr poa_manager,
527 const TAO_POA_Policy_Set &policies)
529 // This operation creates a new POA as a child of the target POA. The
530 // specified name identifies the new POA with respect to other POAs
531 // with the same parent POA. If the target POA already has a child
532 // POA with the specified name, the AdapterAlreadyExists exception
533 // is raised.
534 // Child was found
535 if (this->children_.find (adapter_name) != -1)
537 throw PortableServer::POA::AdapterAlreadyExists ();
541 // Child was not found. Create one.
544 // The specified policy objects are associated with the POA and used
545 // to control its behavior. The policy objects are effectively
546 // copied before this operation returns, so the application is free
547 // to destroy them while the POA is in use. Policies are not
548 // inherited from the parent POA.
549 TAO_Root_POA * poa = this->new_POA (adapter_name,
550 poa_manager,
551 policies,
552 this,
553 this->object_adapter ().lock (),
554 this->object_adapter ().thread_lock (),
555 this->orb_core_,
556 this->object_adapter_);
558 // Give ownership of the new map to the POA_var. Note, that it
559 // is important for the POA_var to take ownership before
560 // checking for exception since we may need to delete the new map.
561 PortableServer::POA_var new_poa = poa;
563 // Check for exception in construction of the POA.
565 // Add to children map
566 if (this->children_.bind (adapter_name, poa) != 0)
568 throw ::CORBA::OBJ_ADAPTER ();
571 // Increment the reference count on the child POA since the children
572 // map must retain ownership. Do so immediately before any other
573 // operations to prevent memory cleanup problems induced from
574 // errors below.
575 poa->_add_ref ();
577 // Iterate over the registered IOR interceptors so that they may be
578 // given the opportunity to add tagged components to the profiles
579 // for this servant.
580 poa->establish_components ();
582 // Note: Creating a POA using a POA manager that is in the active
583 // state can lead to race conditions if the POA supports preexisting
584 // objects, because the new POA may receive a request before its
585 // adapter activator, servant manager, or default servant have been
586 // initialized. These problems do not occur if the POA is created by
587 // an adapter activator registered with a parent of the new POA,
588 // because requests are queued until the adapter activator
589 // returns. To avoid these problems when a POA must be explicitly
590 // initialized, the application can initialize the POA by invoking
591 // find_POA with a TRUE activate parameter.
593 // Everything is fine. Don't let the POA_var release the
594 // implementation.
595 return new_poa._retn ();
597 #endif
599 #if ! defined (CORBA_E_MICRO)
600 PortableServer::POA_ptr
601 TAO_Root_POA::find_POA (const char *adapter_name,
602 CORBA::Boolean activate_it)
604 // Lock access for the duration of this transaction.
605 TAO_POA_GUARD_RETURN (0);
607 TAO_Root_POA *poa = this->find_POA_i (adapter_name, activate_it);
609 return PortableServer::POA::_duplicate (poa);
611 #endif
613 #if ! defined (CORBA_E_MICRO)
614 TAO_Root_POA *
615 TAO_Root_POA::find_POA_i (const ACE_CString &child_name,
616 CORBA::Boolean activate_it)
618 TAO_Root_POA *child = 0;
619 int result = this->children_.find (child_name, child);
621 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT)
623 if (result != 0)
625 if (activate_it)
627 if (!CORBA::is_nil (this->adapter_activator_.in ()))
629 // Check our state
630 this->check_state ();
632 CORBA::Boolean success = false;
635 // ATTENTION: Trick locking here, see class header for details
636 TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (
637 *this);
638 ACE_UNUSED_ARG (non_servant_upcall);
640 // When unknown_adapter gives a system exception, the POA
641 // should just pass the system exception through
642 // See 15.3.9.2 of the 3.1 CORBA spec
643 success =
644 this->adapter_activator_->unknown_adapter (
645 this,
646 child_name.c_str ());
649 if (success)
651 result = this->children_.find (child_name,
652 child);
654 else
656 result = -1;
659 else
661 result = -1;
664 else
666 result = -1;
669 #else
670 ACE_UNUSED_ARG (activate_it);
671 #endif /* TAO_HAS_MINIMUM_POA == 0 */
673 if (result == 0)
675 return child;
677 else
679 // Otherwise, the AdapterNonExistent exception is raised.
680 throw PortableServer::POA::AdapterNonExistent ();
683 #endif
685 TAO_POA_Manager &
686 TAO_Root_POA::tao_poa_manager ()
688 return poa_manager_;
691 #if ! defined (CORBA_E_MICRO)
692 PortableServer::POA_ptr
693 TAO_Root_POA::create_POA (const char *adapter_name,
694 PortableServer::POAManager_ptr poa_manager,
695 const CORBA::PolicyList &policies)
697 // Lock access for the duration of this transaction.
698 TAO_POA_GUARD_RETURN (0);
700 return this->create_POA_i (adapter_name, poa_manager, policies);
702 #endif
704 PortableServer::ObjectId *
705 TAO_Root_POA::servant_to_id (PortableServer::Servant servant)
707 // If we had upgradeable locks, this would initially be a read lock
709 // Lock access for the duration of this transaction.
710 TAO_POA_GUARD_RETURN (0);
712 return this->servant_to_id_i (servant);
715 PortableServer::ObjectId *
716 TAO_Root_POA::servant_to_user_id (PortableServer::Servant servant)
718 return this->active_policy_strategies_.servant_retention_strategy()->
719 servant_to_user_id (servant);
722 PortableServer::Servant
723 TAO_Root_POA::reference_to_servant (CORBA::Object_ptr reference)
725 // Lock access for the duration of this transaction.
726 TAO_POA_GUARD_RETURN (0);
728 return this->reference_to_servant_i (reference);
731 CORBA::Object_ptr
732 TAO_Root_POA::servant_to_reference (PortableServer::Servant servant)
734 TAO_POA_GUARD_RETURN (CORBA::Object::_nil ());
736 return this->servant_to_reference_i (servant);
739 PortableServer::POAList *
740 TAO_Root_POA::the_children ()
742 // Lock access for the duration of this transaction.
743 TAO_POA_GUARD_RETURN (0);
745 return this->the_children_i ();
749 PortableServer::Servant
750 TAO_Root_POA::id_to_servant (const PortableServer::ObjectId &oid)
752 // Lock access for the duration of this transaction.
753 TAO_POA_GUARD_RETURN (0);
755 return this->id_to_servant_i (oid);
758 CORBA::Object_ptr
759 TAO_Root_POA::id_to_reference (const PortableServer::ObjectId &oid)
761 // Lock access for the duration of this transaction.
762 TAO_POA_GUARD_RETURN (0);
764 return this->id_to_reference_i (oid, true);
768 #if ! defined (CORBA_E_MICRO)
769 CORBA::Object_ptr
770 TAO_Root_POA::create_reference_with_id (const PortableServer::ObjectId &id,
771 const char *intf)
773 // Lock access for the duration of this transaction.
774 TAO_POA_GUARD_RETURN (CORBA::Object::_nil ());
776 return this->create_reference_with_id_i (id,
777 intf,
778 this->server_priority ());
780 #endif
782 void
783 TAO_Root_POA::destroy (CORBA::Boolean etherealize_objects,
784 CORBA::Boolean wait_for_completion)
786 // Lock access for the duration of this transaction.
787 TAO::Portable_Server::POA_Guard poa_guard (*this , 0);
788 ACE_UNUSED_ARG (poa_guard);
790 this->destroy_i (etherealize_objects, wait_for_completion);
793 void
794 TAO_Root_POA::remove_from_parent_i ()
796 // The root poa has no parent, so this is a noop
799 void
800 TAO_Root_POA::destroy_i (CORBA::Boolean etherealize_objects,
801 CORBA::Boolean wait_for_completion)
803 if (this->cleanup_in_progress_)
804 return;
806 // Is the <wait_for_completion> semantics for this thread correct?
807 TAO_Root_POA::check_for_valid_wait_for_completions (this->orb_core (),
808 wait_for_completion);
810 this->cleanup_in_progress_ = true;
812 // Inform the custom servant dispatching strategy to stop the working
813 // threads when the poa is destroyed.
814 this->poa_deactivated_hook ();
816 // This operation destroys the POA and all descendant POAs. The POA
817 // so destroyed (that is, the POA with its name) may be re-created
818 // later in the same process. (This differs from the
819 // POAManager::deactivate operation that does not allow a
820 // re-creation of its associated POA in the same process.)
822 // Remove POA from the parent
823 this->remove_from_parent_i ();
825 TAO::ORT_Array array_obj_ref_template (1);
827 CORBA::ULong i = 0;
829 // Gather all ObjectReferenceTemplates and change all adapter states
830 // to INACTIVE.
831 for (CHILDREN::iterator iterator = this->children_.begin ();
832 iterator != this->children_.end ();
833 ++iterator)
835 TAO_Root_POA * const child_poa = (*iterator).int_id_;
837 TAO::ORT_Adapter * const adapter = child_poa->ORT_adapter_i ();
839 // In case no ORT library is linked we get zero.
840 if (adapter != 0)
842 // Get the ObjectReferenceTemplate for the child POA.
843 PortableInterceptor::ObjectReferenceTemplate * const ort =
844 adapter->get_adapter_template ();
846 // Add it to the sequence of object reference templates that
847 // will be destroyed.
848 array_obj_ref_template.size (1);
850 array_obj_ref_template[0] = ort;
853 child_poa->adapter_state_ =
854 PortableInterceptor::INACTIVE;
856 // Notify the state changes to the IORInterceptors
857 this->adapter_state_changed (array_obj_ref_template,
858 PortableInterceptor::INACTIVE);
860 if (adapter != 0)
861 adapter->release (array_obj_ref_template[0]);
863 ++i;
866 // Destroy all child POA's now.
867 for (CHILDREN::iterator destroy_iterator = this->children_.begin ();
868 destroy_iterator != this->children_.end ();
869 ++destroy_iterator)
871 TAO_Root_POA *destroy_child_poa = (*destroy_iterator).int_id_;
873 destroy_child_poa->destroy_i (etherealize_objects,
874 wait_for_completion);
877 // Notify the lifespan strategy of our shutdown
878 this->active_policy_strategies_.lifespan_strategy()->notify_shutdown ();
880 // @todo, is the exception handling above correct, should we just fail when
881 // the notify above fails
883 // When a POA is destroyed, any requests that have started execution
884 // continue to completion. Any requests that have not started
885 // execution are processed as if they were newly arrived, that is,
886 // the POA will attempt to cause recreation of the POA by invoking
887 // one or more adapter activators as described in Section 3.3.3.
888 // If the wait_for_completion parameter is TRUE, the destroy
889 // operation will return only after all requests in process have
890 // completed and all invocations of etherealize have
891 // completed. Otherwise, the destroy operation returns after
892 // destroying the POAs.
894 this->deactivate_all_objects_i (etherealize_objects,
895 wait_for_completion);
897 // If there are no outstanding requests and that we are not in a
898 // non-servant upcall or if we are in a non-servant upcall, make
899 // sure we are the POA related to the non-servant upcall.
900 TAO::Portable_Server::Non_Servant_Upcall *non_servant_upcall_in_progress =
901 this->object_adapter ().non_servant_upcall_in_progress ();
902 if (this->outstanding_requests_ == 0 &&
903 (non_servant_upcall_in_progress == 0 ||
904 &non_servant_upcall_in_progress->poa () != this))
906 TAO::ORT_Array my_array_obj_ref_template;
908 TAO::ORT_Adapter * const ort_adapter =
909 this->ORT_adapter_i ();
911 // In case no ORT library is linked we get zero.
912 if (ort_adapter != 0)
914 // Get the ObjectReferenceTemplate.
915 PortableInterceptor::ObjectReferenceTemplate * const ort =
916 ort_adapter->get_adapter_template ();
918 // Add it to the sequence of object reference templates, we
919 // just notify for ourselves that we are now non_existent,
920 // our childs will do it for themselves.
921 my_array_obj_ref_template.size (1);
922 my_array_obj_ref_template[0] = ort;
925 // According to the ORT spec, after a POA is destroyed, its state
926 // has to be changed to NON_EXISTENT and all the registered
927 // interceptors are to be informed. Since, the POA is destroyed
928 // and is released in the complete_destruction_i method, we are
929 // trying to keep the poa still around by doing a duplicate of
930 // it. (a hack).
931 PortableServer::POA_var poa = PortableServer::POA::_duplicate (this);
933 this->complete_destruction_i ();
935 this->adapter_state_ = PortableInterceptor::NON_EXISTENT;
937 this->adapter_state_changed (my_array_obj_ref_template,
938 this->adapter_state_);
940 if (ort_adapter != 0)
942 ort_adapter->release (my_array_obj_ref_template[0]);
944 if (this->ort_adapter_factory_)
946 this->ort_adapter_factory_->destroy (ort_adapter);
949 this->ort_adapter_ = 0;
952 else
954 // Mark that we are ready for destruction.
955 this->waiting_destruction_ = true;
960 TAO_Root_POA::delete_child (const TAO_Root_POA::String &child)
962 int result = 0;
964 // If we are not closing down, we must remove this child from our
965 // collection.
966 if (!this->cleanup_in_progress_)
967 result = this->children_.unbind (child);
969 // Otherwise, if we are closing down, we are currently iterating
970 // over our children and there is not need to remove this child from
971 // our collection.
973 return result;
976 PortableServer::POAList *
977 TAO_Root_POA::the_children_i ()
979 PortableServer::POAList_var children;
980 CORBA::ULong child_current = static_cast <CORBA::ULong>
981 (this->children_.current_size ());
982 ACE_NEW_THROW_EX (children,
983 PortableServer::POAList (child_current),
984 CORBA::NO_MEMORY ());
986 children->length (child_current);
988 CORBA::ULong index = 0;
989 for (CHILDREN::iterator iterator = this->children_.begin ();
990 iterator != this->children_.end ();
991 ++iterator, ++index)
993 TAO_Root_POA *child_poa = (*iterator).int_id_;
994 children[index] = PortableServer::POA::_duplicate (child_poa);
997 return children._retn ();
1000 PortableInterceptor::AdapterName *
1001 TAO_Root_POA::adapter_name_i ()
1003 // The adapter name is the sequence of names starting from the
1004 // RootPOA to the one whose name is requested. The name of the
1005 // RootPOA is "RootPOA".
1007 PortableServer::POA_var poa = PortableServer::POA::_duplicate (this);
1009 CORBA::ULong len = 0;
1011 // Find the length of the adapter name sequence by traversing the
1012 // POA hierarchy until the RootPOA is reached. The RootPOA has no
1013 // parent.
1014 while (!CORBA::is_nil (poa.in ()))
1016 poa = poa->the_parent ();
1017 ++len;
1020 // Empty adapter name sequence.
1021 PortableInterceptor::AdapterName *names = 0;
1022 ACE_NEW_THROW_EX (names,
1023 PortableInterceptor::AdapterName (len),
1024 CORBA::NO_MEMORY (
1025 CORBA::SystemException::_tao_minor_code (
1026 TAO::VMCID,
1027 ENOMEM),
1028 CORBA::COMPLETED_NO));
1030 PortableInterceptor::AdapterName_var safe_names (names);
1032 names->length (len);
1034 poa = PortableServer::POA::_duplicate (this);
1036 (*names)[0] = CORBA::string_dup ("RootPOA");
1038 // Fill in the AdapterName sequence as the POA hierarchy is
1039 // traversed.
1040 CORBA::ULong ilen = len;
1041 for (CORBA::ULong i = 1; i < len; ++i)
1043 (*names)[--ilen] = poa->the_name ();
1045 poa = poa->the_parent ();
1047 // If this condition asserts, the POA hierarchy was modified
1048 // (i.e. reduced in size) by another thread!
1049 ACE_ASSERT ((ilen > 0 ? !CORBA::is_nil (poa.in ()) : 1));
1052 return safe_names._retn ();
1055 void
1056 TAO_Root_POA::add_ior_component (TAO_MProfile & mprofile,
1057 const IOP::TaggedComponent &component)
1059 // Add the given tagged component to all profiles.
1060 const CORBA::ULong profile_count = mprofile.profile_count ();
1062 for (CORBA::ULong i = 0; i < profile_count; ++i)
1064 TAO_Profile *profile = mprofile.get_profile (i);
1066 profile->add_tagged_component (component);
1070 void
1071 TAO_Root_POA::add_ior_component_to_profile (
1072 TAO_MProfile & mprofile,
1073 const IOP::TaggedComponent &component,
1074 IOP::ProfileId profile_id)
1076 // Add the given tagged component to all profiles matching the given
1077 // ProfileId.
1078 bool found_profile = false;
1080 CORBA::ULong const profile_count = mprofile.profile_count ();
1082 for (CORBA::ULong i = 0; i < profile_count; ++i)
1084 TAO_Profile *profile = mprofile.get_profile (i);
1086 if (profile->tag () == profile_id)
1088 profile->add_tagged_component (component);
1090 found_profile = true;
1094 // According to the Portable Interceptor specification, we're
1095 // supposed to throw a CORBA::BAD_PARAM exception if no profile
1096 // matched the given ProfileId.
1097 if (found_profile == false)
1098 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 29, CORBA::COMPLETED_NO);
1101 void
1102 TAO_Root_POA::adapter_state_changed (
1103 const TAO::ORT_Array &array_obj_ref_template,
1104 PortableInterceptor::AdapterState state)
1106 TAO_IORInterceptor_Adapter *ior_adapter =
1107 this->orb_core_.ior_interceptor_adapter ();
1109 if (ior_adapter)
1111 ior_adapter->adapter_state_changed (array_obj_ref_template, state);
1115 PortableServer::ObjectId *
1116 TAO_Root_POA::activate_object_i (PortableServer::Servant servant,
1117 CORBA::Short priority,
1118 bool &wait_occurred_restart_call)
1120 return this->active_policy_strategies_.servant_retention_strategy()->
1121 activate_object (servant,
1122 priority,
1123 wait_occurred_restart_call);
1126 PortableServer::ObjectId *
1127 TAO_Root_POA::activate_object (PortableServer::Servant servant)
1129 while (1)
1131 bool wait_occurred_restart_call = false;
1133 // Lock access for the duration of this transaction.
1134 TAO_POA_GUARD_RETURN (0);
1136 PortableServer::ObjectId *result =
1137 this->activate_object_i (servant,
1138 this->server_priority (),
1139 wait_occurred_restart_call);
1141 // If we ended up waiting on a condition variable, the POA state
1142 // may have changed while we are waiting. Therefore, we need to
1143 // restart this call.
1144 if (wait_occurred_restart_call)
1145 continue;
1146 else
1147 return result;
1151 void
1152 TAO_Root_POA::activate_object_with_id (const PortableServer::ObjectId &id,
1153 PortableServer::Servant servant)
1155 while (1)
1157 bool wait_occurred_restart_call = false;
1159 // Lock access for the duration of this transaction.
1160 TAO_POA_GUARD;
1162 this->activate_object_with_id_i (id,
1163 servant,
1164 this->server_priority (),
1165 wait_occurred_restart_call);
1167 // If we ended up waiting on a condition variable, the POA state
1168 // may have changed while we are waiting. Therefore, we need to
1169 // restart this call.
1170 if (wait_occurred_restart_call)
1171 continue;
1172 else
1173 return;
1177 void
1178 TAO_Root_POA::activate_object_with_id_i (const PortableServer::ObjectId &id,
1179 PortableServer::Servant servant,
1180 CORBA::Short priority,
1181 bool &wait_occurred_restart_call)
1183 this->active_policy_strategies_.servant_retention_strategy()->
1184 activate_object_with_id (id,
1185 servant,
1186 priority,
1187 wait_occurred_restart_call);
1190 void
1191 TAO_Root_POA::deactivate_all_objects_i (CORBA::Boolean etherealize_objects,
1192 CORBA::Boolean wait_for_completion)
1194 this->deactivate_all_objects_i (etherealize_objects);
1196 this->wait_for_completions (wait_for_completion);
1199 void
1200 TAO_Root_POA::wait_for_completions (CORBA::Boolean wait_for_completion)
1202 while (wait_for_completion &&
1203 this->outstanding_requests_ > 0)
1205 this->wait_for_completion_pending_ = true;
1207 int const result = this->outstanding_requests_condition_.wait ();
1208 if (result == -1)
1210 throw ::CORBA::OBJ_ADAPTER ();
1215 /* static */
1216 void
1217 TAO_Root_POA::check_for_valid_wait_for_completions (const TAO_ORB_Core &orb_core,
1218 CORBA::Boolean wait_for_completion)
1220 if (wait_for_completion)
1222 TAO::Portable_Server::POA_Current_Impl *poa_current_impl =
1223 static_cast <TAO::Portable_Server::POA_Current_Impl *>
1224 (TAO_TSS_Resources::instance ()->poa_current_impl_);
1226 while (1)
1228 // If wait_for_completion is TRUE and the current thread is
1229 // in an invocation context dispatched from some POA
1230 // belonging to the same ORB as this POA, the BAD_INV_ORDER
1231 // system exception with standard minor code 3 is raised and
1232 // POA destruction does not occur.
1233 if ((poa_current_impl != 0) && (poa_current_impl->poa () != 0))
1235 if (&orb_core == &poa_current_impl->orb_core ())
1237 // CORBA 2.3 specifies which minor code corresponds
1238 // to this particular problem.
1239 throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 3,
1240 CORBA::COMPLETED_NO);
1243 else
1244 break;
1246 poa_current_impl =
1247 poa_current_impl->previous_current_impl_;
1252 void
1253 TAO_Root_POA::deactivate_all_objects_i (CORBA::Boolean etherealize_objects)
1255 this->active_policy_strategies_.request_processing_strategy ()->
1256 etherealize_objects (etherealize_objects);
1258 this->active_policy_strategies_.servant_retention_strategy ()->
1259 deactivate_all_objects ();
1262 void
1263 TAO_Root_POA::deactivate_object (const PortableServer::ObjectId &oid)
1265 // Lock access for the duration of this transaction.
1266 TAO_POA_GUARD;
1268 this->deactivate_object_i (oid);
1271 void
1272 TAO_Root_POA::deactivate_object_i (const PortableServer::ObjectId &id)
1274 this->active_policy_strategies_.servant_retention_strategy()->
1275 deactivate_object (id);
1278 CORBA::Boolean
1279 TAO_Root_POA::is_persistent () const
1281 return active_policy_strategies_.lifespan_strategy()->is_persistent ();
1284 CORBA::Object_ptr
1285 TAO_Root_POA::create_reference (const char *intf)
1287 // Lock access for the duration of this transaction.
1288 TAO_POA_GUARD_RETURN (CORBA::Object::_nil ());
1290 return this->create_reference_i (intf,
1291 this->server_priority ());
1294 CORBA::Object_ptr
1295 TAO_Root_POA::create_reference_i (const char *intf,
1296 CORBA::Short priority)
1298 if (!this->has_system_id ())
1300 throw PortableServer::POA::WrongPolicy ();
1303 return this->active_policy_strategies_.servant_retention_strategy()->
1304 create_reference (intf, priority);
1307 CORBA::Object_ptr
1308 TAO_Root_POA::invoke_key_to_object_helper_i (const char * repository_id,
1309 const PortableServer::ObjectId & id)
1311 const PortableInterceptor::ObjectId &user_oid =
1312 reinterpret_cast <const PortableInterceptor::ObjectId &>(id);
1314 // Ask the ORT to create the object.
1315 if (this->ORT_adapter_i ())
1317 // Ask the ORT to create the object.
1318 return this->ort_adapter_->make_object (repository_id, user_oid);
1320 else
1322 return this->invoke_key_to_object ();
1326 #if ! defined (CORBA_E_MICRO)
1327 CORBA::Object_ptr
1328 TAO_Root_POA::create_reference_with_id_i (const PortableServer::ObjectId &user_id,
1329 const char *intf,
1330 CORBA::Short priority)
1332 // If the POA has the SYSTEM_ID policy and it detects that the
1333 // Object Id value was not generated by the system or for this POA,
1334 // the create_reference_with_id operation may raise the BAD_PARAM
1335 // system exception. An ORB is not required to detect all such
1336 // invalid Object Id values, but a portable application must not
1337 // invoke this operation on a POA that has the SYSTEM_ID policy with
1338 // an Object Id value that was not previously generated by the
1339 // system for that POA, or, if the POA also has the PERSISTENT
1340 // policy, for a previous instantiation of the same POA.
1341 if (this->has_system_id () &&
1342 !this->is_poa_generated_id (user_id))
1344 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 14, CORBA::COMPLETED_NO);
1347 return this->active_policy_strategies_.servant_retention_strategy()->
1348 create_reference_with_id (user_id, intf, priority);
1350 #endif
1352 PortableServer::ObjectId *
1353 TAO_Root_POA::servant_to_id_i (PortableServer::Servant servant)
1355 return this->active_policy_strategies_.request_processing_strategy()->
1356 servant_to_id (servant);
1359 CORBA::Object_ptr
1360 TAO_Root_POA::servant_to_reference_i (PortableServer::Servant servant)
1362 return this->active_policy_strategies_.servant_retention_strategy()->
1363 servant_to_reference (servant);
1366 PortableServer::Servant
1367 TAO_Root_POA::reference_to_servant_i (CORBA::Object_ptr reference)
1369 // Make sure that the reference is valid.
1370 if (CORBA::is_nil (reference))
1372 throw ::CORBA::BAD_PARAM ();
1375 PortableServer::ObjectId system_id;
1376 bool const is_generated =
1377 this->is_poa_generated (reference, system_id);
1379 if (!is_generated)
1381 // In case this object reference is not generated by this POA throw
1382 // an exception
1383 throw PortableServer::POA::WrongAdapter ();
1386 PortableServer::Servant servant =
1387 this->active_policy_strategies_.request_processing_strategy()->
1388 system_id_to_servant (system_id);
1390 if (servant != 0)
1392 // ATTENTION: Trick locking here, see class header for details
1393 TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*this);
1394 ACE_UNUSED_ARG (non_servant_upcall);
1396 // The POA invokes _add_ref once on the Servant before returning
1397 // it. If the application uses reference counting, the caller of
1398 // id_to_servant is responsible for invoking _remove_ref once on
1399 // the returned Servant when it is finished with it. A
1400 // conforming caller need not invoke _remove_ref on the returned
1401 // Servant if the type of the Servant uses the default reference
1402 // counting inherited from ServantBase.
1403 servant->_add_ref ();
1406 return servant;
1409 bool
1410 TAO_Root_POA::is_poa_generated (CORBA::Object_ptr reference,
1411 PortableServer::ObjectId &system_id)
1413 TAO::ObjectKey_var key = reference->_key ();
1415 TAO_Object_Adapter::poa_name poa_system_name;
1416 CORBA::Boolean is_root = false;
1417 CORBA::Boolean is_persistent = false;
1418 CORBA::Boolean is_system_id = false;
1419 TAO::Portable_Server::Temporary_Creation_Time poa_creation_time;
1421 int const result = this->parse_key (key.in (),
1422 poa_system_name,
1423 system_id,
1424 is_root,
1425 is_persistent,
1426 is_system_id,
1427 poa_creation_time);
1428 if (result != 0
1429 || (this->root () == 0 && poa_system_name != this->system_name ())
1430 || is_root != this->root ()
1431 || is_system_id != this->system_id ()
1432 || !this->validate_lifespan (is_persistent, poa_creation_time))
1434 // The passed reference is NOT generated by this POA.
1435 return false;
1437 else
1439 // The passed reference is generated by this POA.
1440 return true;
1444 PortableServer::ObjectId *
1445 TAO_Root_POA::reference_to_id (CORBA::Object_ptr reference)
1447 // Make sure that the reference is valid.
1448 if (CORBA::is_nil (reference))
1450 throw ::CORBA::BAD_PARAM ();
1453 // The WrongPolicy exception is declared to allow future extensions.
1455 // This operation is valid only if the reference was created by the
1456 // POA on which the operation is being performed. If the object
1457 // reference was not created by this POA, the WrongAdapter exception
1458 // is raised.
1459 PortableServer::ObjectId system_id;
1460 bool const is_generated = this->is_poa_generated (reference, system_id);
1462 if (!is_generated)
1464 throw PortableServer::POA::WrongAdapter ();
1467 // Lock access for the duration of this transaction.
1468 TAO_POA_GUARD_RETURN (0);
1470 return this->active_policy_strategies_.servant_retention_strategy()->
1471 system_id_to_object_id (system_id);
1474 PortableServer::Servant
1475 TAO_Root_POA::find_servant (const PortableServer::ObjectId &system_id)
1477 return this->active_policy_strategies_.servant_retention_strategy()->
1478 find_servant (system_id);
1482 TAO_Root_POA::unbind_using_user_id (const PortableServer::ObjectId &user_id)
1484 return this->active_policy_strategies_.servant_retention_strategy()->
1485 unbind_using_user_id (user_id);
1488 void
1489 TAO_Root_POA::cleanup_servant (
1490 PortableServer::Servant servant,
1491 const PortableServer::ObjectId &user_id)
1493 this->active_policy_strategies_.request_processing_strategy()->
1494 cleanup_servant (servant, user_id);
1497 PortableServer::Servant
1498 TAO_Root_POA::id_to_servant_i (const PortableServer::ObjectId &id)
1500 PortableServer::Servant servant =
1501 this->active_policy_strategies_.request_processing_strategy()->
1502 id_to_servant (id);
1504 if (servant != 0)
1506 // ATTENTION: Trick locking here, see class header for details
1507 TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*this);
1508 ACE_UNUSED_ARG (non_servant_upcall);
1510 // The POA invokes _add_ref once on the Servant before returning
1511 // it. If the application uses reference counting, the caller of
1512 // id_to_servant is responsible for invoking _remove_ref once on
1513 // the returned Servant when it is finished with it. A
1514 // conforming caller need not invoke _remove_ref on the returned
1515 // Servant if the type of the Servant uses the default reference
1516 // counting inherited from ServantBase.
1517 servant->_add_ref ();
1520 return servant;
1523 PortableServer::Servant
1524 TAO_Root_POA::user_id_to_servant_i (const PortableServer::ObjectId &id)
1526 return this->active_policy_strategies_.servant_retention_strategy()->
1527 user_id_to_servant (id);
1530 CORBA::Object_ptr
1531 TAO_Root_POA::id_to_reference_i (const PortableServer::ObjectId &id,
1532 bool indirect)
1534 return this->active_policy_strategies_.servant_retention_strategy()->
1535 id_to_reference (id, indirect);
1538 CORBA::OctetSeq *
1539 TAO_Root_POA::id ()
1541 CORBA::OctetSeq *id = 0;
1542 ACE_NEW_THROW_EX (id,
1543 CORBA::OctetSeq (this->id_),
1544 CORBA::NO_MEMORY ());
1546 return id;
1549 PortableServer::Servant
1550 TAO_Root_POA::locate_servant_i (const char *operation,
1551 const PortableServer::ObjectId &system_id,
1552 TAO::Portable_Server::Servant_Upcall &servant_upcall,
1553 TAO::Portable_Server::POA_Current_Impl &poa_current_impl,
1554 bool &wait_occurred_restart_call)
1556 return this->active_policy_strategies_.request_processing_strategy()->
1557 locate_servant (operation,
1558 system_id,
1559 servant_upcall,
1560 poa_current_impl,
1561 wait_occurred_restart_call);
1564 /* static */
1566 TAO_Root_POA::parse_key (const TAO::ObjectKey &key,
1567 TAO_Object_Adapter::poa_name &poa_system_name,
1568 PortableServer::ObjectId &system_id,
1569 CORBA::Boolean &is_root,
1570 CORBA::Boolean &is_persistent,
1571 CORBA::Boolean &is_system_id,
1572 TAO::Portable_Server::Temporary_Creation_Time &poa_creation_time)
1574 // Get the object key octets.
1575 const CORBA::Octet *key_data = key.get_buffer ();
1577 // Skip the object key prefix since we have already checked for this.
1578 CORBA::ULong starting_at = TAO_OBJECTKEY_PREFIX_SIZE;
1580 // Check the root indicator.
1581 char root_key_type = key_data[starting_at];
1582 if (root_key_type == TAO_Root_POA::root_key_char ())
1584 is_root = true;
1586 else if (root_key_type == TAO_Root_POA::non_root_key_char ())
1588 is_root = false;
1590 else
1592 // Incorrect key
1593 return -1;
1596 // Skip past the system id indicator
1597 starting_at += TAO_Root_POA::root_key_type_length ();
1599 // Check the system id indicator.
1600 char system_id_key_type = key_data[starting_at];
1601 if (system_id_key_type == TAO_Root_POA::system_id_key_char ())
1603 is_system_id = true;
1605 else if (system_id_key_type == TAO_Root_POA::user_id_key_char ())
1607 is_system_id = false;
1609 else
1611 // Incorrect key
1612 return -1;
1615 // Skip past the system id indicator
1616 starting_at += TAO_Root_POA::system_id_key_type_length ();
1618 // Check the persistence indicator
1619 char persistent_key_type = key_data[starting_at];
1620 if (persistent_key_type == TAO_Root_POA::persistent_key_char ())
1622 is_persistent = true;
1624 else if (persistent_key_type == TAO_Root_POA::transient_key_char ())
1626 is_persistent = false;
1628 else
1630 // Incorrect key
1631 return -1;
1634 // Skip past the persistent indicator
1635 starting_at += TAO_Root_POA::persistent_key_type_length ();
1637 #if (POA_NO_TIMESTAMP == 0)
1638 // Grab the timestamp for transient POAs.
1639 if (!is_persistent)
1641 // Take the creation time for the timestamp
1642 poa_creation_time.creation_time (key_data + starting_at);
1644 // Skip past the timestamp
1645 starting_at += TAO::Portable_Server::Creation_Time::creation_time_length ();
1647 #else
1648 ACE_UNUSED_ARG (poa_creation_time);
1649 #endif /* POA_NO_TIMESTAMP */
1651 // Calculate the size of the POA name.
1652 CORBA::ULong poa_name_size = 0;
1653 if (!is_persistent)
1655 // Transient POAs have fixed size.
1656 poa_name_size = TAO_Object_Adapter::transient_poa_name_size ();
1658 else if (is_system_id)
1660 // System ids have fixed size.
1661 poa_name_size = static_cast <CORBA::ULong>
1662 (key.length () - starting_at -
1663 TAO_Active_Object_Map::system_id_size ());
1665 else
1667 // Get the size from the object key.
1668 ACE_OS::memcpy (&poa_name_size,
1669 key_data + starting_at,
1670 sizeof (poa_name_size));
1671 poa_name_size = ACE_NTOHL (poa_name_size);
1673 starting_at += sizeof (poa_name_size);
1676 // Grep the name if there is a name
1677 if (!is_root)
1679 poa_system_name.replace (poa_name_size,
1680 poa_name_size,
1681 (CORBA::Octet *) key_data + starting_at,
1684 starting_at += poa_name_size;
1687 // The rest is the system id.
1688 CORBA::ULong system_id_size = key.length () - starting_at;
1690 // Reset <system_id>.
1691 system_id.length (system_id_size);
1692 CORBA::Octet * buf = system_id.get_buffer ();
1693 ACE_OS::memcpy (buf, key_data + starting_at, system_id_size);
1695 // Success
1696 return 0;
1699 TAO::ObjectKey *
1700 TAO_Root_POA::create_object_key (const PortableServer::ObjectId &id)
1702 // Calculate the space required for the key.
1703 CORBA::ULong buffer_size =
1704 this->id_.length () +
1705 id.length ();
1707 // Create the buffer for the key.
1708 CORBA::Octet *buffer = TAO::ObjectKey::allocbuf (buffer_size);
1710 // First copy the POA id into the key.
1711 ACE_OS::memcpy (&buffer[0],
1712 this->id_.get_buffer (),
1713 this->id_.length ());
1715 // Then copy the object id into the key.
1716 ACE_OS::memcpy (&buffer[this->id_.length ()],
1717 id.get_buffer (),
1718 id.length ());
1720 // Create the key, giving the ownership of the buffer to the
1721 // sequence.
1722 TAO::ObjectKey *key = 0;
1723 ACE_NEW_RETURN (key,
1724 TAO::ObjectKey (buffer_size,
1725 buffer_size,
1726 buffer,
1730 return key;
1733 void
1734 TAO_Root_POA::set_id (TAO_Root_POA *parent)
1736 // Calculate the prefix size.
1737 CORBA::ULong prefix_size = 0;
1738 prefix_size += TAO_OBJECTKEY_PREFIX_SIZE;
1740 // If we are dealing with a persistent POA and user ids are being
1741 // used, then we need to add the POA name length field to the object
1742 // key. Otherwise, the POA name length can be calculated by looking
1743 // at the remainder after extracting other parts of the key.
1744 bool const add_poa_name_length =
1745 this->is_persistent () &&
1746 !this->system_id ();
1748 // Size required by the POA name.
1749 CORBA::ULong poa_name = 0;
1751 // Calculate the space required for the POA name.
1752 CORBA::ULong poa_name_length = this->system_name_->length ();
1753 if (parent != 0)
1755 poa_name += poa_name_length;
1758 // Check if we need to added the length of the POA name.
1759 if (add_poa_name_length)
1761 poa_name += sizeof (poa_name_length);
1764 // Get the space needed for the lifespan length
1765 // byte.
1766 CORBA::ULong const lifespan_key_length =
1767 this->active_policy_strategies_.lifespan_strategy()->key_length ();
1769 CORBA::ULong const id_assignment_key_length =
1770 this->active_policy_strategies_.id_assignment_strategy()->key_type_length ();
1772 // Calculate the space required for the POA id.
1773 CORBA::ULong const buffer_size =
1774 prefix_size +
1775 this->root_key_type_length () +
1776 id_assignment_key_length +
1777 lifespan_key_length +
1778 poa_name;
1780 // Create the buffer for the POA id.
1781 this->id_.length (buffer_size);
1782 CORBA::Octet *buffer = &this->id_[0];
1784 // Keeps track of where the next infomation goes; start at 0 byte.
1785 CORBA::ULong starting_at = 0;
1787 // Add the object key prefix.
1788 ACE_OS::memcpy (&buffer[starting_at],
1789 &objectkey_prefix[0],
1790 TAO_OBJECTKEY_PREFIX_SIZE);
1792 starting_at += TAO_OBJECTKEY_PREFIX_SIZE;
1794 // Copy the root byte.
1795 if (parent != 0)
1797 buffer[starting_at] = (CORBA::Octet) TAO_Root_POA::non_root_key_char ();
1799 else
1801 buffer[starting_at] = (CORBA::Octet) TAO_Root_POA::root_key_char ();
1803 starting_at += this->root_key_type_length ();
1805 // Add the id_assignment part
1806 this->active_policy_strategies_.id_assignment_strategy()->create_key (buffer, starting_at);
1808 // Add the lifespan part
1809 this->active_policy_strategies_.lifespan_strategy()->create_key (buffer, starting_at);
1811 // Check if we need to added the length of the POA name.
1812 if (add_poa_name_length)
1814 poa_name_length = ACE_HTONL (poa_name_length);
1815 ACE_OS::memcpy (&buffer[starting_at],
1816 &poa_name_length,
1817 sizeof (poa_name_length));
1818 starting_at += sizeof (poa_name_length);
1821 // Put the POA name into the key (for non-root POAs).
1822 if (parent != 0)
1824 ACE_OS::memcpy (&buffer[starting_at],
1825 this->system_name_->get_buffer (),
1826 this->system_name_->length ());
1827 starting_at += this->system_name_->length ();
1832 TAO_Root_POA::is_poa_generated_id (const PortableServer::ObjectId &id)
1834 #if defined (POA_NAME_IN_POA_GENERATED_ID)
1836 // Grab the buffer
1837 const char *id_buffer = (const char *) id.get_buffer ();
1839 // Check to see if the POA name is the first part of the id
1840 return
1841 this->name_.length () < id.length () &&
1842 ACE_OS::strncmp (id_buffer,
1843 this->name_.c_str (),
1844 this->name_.length ()) == 0;
1845 #else /* POA_NAME_IN_POA_GENERATED_ID */
1847 ACE_UNUSED_ARG (id);
1848 return 1;
1850 #endif /* POA_NAME_IN_POA_GENERATED_ID */
1853 void
1854 TAO_Root_POA::set_folded_name (TAO_Root_POA *parent)
1856 size_t length = 0;
1857 size_t parent_length = 0;
1859 if (parent != 0)
1861 parent_length = parent->folded_name ().length ();
1862 length += parent_length;
1865 length += this->name_.length ();
1866 length += TAO_Root_POA::name_separator_length ();
1868 this->folded_name_.length (static_cast <CORBA::ULong> (length));
1869 CORBA::Octet *folded_name_buffer = this->folded_name_.get_buffer ();
1871 if (parent != 0)
1873 ACE_OS::memcpy (folded_name_buffer,
1874 parent->folded_name ().get_buffer (),
1875 parent_length);
1878 ACE_OS::memcpy (&folded_name_buffer[parent_length],
1879 this->name_.c_str (),
1880 this->name_.length ());
1882 folded_name_buffer[length - TAO_Root_POA::name_separator_length ()] = TAO_Root_POA::name_separator ();
1886 TAO_Root_POA::parse_ir_object_key (const TAO::ObjectKey &object_key,
1887 PortableServer::ObjectId &user_id)
1889 TAO_Object_Adapter::poa_name poa_system_name;
1890 CORBA::Boolean is_root = false;
1891 CORBA::Boolean is_persistent = false;
1892 CORBA::Boolean is_system_id = false;
1893 TAO::Portable_Server::Temporary_Creation_Time poa_creation_time;
1895 return TAO_Root_POA::parse_key (object_key,
1896 poa_system_name,
1897 user_id,
1898 is_root,
1899 is_persistent,
1900 is_system_id,
1901 poa_creation_time);
1904 TAO_Object_Adapter &
1905 TAO_Root_POA::object_adapter ()
1907 return *this->object_adapter_;
1910 CORBA::Object_ptr
1911 TAO_Root_POA::invoke_key_to_object ()
1913 PortableServer::ObjectId_var &system_id =
1914 *this->key_to_object_params_.system_id_;
1916 // Create object key.
1917 TAO::ObjectKey_var key =
1918 this->create_object_key (system_id.in ());
1920 return this->key_to_object (key.in (),
1921 this->key_to_object_params_.type_id_,
1922 this->key_to_object_params_.servant_,
1923 this->key_to_object_params_.collocated_,
1924 this->key_to_object_params_.priority_,
1925 this->key_to_object_params_.indirect_);
1928 CORBA::Object_ptr
1929 TAO_Root_POA::key_to_object (const TAO::ObjectKey &key,
1930 const char *type_id,
1931 TAO_ServantBase *servant,
1932 CORBA::Boolean collocated,
1933 CORBA::Short priority,
1934 bool indirect)
1936 // Check if the ORB is still running, otherwise throw an exception.
1937 // @@ What if the ORB was destroyed? In that case we shouldn't even
1938 // get here!
1939 this->orb_core_.check_shutdown ();
1942 // ImplRepo related.
1944 #if (TAO_HAS_MINIMUM_CORBA == 0)
1946 if (indirect && this->orb_core ().imr_endpoints_in_ior ())
1948 CORBA::Object_ptr obj = this->active_policy_strategies_.
1949 lifespan_strategy()->imr_key_to_object (key, type_id);
1950 if (!CORBA::is_nil (obj))
1952 return obj;
1956 #else
1957 ACE_UNUSED_ARG (indirect);
1958 #endif /* TAO_HAS_MINIMUM_CORBA */
1960 TAO_Stub *data = this->key_to_stub_i (key, type_id, priority);
1962 TAO_Stub_Auto_Ptr safe_data (data);
1964 CORBA::Object_ptr tmp;
1966 if (this->orb_core_.optimize_collocation_objects ())
1968 ACE_NEW_THROW_EX (tmp, CORBA::Object (data,
1969 collocated,
1970 servant),
1971 CORBA::INTERNAL ());
1973 else
1975 ACE_NEW_THROW_EX (tmp,
1976 CORBA::Object (data,
1977 collocated),
1978 CORBA::INTERNAL ());
1981 data->servant_orb (this->orb_core_.orb ());
1983 // Transfer ownership to the Object.
1984 (void) safe_data.release ();
1986 return tmp;
1989 TAO_Stub *
1990 TAO_Root_POA::key_to_stub (const TAO::ObjectKey &key,
1991 const char *type_id,
1992 CORBA::Short priority)
1994 // Check if the ORB is still running, otherwise throw an exception.
1995 // @@ What if the ORB was destroyed? In that case we shouldn't even
1996 // get here!
1997 this->orb_core_.check_shutdown ();
1999 return this->key_to_stub_i (key, type_id, priority);
2002 TAO_Stub *
2003 TAO_Root_POA::key_to_stub_i (const TAO::ObjectKey &key,
2004 const char *type_id,
2005 CORBA::Short priority)
2007 CORBA::PolicyList_var client_exposed_policies =
2008 this->client_exposed_policies (priority);
2010 TAO_Acceptor_Filter* filter = 0;
2012 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
2013 if (this->filter_factory_)
2015 filter = this->filter_factory_->create_object (this->poa_manager_);
2017 else
2018 #endif
2020 ACE_NEW_RETURN (filter,
2021 TAO_Default_Acceptor_Filter (),
2025 // Give ownership to the auto pointer.
2026 std::unique_ptr<TAO_Acceptor_Filter> new_filter (filter);
2028 TAO_Stub *data =
2029 this->create_stub_object (
2030 key,
2031 type_id,
2032 client_exposed_policies._retn (),
2033 filter,
2034 this->orb_core_.lane_resources ().acceptor_registry ());
2036 return data;
2039 void
2040 TAO_Root_POA::establish_components ()
2042 TAO_IORInterceptor_Adapter *ior_adapter =
2043 this->orb_core_.ior_interceptor_adapter ();
2045 if (ior_adapter)
2047 ior_adapter->establish_components (this);
2051 void
2052 TAO_Root_POA::components_established (PortableInterceptor::IORInfo_ptr info)
2054 TAO_IORInterceptor_Adapter *ior_adapter =
2055 this->orb_core_.ior_interceptor_adapter ();
2057 if (ior_adapter)
2059 ior_adapter->components_established (info);
2063 void
2064 TAO_Root_POA::save_ior_component (const IOP::TaggedComponent &component)
2066 CORBA::ULong const old_len = this->tagged_component_.length ();
2068 this->tagged_component_.length (old_len + 1);
2069 this->tagged_component_[old_len] = component;
2072 void
2073 TAO_Root_POA::
2074 save_ior_component_and_profile_id (const IOP::TaggedComponent &component,
2075 IOP::ProfileId profile_id)
2077 // The length of this->tagged_component_id_ is the same as the
2078 // length of the profile_id_array_ since we are trying to make a
2079 // one-to-one link between these two arrays. So, whenever
2080 // this->tagged_component_id_ is increased, we need to increase the
2081 // size of this->profile_id_array_ also.
2083 CORBA::ULong const old_len = this->tagged_component_id_.length ();
2085 CORBA::ULong const new_len = old_len + 1;
2087 this->tagged_component_id_.length (new_len);
2088 this->tagged_component_id_[old_len] = component;
2090 this->profile_id_array_.size (new_len);
2091 this->profile_id_array_[old_len] = profile_id;
2094 TAO_Stub *
2095 TAO_Root_POA::create_stub_object (const TAO::ObjectKey &object_key,
2096 const char *type_id,
2097 CORBA::PolicyList *policy_list,
2098 TAO_Acceptor_Filter *filter,
2099 TAO_Acceptor_Registry &acceptor_registry)
2101 bool error = false;
2103 // Count the number of endpoints.
2104 size_t const profile_count = acceptor_registry.endpoint_count ();
2106 // Create a profile container and have acceptor registries populate
2107 // it with profiles as appropriate.
2108 TAO_MProfile mprofile (0);
2110 // Allocate space for storing the profiles. There can never be more
2111 // profiles than there are endpoints. In some cases, there can be
2112 // less profiles than endpoints.
2113 int result = mprofile.set (static_cast <CORBA::ULong> (profile_count));
2114 if (result == -1)
2115 error = true;
2117 if (!error)
2119 result =
2120 filter->fill_profile (object_key,
2121 mprofile,
2122 acceptor_registry.begin (),
2123 acceptor_registry.end ());
2124 if (result == -1)
2125 error = true;
2128 if (!error)
2129 result = filter->encode_endpoints (mprofile);
2131 if (result == -1)
2132 error = true;
2134 if (error)
2135 throw ::CORBA::INTERNAL (
2136 CORBA::SystemException::_tao_minor_code (
2137 TAO_MPROFILE_CREATION_ERROR,
2139 CORBA::COMPLETED_NO);
2141 // Make sure we have at least one profile. <mp> may end up being
2142 // empty if none of the acceptor endpoints have the right priority
2143 // for this object, for example.
2144 if (mprofile.profile_count () == 0)
2145 throw ::CORBA::BAD_PARAM (
2146 CORBA::SystemException::_tao_minor_code (
2147 TAO_MPROFILE_CREATION_ERROR,
2149 CORBA::COMPLETED_NO);
2151 TAO_Stub *stub =
2152 this->orb_core_.create_stub_object (mprofile, type_id, policy_list);
2154 // Add the saved tagged components methods to the profiles.
2155 CORBA::ULong len = this->tagged_component_.length ();
2156 for (CORBA::ULong i = 0; i != len; ++i)
2158 this->add_ior_component (mprofile, this->tagged_component_[i]);
2161 len = this->tagged_component_id_.length ();
2163 for (CORBA::ULong k = 0; k != len; ++k)
2165 this->add_ior_component_to_profile (mprofile,
2166 this->tagged_component_id_[k],
2167 this->profile_id_array_[k]);
2170 return stub;
2173 CORBA::PolicyList *
2174 TAO_Root_POA::client_exposed_policies (CORBA::Short /* object_priority */)
2176 CORBA::PolicyList *client_exposed_policies = 0;
2177 ACE_NEW_THROW_EX (client_exposed_policies,
2178 CORBA::PolicyList (),
2179 CORBA::NO_MEMORY (TAO::VMCID,
2180 CORBA::COMPLETED_NO));
2182 CORBA::PolicyList_var policies = client_exposed_policies;
2184 // Add in all of the client exposed policies.
2185 this->policies_.add_client_exposed_fixed_policies (client_exposed_policies);
2187 return policies._retn ();
2190 TAO_Servant_Location
2191 TAO_Root_POA::locate_servant_i (const PortableServer::ObjectId &system_id,
2192 PortableServer::Servant &servant)
2194 return this->active_policy_strategies_.request_processing_strategy()->
2195 locate_servant (system_id, servant);
2198 TAO_Servant_Location
2199 TAO_Root_POA::servant_present (const PortableServer::ObjectId &system_id,
2200 PortableServer::Servant &servant)
2202 return this->active_policy_strategies_.servant_retention_strategy()->
2203 servant_present (system_id, servant);
2206 PortableServer::Servant
2207 TAO_Root_POA::find_servant (
2208 const PortableServer::ObjectId &system_id,
2209 TAO::Portable_Server::Servant_Upcall &servant_upcall,
2210 TAO::Portable_Server::POA_Current_Impl &poa_current_impl)
2212 return this->active_policy_strategies_.servant_retention_strategy()->
2213 find_servant (system_id,
2214 servant_upcall,
2215 poa_current_impl);
2219 TAO_Root_POA::find_servant_priority (
2220 const PortableServer::ObjectId &system_id,
2221 CORBA::Short &priority)
2223 return this->active_policy_strategies_.servant_retention_strategy()->
2224 find_servant_priority (system_id, priority);
2227 TAO::ORT_Adapter *
2228 TAO_Root_POA::ORT_adapter_i ()
2230 if ((this->ort_adapter_factory_) && (this->ort_adapter_ == 0))
2234 // Get the full adapter name of this POA, do this before we
2235 // create the adapter so that in case this fails, we just
2236 // return 0 and not a not activated adapter
2237 PortableInterceptor::AdapterName *adapter_name = this->adapter_name_i ();
2239 this->ort_adapter_ = this->ort_adapter_factory_->create ();
2241 if (this->ort_adapter_)
2243 // @todo We have to look at this, we activate it but hold the POA lock,
2244 // in case we are called by ORT_adapter, we shouldn't keep the lock
2245 // here, but then the ort_adapter should be guarded against multiple
2246 // activations.
2247 this->ort_adapter_->activate (this->orb_core_.server_id (),
2248 this->orb_core_.orbid (),
2249 adapter_name,
2250 this);
2253 catch (const ::CORBA::Exception& ex)
2255 ex._tao_print_exception (
2256 "(%P|%t) Cannot initialize the "
2257 "object_reference_template_adapter\n");
2261 return this->ort_adapter_;
2264 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
2266 PortableServer::AdapterActivator_ptr
2267 TAO_Root_POA::the_activator ()
2269 // Lock access for the duration of this transaction.
2270 TAO_POA_GUARD_RETURN (PortableServer::AdapterActivator::_nil ());
2272 return PortableServer::AdapterActivator::_duplicate (this->adapter_activator_.in ());
2275 void
2276 TAO_Root_POA::the_activator (PortableServer::AdapterActivator_ptr adapter_activator)
2278 // Lock access for the duration of this transaction.
2279 TAO_POA_GUARD;
2281 this->adapter_activator_ = PortableServer::AdapterActivator::_duplicate (adapter_activator);
2284 #endif /* TAO_HAS_MINIMUM_POA == 0 && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)*/
2286 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
2288 PortableServer::ServantManager_ptr
2289 TAO_Root_POA::get_servant_manager ()
2291 // Lock access for the duration of this transaction.
2292 TAO_POA_GUARD_RETURN (PortableServer::ServantManager::_nil ());
2294 return this->active_policy_strategies_.request_processing_strategy()->
2295 get_servant_manager ();
2298 void
2299 TAO_Root_POA::set_servant_manager (PortableServer::ServantManager_ptr imgr)
2301 // Lock access for the duration of this transaction.
2302 TAO_POA_GUARD;
2304 this->active_policy_strategies_.request_processing_strategy()->
2305 set_servant_manager (imgr);
2308 PortableServer::Servant
2309 TAO_Root_POA::get_servant_i ()
2311 return this->active_policy_strategies_.request_processing_strategy()->
2312 get_servant ();
2315 PortableServer::Servant
2316 TAO_Root_POA::get_servant ()
2318 // Lock access for the duration of this transaction.
2319 TAO_POA_GUARD_RETURN (0);
2321 PortableServer::Servant servant = this->get_servant_i ();
2323 if (servant != 0)
2325 // ATTENTION: Trick locking here, see class header for details
2326 TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*this);
2327 ACE_UNUSED_ARG (non_servant_upcall);
2329 // The POA invokes _add_ref once on the Servant before returning
2330 // it. If the application uses reference counting, the caller of
2331 // get_servant is responsible for invoking _remove_ref once on
2332 // the returned Servant when it is finished with it. A
2333 // conforming caller need not invoke _remove_ref on the returned
2334 // Servant if the type of the Servant uses the default reference
2335 // counting inherited from ServantBase.
2336 servant->_add_ref ();
2338 return servant;
2340 else
2342 // If no servant has been associated with the POA, the NoServant
2343 // exception is raised.
2344 throw PortableServer::POA::NoServant ();
2348 void
2349 TAO_Root_POA::set_servant (PortableServer::Servant servant)
2351 // Lock access for the duration of this transaction.
2352 TAO_POA_GUARD;
2354 this->active_policy_strategies_.request_processing_strategy()->
2355 set_servant (servant);
2358 #endif /* TAO_HAS_MINIMUM_POA == 0 && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) */
2360 bool
2361 TAO_Root_POA::is_servant_activation_allowed (PortableServer::Servant servant,
2362 bool &wait_occurred_restart_call)
2364 return this->active_policy_strategies_.id_uniqueness_strategy ()->
2365 is_servant_activation_allowed (servant, wait_occurred_restart_call);
2368 bool
2369 TAO_Root_POA::has_system_id () const
2371 return this->active_policy_strategies_.id_assignment_strategy ()->
2372 has_system_id ();
2376 TAO_Root_POA::rebind_using_user_id_and_system_id (
2377 PortableServer::Servant servant,
2378 const PortableServer::ObjectId &user_id,
2379 const PortableServer::ObjectId &system_id,
2380 TAO::Portable_Server::Servant_Upcall &servant_upcall)
2382 return this->active_policy_strategies_.servant_retention_strategy ()->
2383 rebind_using_user_id_and_system_id (servant,
2384 user_id,
2385 system_id,
2386 servant_upcall);
2389 CORBA::Boolean
2390 TAO_Root_POA::servant_has_remaining_activations (PortableServer::Servant servant)
2392 return this->active_policy_strategies_.servant_retention_strategy ()->
2393 servant_has_remaining_activations (servant);
2396 bool
2397 TAO_Root_POA::allow_implicit_activation () const
2399 return this->active_policy_strategies_.implicit_activation_strategy ()->
2400 allow_implicit_activation ();
2403 bool
2404 TAO_Root_POA::allow_multiple_activations () const
2406 return this->active_policy_strategies_.id_uniqueness_strategy ()->
2407 allow_multiple_activations ();
2410 void
2411 TAO_Root_POA::post_invoke_servant_cleanup(
2412 const PortableServer::ObjectId &system_id,
2413 const TAO::Portable_Server::Servant_Upcall &servant_upcall)
2415 this->active_policy_strategies_.request_processing_strategy ()->
2416 post_invoke_servant_cleanup (system_id, servant_upcall);
2419 CORBA::Short
2420 TAO_Root_POA::server_priority () const
2422 return this->cached_policies_.server_priority ();
2426 TAO_Root_POA::is_servant_active (
2427 PortableServer::Servant servant,
2428 bool &wait_occurred_restart_call)
2430 return this->active_policy_strategies_.servant_retention_strategy ()->
2431 is_servant_in_map (servant, wait_occurred_restart_call);
2434 TAO::Portable_Server::Cached_Policies&
2435 TAO_Root_POA::cached_policies ()
2437 return this->cached_policies_;
2440 TAO_Network_Priority_Hook*
2441 TAO_Root_POA::network_priority_hook ()
2443 return this->network_priority_hook_;
2446 TAO::Portable_Server::Cached_Policies::PriorityModel
2447 TAO_Root_POA::priority_model () const
2449 return cached_policies_.priority_model ();
2452 #if (TAO_HAS_MINIMUM_POA == 0)
2454 TAO_Root_POA::enter ()
2456 return this->active_policy_strategies_.thread_strategy ()->enter();
2458 #endif /* TAO_HAS_MINIMUM_POA == 0 */
2460 #if (TAO_HAS_MINIMUM_POA == 0)
2462 TAO_Root_POA::exit ()
2464 return this->active_policy_strategies_.thread_strategy ()->exit();
2466 #endif /* TAO_HAS_MINIMUM_POA == 0 */
2468 bool
2469 TAO_Root_POA::validate_lifespan (
2470 CORBA::Boolean is_persistent,
2471 const TAO::Portable_Server::Temporary_Creation_Time& creation_time) const
2473 return this->active_policy_strategies_.lifespan_strategy()->
2474 validate (is_persistent, creation_time);
2477 CORBA::Boolean
2478 TAO_Root_POA::root () const
2480 return true;
2483 TAO::ORT_Adapter *
2484 TAO_Root_POA::ORT_adapter ()
2486 if (this->ort_adapter_ != 0)
2487 return this->ort_adapter_;
2489 // Lock access for the duration of this transaction.
2490 TAO_POA_GUARD_RETURN (0);
2492 // DCL ..
2493 if (this->ort_adapter_ != 0)
2495 return this->ort_adapter_;
2498 return this->ORT_adapter_i ();
2501 CORBA::Policy *
2502 TAO_Root_POA::server_protocol ()
2504 return 0;
2507 void
2508 TAO_Root_POA::Key_To_Object_Params::set (PortableServer::ObjectId_var &system_id,
2509 const char *type_id,
2510 TAO_ServantBase *servant,
2511 CORBA::Boolean collocated,
2512 CORBA::Short priority,
2513 bool indirect)
2515 this->system_id_ = &system_id;
2516 this->type_id_ = type_id;
2517 this->servant_ = servant;
2518 this->collocated_ = collocated;
2519 this->priority_ = priority;
2520 this->indirect_ = indirect;
2523 CORBA::ULong
2524 TAO_Root_POA::waiting_servant_deactivation () const
2526 return this->active_policy_strategies_.servant_retention_strategy ()->
2527 waiting_servant_deactivation ();
2530 void
2531 TAO_Root_POA::ort_adapter_factory_name (const char *name)
2533 TAO_POA_Static_Resources::instance ()->ort_adapter_factory_name_ =
2534 name;
2537 CORBA::Policy_ptr
2538 TAO_Root_POA::get_policy (CORBA::PolicyType policy)
2540 return this->policies_.get_policy (policy);
2543 void
2544 TAO_Root_POA::check_state ()
2546 this->active_policy_strategies_.lifespan_strategy ()->check_state ();
2549 const char *
2550 TAO_Root_POA::ort_adapter_factory_name ()
2552 return TAO_POA_Static_Resources::instance ()->ort_adapter_factory_name_.c_str();
2555 void
2556 TAO_Root_POA::imr_client_adapter_name (const char *name)
2558 TAO_POA_Static_Resources::instance ()->imr_client_adapter_name_ = name;
2561 const char *
2562 TAO_Root_POA::imr_client_adapter_name ()
2564 return TAO_POA_Static_Resources::instance ()->imr_client_adapter_name_.c_str();
2567 PortableServer::POAManager_ptr
2568 TAO_Root_POA::the_POAManager ()
2570 return PortableServer::POAManager::_duplicate (&this->poa_manager_);
2573 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
2574 PortableServer::POAManagerFactory_ptr
2575 TAO_Root_POA::the_POAManagerFactory ()
2577 return PortableServer::POAManagerFactory::_duplicate (&this->poa_manager_factory_);
2579 #endif
2581 CORBA::ORB_ptr
2582 TAO_Root_POA::_get_orb ()
2584 return CORBA::ORB::_duplicate (this->orb_core_.orb ());
2587 // Initialize instance_ to 0, since this is what we test for in the call
2588 // to instance (). Note that this does not require a constructor call, so
2589 // it is always initialized by the time that instance () can be called.
2590 TAO_POA_Static_Resources* TAO_POA_Static_Resources::instance_ = 0;
2592 // Force an instance to be created at module initialization time,
2593 // since we do not want to worry about double checked locking and
2594 // the race condition to initialize the lock.
2595 TAO_POA_Static_Resources* TAO_POA_Static_Resources::initialization_reference_ =
2596 TAO_POA_Static_Resources::instance ();
2598 void
2599 TAO_POA_Static_Resources::fini ()
2601 delete TAO_POA_Static_Resources::instance_;
2602 TAO_POA_Static_Resources::instance_ = 0;
2605 TAO_POA_Static_Resources*
2606 TAO_POA_Static_Resources::instance ()
2608 if (TAO_POA_Static_Resources::instance_ == 0)
2610 // This new is never freed on purpose. The data specified by
2611 // it needs to be around for the last shared library that references
2612 // this class. This could occur in a destructor in a shared library
2613 // that is unloaded after this one. One solution to avoid this
2614 // harmless memory leak would be to use reference counting.
2615 ACE_NEW_RETURN (TAO_POA_Static_Resources::instance_,
2616 TAO_POA_Static_Resources (),
2620 return TAO_POA_Static_Resources::instance_;
2623 TAO_POA_Static_Resources::TAO_POA_Static_Resources ()
2624 : ort_adapter_factory_name_ ("ORT_Adapter_Factory"),
2625 imr_client_adapter_name_ ("ImR_Client_Adapter")
2629 void
2630 TAO_Root_POA::poa_activated_hook ()
2634 void
2635 TAO_Root_POA::poa_deactivated_hook ()
2639 void
2640 TAO_Root_POA::servant_activated_hook (PortableServer::Servant,
2641 const PortableServer::ObjectId&)
2645 void
2646 TAO_Root_POA::servant_deactivated_hook (PortableServer::Servant,
2647 const PortableServer::ObjectId&)
2651 TAO_Active_Object_Map *
2652 TAO_Root_POA::get_active_object_map() const
2654 return this->active_policy_strategies_.servant_retention_strategy()->
2655 get_active_object_map();
2659 TAO_END_VERSIONED_NAMESPACE_DECL