3 //=============================================================================
5 * @file ServantRetentionStrategyRetain.cpp
7 //=============================================================================
9 #include "tao/ORB_Core.h"
10 #include "tao/debug.h"
11 #include "tao/PortableServer/ServantRetentionStrategyRetain.h"
12 #include "tao/PortableServer/Non_Servant_Upcall.h"
13 #include "tao/PortableServer/Servant_Upcall.h"
14 #include "tao/PortableServer/POA_Current_Impl.h"
15 #include "tao/PortableServer/Root_POA.h"
16 #include "tao/PortableServer/Active_Object_Map.h"
17 #include "tao/PortableServer/Active_Object_Map_Entry.h"
19 #if defined (TAO_HAS_MONITOR_POINTS) && (TAO_HAS_MONITOR_POINTS == 1)
20 #include "ace/Monitor_Size.h"
21 #endif /* TAO_HAS_MONITOR_POINTS */
23 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
27 namespace Portable_Server
29 ServantRetentionStrategyRetain::ServantRetentionStrategyRetain () :
30 ServantRetentionStrategyNonRetain (),
31 active_object_map_ (),
32 waiting_servant_deactivation_ (0)
37 ServantRetentionStrategyRetain::strategy_init (TAO_Root_POA
*poa
)
41 // Create the active object map to be used
42 TAO_Active_Object_Map
*active_object_map
= 0;
43 ACE_NEW_THROW_EX (active_object_map
,
44 TAO_Active_Object_Map (!poa
->system_id (),
45 !poa
->allow_multiple_activations (),
46 poa
->is_persistent (),
47 poa
->orb_core().server_factory ()->active_object_map_creation_parameters ()
48 ), CORBA::NO_MEMORY ());
50 this->active_object_map_
.reset (active_object_map
);
52 #if defined (TAO_HAS_MONITOR_POINTS) && (TAO_HAS_MONITOR_POINTS == 1)
53 ACE_CString
name_str ("Active_Object_Map_");
54 name_str
+= poa
->orb_core ().orbid ();
56 name_str
+= poa
->the_name ();
58 active_object_map
->monitor_
->name (name_str
.c_str ());
59 active_object_map
->monitor_
->add_to_registry ();
60 #endif /* TAO_HAS_MONITOR_POINTS */
64 ServantRetentionStrategyRetain::strategy_cleanup ()
69 ServantRetentionStrategyRetain::deactivate_object (
70 const PortableServer::ObjectId
&id
)
72 TAO_Active_Object_Map_Entry
*active_object_map_entry
= 0;
73 int const result
= this->active_object_map_
->
74 find_entry_using_user_id (id
, active_object_map_entry
);
76 // If there is no active object associated with the specified Object
77 // Id, the operation raises an ObjectNotActive exception.
80 throw PortableServer::POA::ObjectNotActive ();
83 this->deactivate_map_entry (active_object_map_entry
);
87 ServantRetentionStrategyRetain::deactivate_map_entry (
88 TAO_Active_Object_Map_Entry
*active_object_map_entry
)
90 // Decrement the reference count.
91 CORBA::UShort
const new_count
= --active_object_map_entry
->reference_count_
;
93 // Inform the custom servant dispatching (CSD) strategy that the
94 // servant is deactivated. This would be called just once when the
95 // servant is deactivated the first time.
96 if (active_object_map_entry
->deactivated_
== 0)
98 this->poa_
->servant_deactivated_hook (
99 active_object_map_entry
->servant_
,
100 active_object_map_entry
->user_id_
);
105 this->poa_
->cleanup_servant (active_object_map_entry
->servant_
,
106 active_object_map_entry
->user_id_
);
110 // It should be noted that there may be a period of time between
111 // an object's deactivation and the etherealization (during
112 // which outstanding requests are being processed) in which
113 // arriving requests on that object should not be passed to its
114 // servant. During this period, requests targeted for such an
115 // object act as if the POA were in holding state until
116 // etherealize completes. If etherealize is called as a
117 // consequence of a deactivate call with a etherealize_objects
118 // parameter of TRUE, incoming requests are rejected.
120 // Else mark entry as closed...
121 active_object_map_entry
->deactivated_
= 1;
126 ServantRetentionStrategyRetain::unbind_using_user_id (
127 const PortableServer::ObjectId
&user_id
)
129 return this->active_object_map_
->unbind_using_user_id (user_id
);
132 PortableServer::Servant
133 ServantRetentionStrategyRetain::find_servant (
134 const PortableServer::ObjectId
&system_id
)
136 // Find user id from system id.
137 PortableServer::ObjectId_var user_id
;
138 if (active_object_map_
->
139 find_user_id_using_system_id (system_id
, user_id
.out()) != 0)
141 throw ::CORBA::OBJ_ADAPTER ();
144 // This operation returns the active servant associated with the
145 // specified system Object Id value. If the Object Id value is
146 // not active in the POA, an ObjectNotActive exception is
148 TAO_Active_Object_Map_Entry
*entry
= 0;
149 PortableServer::Servant servant
= 0;
153 find_servant_using_system_id_and_user_id (system_id
,
160 throw PortableServer::POA::ObjectNotActive ();
166 PortableServer::ObjectId
*
167 ServantRetentionStrategyRetain::system_id_to_object_id (
168 const PortableServer::ObjectId
&system_id
)
170 // The object denoted by the reference does not have to be
171 // active for this operation to succeed.
172 PortableServer::ObjectId_var user_id
;
173 if (this->active_object_map_
->
174 find_user_id_using_system_id (system_id
,
175 user_id
.out ()) != 0)
177 throw ::CORBA::OBJ_ADAPTER ();
180 return user_id
._retn ();
183 PortableServer::Servant
184 ServantRetentionStrategyRetain::user_id_to_servant (
185 const PortableServer::ObjectId
&id
)
187 // If the POA has the RETAIN policy and the specified ObjectId is in
188 // the Active Object Map, this operation returns the servant
189 // associated with that object in the Active Object Map.
190 PortableServer::Servant servant
= 0;
192 if (this->active_object_map_
->find_servant_using_user_id (id
, servant
) == -1)
194 throw PortableServer::POA::ObjectNotActive ();
201 ServantRetentionStrategyRetain::id_to_reference (
202 const PortableServer::ObjectId
&id
,
205 // If an object with the specified Object Id value is currently
206 // active, a reference encapsulating the information used to
207 // activate the object is returned.
208 PortableServer::ObjectId_var system_id
;
209 PortableServer::Servant servant
;
210 CORBA::Short priority
;
212 if (this->active_object_map_
->
213 find_servant_and_system_id_using_user_id (id
,
218 // Remember params for potentially invoking <key_to_object> later.
219 this->poa_
->key_to_object_params_
.set (system_id
,
220 servant
->_interface_repository_id (),
226 return this->poa_
->invoke_key_to_object_helper_i (servant
->_interface_repository_id (),
231 // If the Object Id value is not active in the POA, an
232 // ObjectNotActive exception is raised.
233 throw PortableServer::POA::ObjectNotActive ();
238 ServantRetentionStrategyRetain::servant_present (
239 const PortableServer::ObjectId
&system_id
,
240 PortableServer::Servant
&servant
)
242 // Find user id from system id.
243 PortableServer::ObjectId_var user_id
;
244 if (this->active_object_map_
->
245 find_user_id_using_system_id (system_id
, user_id
.out()) != 0)
247 throw ::CORBA::OBJ_ADAPTER ();
250 TAO_Active_Object_Map_Entry
*entry
= 0;
251 int const result
= this->active_object_map_
->
252 find_servant_using_system_id_and_user_id (system_id
,
259 return TAO_SERVANT_FOUND
;
263 return TAO_SERVANT_NOT_FOUND
;
267 PortableServer::Servant
268 ServantRetentionStrategyRetain::find_servant (
269 const PortableServer::ObjectId
&system_id
,
270 TAO::Portable_Server::Servant_Upcall
&servant_upcall
,
271 TAO::Portable_Server::POA_Current_Impl
&poa_current_impl
)
273 PortableServer::ObjectId user_id
;
274 // If we have the RETAIN policy, convert/transform from system id to
276 if (this->active_object_map_
->
277 find_user_id_using_system_id (system_id
,
280 throw ::CORBA::OBJ_ADAPTER ();
283 poa_current_impl
.object_id(user_id
);
284 servant_upcall
.user_id (&poa_current_impl
.object_id());
286 // If the POA has the RETAIN policy, the POA looks in the Active
287 // Object Map to find if there is a servant associated with the
288 // Object Id value from the request. If such a servant exists, the
289 // POA invokes the appropriate method on the servant.
290 PortableServer::Servant servant
= 0;
291 TAO_Active_Object_Map_Entry
*active_object_map_entry
= 0;
292 int const result
= this->active_object_map_
->
293 find_servant_using_system_id_and_user_id (system_id
,
296 active_object_map_entry
);
301 servant_upcall
.active_object_map_entry (active_object_map_entry
);
303 // Increment the reference count.
304 servant_upcall
.increment_servant_refcount ();
311 ServantRetentionStrategyRetain::find_servant_priority (
312 const PortableServer::ObjectId
&system_id
,
313 CORBA::Short
&priority
)
315 PortableServer::ObjectId user_id
;
316 // If we have the RETAIN policy, convert/transform from system id to
318 if (this->active_object_map_
->
319 find_user_id_using_system_id (system_id
,
322 throw ::CORBA::OBJ_ADAPTER ();
325 // If the POA has the RETAIN policy, the POA looks in the Active
326 // Object Map to find if there is a servant associated with the
327 // Object Id value from the request. If such a servant exists, the
328 // POA invokes the appropriate method on the servant.
329 PortableServer::Servant servant
= 0;
330 TAO_Active_Object_Map_Entry
*active_object_map_entry
= 0;
331 int const result
= this->active_object_map_
->
332 find_servant_using_system_id_and_user_id (system_id
,
335 active_object_map_entry
);
339 priority
= active_object_map_entry
->priority_
;
347 ServantRetentionStrategyRetain::is_servant_in_map (
348 PortableServer::Servant servant
,
349 bool &wait_occurred_restart_call
)
351 bool deactivated
= false;
353 this->active_object_map_
->is_servant_in_map (servant
, deactivated
);
363 if (TAO_debug_level
> 0)
364 TAOLIB_DEBUG ((LM_DEBUG
,
365 ACE_TEXT ("(%t) TAO_Root_POA::is_servant_in_map: waiting for servant to deactivate\n")));
367 // We are going to wait on this condition variable; the POA
368 // state may change by the time we get the lock again.
369 // Therefore, indicate to the caller that all conditions
370 // need to be checked again.
371 wait_occurred_restart_call
= true;
373 ++this->waiting_servant_deactivation_
;
375 this->poa_
->servant_deactivation_condition ().wait ();
377 --this->waiting_servant_deactivation_
;
389 ServantRetentionStrategyRetain::is_user_id_in_map (
390 const PortableServer::ObjectId
&id
,
391 CORBA::Short priority
,
392 bool &priorities_match
,
393 bool &wait_occurred_restart_call
)
395 bool deactivated
= false;
396 bool user_id_in_map
=
397 this->active_object_map_
->is_user_id_in_map (id
,
410 if (TAO_debug_level
> 0)
411 TAOLIB_DEBUG ((LM_DEBUG
,
412 ACE_TEXT ("(%t) TAO_Root_POA::is_user_id_in_map: waiting for servant to deactivate\n")));
414 // We are going to wait on this condition variable; the POA
415 // state may change by the time we get the lock again.
416 // Therefore, indicate to the caller that all conditions
417 // need to be checked again.
418 wait_occurred_restart_call
= 1;
420 ++this->waiting_servant_deactivation_
;
422 this->poa_
->servant_deactivation_condition ().wait ();
424 --this->waiting_servant_deactivation_
;
436 ServantRetentionStrategyRetain::waiting_servant_deactivation () const
438 return waiting_servant_deactivation_
;
442 ServantRetentionStrategyRetain::deactivate_all_objects ()
444 // If the etherealize_objects parameter is TRUE, the POA has the
445 // RETAIN policy, and a servant manager is registered with the POA,
446 // the etherealize operation on the servant manager will be called
447 // for each active object in the Active Object Map. The apparent
448 // destruction of the POA occurs before any calls to etherealize are
449 // made. Thus, for example, an etherealize method that attempts to
450 // invoke operations on the POA will receive the OBJECT_NOT_EXIST
453 // We must copy the map entries into a separate place since we
454 // cannot remove entries while iterating through the map.
455 ACE_Array_Base
<TAO_Active_Object_Map_Entry
*> map_entries
456 (this->active_object_map_
->current_size ());
459 TAO_Active_Object_Map::user_id_map::iterator end
460 = this->active_object_map_
->user_id_map_
->end ();
462 for (TAO_Active_Object_Map::user_id_map::iterator iter
463 = this->active_object_map_
->user_id_map_
->begin ();
467 TAO_Active_Object_Map::user_id_map::value_type map_pair
= *iter
;
468 TAO_Active_Object_Map_Entry
*active_object_map_entry
= map_pair
.second ();
470 if (!active_object_map_entry
->deactivated_
)
472 map_entries
[counter
] = active_object_map_entry
;
481 this->deactivate_map_entry (map_entries
[i
]);
485 PortableServer::ObjectId
*
486 ServantRetentionStrategyRetain::servant_to_user_id (
487 PortableServer::Servant servant
)
489 // This operation requires the RETAIN and either the UNIQUE_ID or
490 // IMPLICIT_ACTIVATION policies; if not present, the WrongPolicy
491 // exception is raised.
492 if (!((!this->poa_
->allow_multiple_activations ()
493 || this->poa_
->allow_implicit_activation ())))
495 throw PortableServer::POA::WrongPolicy ();
499 * If the POA has both the RETAIN and the UNIQUE_ID policy and the
500 * specified servant is active, the Object Id associated with that
501 * servant is returned.
503 * If the POA has both the RETAIN and the IMPLICIT_ACTIVATION policy and
504 * either the POA has the MULTIPLE_ID policy or the specified servant is
505 * not active, the servant is activated using a POA-generated Object Id
506 * and the Interface Id associated with the servant, and that Object Id
511 // If the POA has the UNIQUE_ID policy and the specified servant is
512 // active, the Object Id associated with that servant is returned.
513 PortableServer::ObjectId_var user_id
;
514 if (!this->poa_
->allow_multiple_activations () &&
515 this->active_object_map_
->
516 find_user_id_using_servant (servant
, user_id
.out ()) != -1)
518 return user_id
._retn ();
521 // If the POA has the IMPLICIT_ACTIVATION policy and either the POA
522 // has the MULTIPLE_ID policy or the specified servant is not
523 // active, the servant is activated using a POA-generated Object Id
524 // and the Interface Id associated with the servant, and that Object
526 if (this->poa_
->allow_implicit_activation ())
528 // If we reach here, then we either have the MULTIPLE_ID policy
529 // or we have the UNIQUE_ID policy and we are not in the active
531 PortableServer::ObjectId_var user_id
;
532 if (this->active_object_map_
->
533 bind_using_system_id_returning_user_id (servant
,
534 this->poa_
->server_priority (),
535 user_id
.out ()) != 0)
537 throw ::CORBA::OBJ_ADAPTER ();
541 // Everything is finally ok
544 // Inform the custom servant dispatching (CSD) strategy that the
545 // sevant is activated.
546 this->poa_
->servant_activated_hook (servant
, user_id
.in ());
548 // ATTENTION: Trick locking here, see class header for details
549 Non_Servant_Upcall
non_servant_upcall (*this->poa_
);
550 ACE_UNUSED_ARG (non_servant_upcall
);
552 // If this operation causes the object to be activated, _add_ref
553 // is invoked at least once on the Servant argument before
554 // returning. Otherwise, the POA does not increment or decrement
555 // the reference count of the Servant passed to this function.
556 servant
->_add_ref ();
558 return user_id
._retn ();
562 * Otherwise, the ServantNotActive exception is raised.
564 throw PortableServer::POA::ServantNotActive ();
567 PortableServer::ObjectId
*
568 ServantRetentionStrategyRetain::servant_to_system_id_i (
569 PortableServer::Servant servant
,
570 CORBA::Short
&priority
)
572 // This operation requires the RETAIN and either the UNIQUE_ID or
573 // IMPLICIT_ACTIVATION policies; if not present, the WrongPolicy
574 // exception is raised.
575 if (!((!this->poa_
->allow_multiple_activations ()
576 || this->poa_
->allow_implicit_activation ())))
578 throw PortableServer::POA::WrongPolicy ();
581 // This operation has three possible behaviors.
583 // If the POA has the UNIQUE_ID policy and the specified servant is
584 // active, the Object Id associated with that servant is returned.
585 PortableServer::ObjectId_var system_id
;
586 if (!this->poa_
->allow_multiple_activations () &&
587 this->active_object_map_
->
588 find_system_id_using_servant (servant
,
592 return system_id
._retn ();
595 #if defined (CORBA_E_COMPACT) || defined (CORBA_E_MICRO)
596 // CORBA e does not allow implicit activation.
597 // At this point we can throw the WrongPolicy exception.
598 throw PortableServer::POA::WrongPolicy ();
599 #endif /* CORBA_E_COMPACT || CORBA_E_MICRO */
601 // If the POA has the IMPLICIT_ACTIVATION policy and either the POA
602 // has the MULTIPLE_ID policy or the specified servant is not
603 // active, the servant is activated using a POA-generated Object Id
604 // and the Interface Id associated with the servant, and that Object
606 if (this->poa_
->allow_implicit_activation ())
608 // If we reach here, then we either have the MULTIPLE_ID policy
609 // or we have the UNIQUE_ID policy and we are not in the active
611 PortableServer::ObjectId_var system_id
;
612 if (this->active_object_map_
->
613 bind_using_system_id_returning_system_id (servant
,
615 system_id
.out ()) != 0)
617 throw ::CORBA::OBJ_ADAPTER ();
621 // Everything is finally ok
624 // Inform the custom servant dispatching (CSD) strategy that the
625 // sevant is activated.
626 this->poa_
->servant_activated_hook (servant
, system_id
.in ());
628 // ATTENTION: Trick locking here, see class header for details
629 Non_Servant_Upcall
non_servant_upcall (*this->poa_
);
630 ACE_UNUSED_ARG (non_servant_upcall
);
632 // If this operation causes the object to be activated, _add_ref
633 // is invoked at least once on the Servant argument before
634 // returning. Otherwise, the POA does not increment or decrement
635 // the reference count of the Servant passed to this function.
636 servant
->_add_ref ();
638 return system_id
._retn ();
641 // Otherwise, the ServantNotActive exception is raised.
642 throw PortableServer::POA::ServantNotActive ();
646 ServantRetentionStrategyRetain::servant_to_reference (
647 PortableServer::Servant servant
)
649 // Note: The allocation of an Object Id value and installation in
650 // the Active Object Map caused by implicit activation may actually
651 // be deferred until an attempt is made to externalize the
652 // reference. The real requirement here is that a reference is
653 // produced that will behave appropriately (that is, yield a
654 // consistent Object Id value when asked politely).
655 CORBA::Short priority
= this->poa_
->server_priority ();
657 PortableServer::ObjectId_var system_id
=
658 this->servant_to_system_id_i (servant
, priority
);
660 PortableServer::ObjectId user_id
;
662 // This operation requires the RETAIN, therefore don't worry about
663 // the NON_RETAIN case.
664 if (this->active_object_map_
->
665 find_user_id_using_system_id (system_id
.in (), user_id
) != 0)
667 throw ::CORBA::OBJ_ADAPTER ();
670 // Remember params for potentially invoking <key_to_object> later.
671 this->poa_
->key_to_object_params_
.set (
673 servant
->_interface_repository_id (),
679 // Ask the ORT to create the object.
680 // @@NOTE:There is a possible deadlock lurking here. We held the
681 // lock, and we are possibly trying to make a call into the
682 // application code. Think what would happen if the app calls us
683 // back. We need to get to this at some point.
684 return this->poa_
->invoke_key_to_object_helper_i (
685 servant
->_interface_repository_id (), user_id
);
688 PortableServer::ObjectId
*
689 ServantRetentionStrategyRetain::activate_object (
690 PortableServer::Servant servant
,
691 CORBA::Short priority
,
692 bool &wait_occurred_restart_call
)
694 if (!this->poa_
->has_system_id ())
696 throw PortableServer::POA::WrongPolicy ();
700 this->poa_
->is_servant_activation_allowed (servant
, wait_occurred_restart_call
);
704 if (wait_occurred_restart_call
)
710 throw PortableServer::POA::ServantAlreadyActive ();
714 // Otherwise, the activate_object operation generates an Object Id
715 // and enters the Object Id and the specified servant in the Active
716 // Object Map. The Object Id is returned.
717 PortableServer::ObjectId_var user_id
;
718 if (this->active_object_map_
->
719 bind_using_system_id_returning_user_id (servant
,
721 user_id
.out ()) != 0)
723 throw ::CORBA::OBJ_ADAPTER ();
727 // Everything is finally ok
730 // Inform the custom servant dispatching (CSD) strategy that the
731 // sevant is activated.
732 this->poa_
->servant_activated_hook (servant
, user_id
.in ());
734 // ATTENTION: Trick locking here, see class header for details
735 Non_Servant_Upcall
non_servant_upcall (*this->poa_
);
736 ACE_UNUSED_ARG (non_servant_upcall
);
738 // The implementation of activate_object will invoke _add_ref at
739 // least once on the Servant argument before returning. When the POA
740 // no longer needs the Servant, it will invoke _remove_ref on it the
741 // same number of times.
742 servant
->_add_ref ();
744 return user_id
._retn ();
748 ServantRetentionStrategyRetain::activate_object_with_id (
749 const PortableServer::ObjectId
&id
,
750 PortableServer::Servant servant
,
751 CORBA::Short priority
,
752 bool &wait_occurred_restart_call
)
754 // If the POA has the SYSTEM_ID policy and it detects that the
755 // Object Id value was not generated by the system or for this POA,
756 // the activate_object_with_id operation may raise the BAD_PARAM
757 // system exception. An ORB is not required to detect all such
758 // invalid Object Id values, but a portable application must not
759 // invoke activate_object_with_id on a POA that has the SYSTEM_ID
760 // policy with an Object Id value that was not previously generated
761 // by the system for that POA, or, if the POA also has the
762 // PERSISTENT policy, for a previous instantiation of the same POA.
763 if (this->poa_
->has_system_id () &&
764 !this->poa_
->is_poa_generated_id (id
))
766 throw ::CORBA::BAD_PARAM ();
769 // If the CORBA object denoted by the Object Id value is already
770 // active in this POA (there is a servant bound to it in the Active
771 // Object Map), the ObjectAlreadyActive exception is raised.
772 bool priorities_match
= true;
774 this->is_user_id_in_map (id
,
777 wait_occurred_restart_call
);
779 // @johnny the implementation is not complete, this does the spec also say
780 // If the POA has the UNIQUE_ID policy and the servant is already
781 // in the Active Object Map, the ServantAlreadyActive exception is raised.
784 throw PortableServer::POA::ObjectAlreadyActive ();
786 else if (wait_occurred_restart_call
)
788 // We ended up waiting on a condition variable, the POA state
789 // may have changed while we are waiting. Therefore, we need to
790 // restart this call.
794 // If the activate_object_with_id_and_priority operation is invoked
795 // with a different priority to an earlier invocation of one of the
796 // create reference with priority operations, for the same object,
797 // then the ORB shall raise a BAD_INV_ORDER system exception (with a
798 // Standard Minor Exception Code of 1). If the priority value is the
799 // same then the ORB shall return SUCCESS.
800 if (!priorities_match
)
802 throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID
| 1,
803 CORBA::COMPLETED_NO
);
806 bool const may_activate
=
807 this->poa_
->is_servant_activation_allowed (servant
, wait_occurred_restart_call
);
811 if (wait_occurred_restart_call
)
817 throw PortableServer::POA::ServantAlreadyActive ();
821 // Otherwise, the activate_object_with_id operation enters an
822 // association between the specified Object Id and the specified
823 // servant in the Active Object Map.
824 if (this->active_object_map_
->bind_using_user_id (servant
,
828 throw ::CORBA::OBJ_ADAPTER ();
832 // Everything is finally ok
835 // Inform the custom servant dispatching (CSD) strategy that the
836 // sevant is activated.
837 this->poa_
->servant_activated_hook (servant
, id
);
839 // ATTENTION: Trick locking here, see class header for details
840 Non_Servant_Upcall
non_servant_upcall (*this->poa_
);
841 ACE_UNUSED_ARG (non_servant_upcall
);
843 // The implementation of activate_object_with_id will invoke
844 // _add_ref at least once on the Servant argument before
845 // returning. When the POA no longer needs the Servant, it will
846 // invoke _remove_ref on it the same number of times.
847 servant
->_add_ref ();
851 ServantRetentionStrategyRetain::create_reference (
853 CORBA::Short priority
)
855 // This operation creates an object reference that encapsulates a
856 // POA-generated Object Id value and the specified interface
857 // repository id. This operation does not cause an activation to
858 // take place. The resulting reference may be passed to clients, so
859 // that subsequent requests on those references will cause the
860 // appropriate servant manager to be invoked, if one is
861 // available. The generated Object Id value may be obtained by
862 // invoking POA::reference_to_id with the created reference.
864 PortableServer::ObjectId_var system_id
;
865 PortableServer::ObjectId user_id
;
867 if (this->active_object_map_
->
868 bind_using_system_id_returning_system_id (0,
870 system_id
.out ()) != 0)
872 throw ::CORBA::OBJ_ADAPTER ();
875 // Find user id from system id.
876 if (this->active_object_map_
->
877 find_user_id_using_system_id (system_id
.in (),
880 throw ::CORBA::OBJ_ADAPTER ();
883 // Remember params for potentially invoking <key_to_object> later.
884 this->poa_
->key_to_object_params_
.set (system_id
,
891 return this->poa_
->invoke_key_to_object_helper_i (intf
,
895 #if !defined (CORBA_E_MICRO)
897 ServantRetentionStrategyRetain::create_reference_with_id (
898 const PortableServer::ObjectId
&oid
,
900 CORBA::Short priority
)
902 // This operation creates an object reference that encapsulates the
903 // specified Object Id and interface repository Id values. This
904 // operation does not cause an activation to take place. The
905 // resulting reference may be passed to clients, so that subsequent
906 // requests on those references will cause the object to be
907 // activated if necessary, or the default servant used, depending on
908 // the applicable policies.
910 PortableServer::Servant servant
= 0;
911 PortableServer::ObjectId_var system_id
;
913 // @@ We need something that can find the system id using
914 // appropriate strategy, at the same time, return the servant if
915 // one is available. Before we have that function,
916 // <create_reference_with_id_i> basically generates broken
917 // collocated object when DIRECT collocation strategy is used.
919 if (this->active_object_map_
->
920 find_system_id_using_user_id (oid
,
922 system_id
.out ()) != 0)
924 throw ::CORBA::OBJ_ADAPTER ();
927 // Remember params for potentially invoking <key_to_object> later.
928 this->poa_
->key_to_object_params_
.set (system_id
,
935 return this->poa_
->invoke_key_to_object_helper_i (intf
, oid
);
940 ServantRetentionStrategyRetain::rebind_using_user_id_and_system_id (
941 PortableServer::Servant servant
,
942 const PortableServer::ObjectId
&user_id
,
943 const PortableServer::ObjectId
&system_id
,
944 TAO::Portable_Server::Servant_Upcall
&servant_upcall
)
946 TAO_Active_Object_Map_Entry
*entry
= 0;
947 int result
= this->active_object_map_
->
948 rebind_using_user_id_and_system_id (servant
,
952 servant_upcall
.active_object_map_entry(entry
);
958 ServantRetentionStrategyRetain::servant_has_remaining_activations (
959 PortableServer::Servant servant
)
961 return this->active_object_map_
->remaining_activations (servant
);
965 ::PortableServer::ServantRetentionPolicyValue
966 ServantRetentionStrategyRetain::type() const
968 return ::PortableServer::RETAIN
;
971 TAO_Active_Object_Map
*
972 ServantRetentionStrategyRetain::get_active_object_map() const
974 return this->active_object_map_
.get();
980 TAO_END_VERSIONED_NAMESPACE_DECL