Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / PortableServer / ServantRetentionStrategyRetain.cpp
blob292e13dfcd27b8301a3c4ff6bb3281f2af35b12d
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file ServantRetentionStrategyRetain.cpp
6 */
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
25 namespace TAO
27 namespace Portable_Server
29 void
30 ServantRetentionStrategyRetain::strategy_init (TAO_Root_POA *poa)
32 poa_ = poa;
34 // Create the active object map to be used
35 TAO_Active_Object_Map *active_object_map = 0;
36 ACE_NEW_THROW_EX (active_object_map,
37 TAO_Active_Object_Map (!poa->system_id (),
38 !poa->allow_multiple_activations (),
39 poa->is_persistent (),
40 poa->orb_core().server_factory ()->active_object_map_creation_parameters ()
41 ), CORBA::NO_MEMORY ());
43 this->active_object_map_.reset (active_object_map);
45 #if defined (TAO_HAS_MONITOR_POINTS) && (TAO_HAS_MONITOR_POINTS == 1)
46 ACE_CString name_str ("Active_Object_Map_");
47 name_str += poa->orb_core ().orbid ();
48 name_str += '_';
49 name_str += poa->the_name ();
51 active_object_map->monitor_->name (name_str.c_str ());
52 active_object_map->monitor_->add_to_registry ();
53 #endif /* TAO_HAS_MONITOR_POINTS */
56 void
57 ServantRetentionStrategyRetain::strategy_cleanup ()
61 void
62 ServantRetentionStrategyRetain::deactivate_object (
63 const PortableServer::ObjectId &id)
65 TAO_Active_Object_Map_Entry *active_object_map_entry = 0;
66 int const result = this->active_object_map_->
67 find_entry_using_user_id (id, active_object_map_entry);
69 // If there is no active object associated with the specified Object
70 // Id, the operation raises an ObjectNotActive exception.
71 if (result != 0)
73 throw PortableServer::POA::ObjectNotActive ();
76 this->deactivate_map_entry (active_object_map_entry);
79 void
80 ServantRetentionStrategyRetain::deactivate_map_entry (
81 TAO_Active_Object_Map_Entry *active_object_map_entry)
83 // Decrement the reference count.
84 CORBA::UShort const new_count = --active_object_map_entry->reference_count_;
86 // Inform the custom servant dispatching (CSD) strategy that the
87 // servant is deactivated. This would be called just once when the
88 // servant is deactivated the first time.
89 if (active_object_map_entry->deactivated_ == 0)
91 this->poa_->servant_deactivated_hook (
92 active_object_map_entry->servant_,
93 active_object_map_entry->user_id_);
96 if (new_count == 0)
98 this->poa_->cleanup_servant (active_object_map_entry->servant_,
99 active_object_map_entry->user_id_);
101 else
103 // It should be noted that there may be a period of time between
104 // an object's deactivation and the etherealization (during
105 // which outstanding requests are being processed) in which
106 // arriving requests on that object should not be passed to its
107 // servant. During this period, requests targeted for such an
108 // object act as if the POA were in holding state until
109 // etherealize completes. If etherealize is called as a
110 // consequence of a deactivate call with a etherealize_objects
111 // parameter of TRUE, incoming requests are rejected.
113 // Else mark entry as closed...
114 active_object_map_entry->deactivated_ = 1;
119 ServantRetentionStrategyRetain::unbind_using_user_id (
120 const PortableServer::ObjectId &user_id)
122 return this->active_object_map_->unbind_using_user_id (user_id);
125 PortableServer::Servant
126 ServantRetentionStrategyRetain::find_servant (
127 const PortableServer::ObjectId &system_id)
129 // Find user id from system id.
130 PortableServer::ObjectId_var user_id;
131 if (active_object_map_->
132 find_user_id_using_system_id (system_id, user_id.out()) != 0)
134 throw ::CORBA::OBJ_ADAPTER ();
137 // This operation returns the active servant associated with the
138 // specified system Object Id value. If the Object Id value is
139 // not active in the POA, an ObjectNotActive exception is
140 // raised.
141 TAO_Active_Object_Map_Entry *entry = 0;
142 PortableServer::Servant servant = 0;
144 int const result =
145 active_object_map_->
146 find_servant_using_system_id_and_user_id (system_id,
147 user_id.in(),
148 servant,
149 entry);
151 if (result == -1)
153 throw PortableServer::POA::ObjectNotActive ();
156 return servant;
159 PortableServer::ObjectId *
160 ServantRetentionStrategyRetain::system_id_to_object_id (
161 const PortableServer::ObjectId &system_id)
163 // The object denoted by the reference does not have to be
164 // active for this operation to succeed.
165 PortableServer::ObjectId_var user_id;
166 if (this->active_object_map_->
167 find_user_id_using_system_id (system_id,
168 user_id.out ()) != 0)
170 throw ::CORBA::OBJ_ADAPTER ();
173 return user_id._retn ();
176 PortableServer::Servant
177 ServantRetentionStrategyRetain::user_id_to_servant (
178 const PortableServer::ObjectId &id)
180 // If the POA has the RETAIN policy and the specified ObjectId is in
181 // the Active Object Map, this operation returns the servant
182 // associated with that object in the Active Object Map.
183 PortableServer::Servant servant = 0;
185 if (this->active_object_map_->find_servant_using_user_id (id, servant) == -1)
187 throw PortableServer::POA::ObjectNotActive ();
190 return servant;
193 CORBA::Object_ptr
194 ServantRetentionStrategyRetain::id_to_reference (
195 const PortableServer::ObjectId &id,
196 bool indirect)
198 // If an object with the specified Object Id value is currently
199 // active, a reference encapsulating the information used to
200 // activate the object is returned.
201 PortableServer::ObjectId_var system_id;
202 PortableServer::Servant servant;
203 CORBA::Short priority;
205 if (this->active_object_map_->
206 find_servant_and_system_id_using_user_id (id,
207 servant,
208 system_id.out (),
209 priority) == 0)
211 // Remember params for potentially invoking <key_to_object> later.
212 this->poa_->key_to_object_params_.set (system_id,
213 servant->_interface_repository_id (),
214 servant,
216 priority,
217 indirect);
219 return this->poa_->invoke_key_to_object_helper_i (servant->_interface_repository_id (),
220 id);
222 else
224 // If the Object Id value is not active in the POA, an
225 // ObjectNotActive exception is raised.
226 throw PortableServer::POA::ObjectNotActive ();
230 TAO_Servant_Location
231 ServantRetentionStrategyRetain::servant_present (
232 const PortableServer::ObjectId &system_id,
233 PortableServer::Servant &servant)
235 // Find user id from system id.
236 PortableServer::ObjectId_var user_id;
237 if (this->active_object_map_->
238 find_user_id_using_system_id (system_id, user_id.out()) != 0)
240 throw ::CORBA::OBJ_ADAPTER ();
243 TAO_Active_Object_Map_Entry *entry = 0;
244 int const result = this->active_object_map_->
245 find_servant_using_system_id_and_user_id (system_id,
246 user_id.in(),
247 servant,
248 entry);
249 if (result == 0)
251 // Success
252 return TAO_Servant_Location::Found;
254 else
256 return TAO_Servant_Location::Not_Found;
260 PortableServer::Servant
261 ServantRetentionStrategyRetain::find_servant (
262 const PortableServer::ObjectId &system_id,
263 TAO::Portable_Server::Servant_Upcall &servant_upcall,
264 TAO::Portable_Server::POA_Current_Impl &poa_current_impl)
266 PortableServer::ObjectId user_id;
267 // If we have the RETAIN policy, convert/transform from system id to
268 // user id.
269 if (this->active_object_map_->
270 find_user_id_using_system_id (system_id,
271 user_id) != 0)
273 throw ::CORBA::OBJ_ADAPTER ();
276 poa_current_impl.object_id(user_id);
277 servant_upcall.user_id (&poa_current_impl.object_id());
279 // If the POA has the RETAIN policy, the POA looks in the Active
280 // Object Map to find if there is a servant associated with the
281 // Object Id value from the request. If such a servant exists, the
282 // POA invokes the appropriate method on the servant.
283 PortableServer::Servant servant = 0;
284 TAO_Active_Object_Map_Entry *active_object_map_entry = 0;
285 int const result = this->active_object_map_->
286 find_servant_using_system_id_and_user_id (system_id,
287 user_id,
288 servant,
289 active_object_map_entry);
292 if (result == 0)
294 servant_upcall.active_object_map_entry (active_object_map_entry);
296 // Increment the reference count.
297 servant_upcall.increment_servant_refcount ();
300 return servant;
304 ServantRetentionStrategyRetain::find_servant_priority (
305 const PortableServer::ObjectId &system_id,
306 CORBA::Short &priority)
308 PortableServer::ObjectId user_id;
309 // If we have the RETAIN policy, convert/transform from system id to
310 // user id.
311 if (this->active_object_map_->
312 find_user_id_using_system_id (system_id,
313 user_id) != 0)
315 throw ::CORBA::OBJ_ADAPTER ();
318 // If the POA has the RETAIN policy, the POA looks in the Active
319 // Object Map to find if there is a servant associated with the
320 // Object Id value from the request. If such a servant exists, the
321 // POA invokes the appropriate method on the servant.
322 PortableServer::Servant servant = 0;
323 TAO_Active_Object_Map_Entry *active_object_map_entry = 0;
324 int const result = this->active_object_map_->
325 find_servant_using_system_id_and_user_id (system_id,
326 user_id,
327 servant,
328 active_object_map_entry);
330 if (result == 0)
332 priority = active_object_map_entry->priority_;
333 return 0;
336 return -1;
340 ServantRetentionStrategyRetain::is_servant_in_map (
341 PortableServer::Servant servant,
342 bool &wait_occurred_restart_call)
344 bool deactivated = false;
345 int servant_in_map =
346 this->active_object_map_->is_servant_in_map (servant, deactivated);
348 if (!servant_in_map)
350 return 0;
352 else
354 if (deactivated)
356 if (TAO_debug_level > 0)
357 TAOLIB_DEBUG ((LM_DEBUG,
358 ACE_TEXT ("(%t) TAO_Root_POA::is_servant_in_map: waiting for servant to deactivate\n")));
360 // We are going to wait on this condition variable; the POA
361 // state may change by the time we get the lock again.
362 // Therefore, indicate to the caller that all conditions
363 // need to be checked again.
364 wait_occurred_restart_call = true;
366 ++this->waiting_servant_deactivation_;
368 this->poa_->servant_deactivation_condition ().wait ();
370 --this->waiting_servant_deactivation_;
372 return 0;
374 else
376 return 1;
382 ServantRetentionStrategyRetain::is_user_id_in_map (
383 const PortableServer::ObjectId &id,
384 CORBA::Short priority,
385 bool &priorities_match,
386 bool &wait_occurred_restart_call)
388 bool deactivated = false;
389 bool user_id_in_map =
390 this->active_object_map_->is_user_id_in_map (id,
391 priority,
392 priorities_match,
393 deactivated);
395 if (!user_id_in_map)
397 return 0;
399 else
401 if (deactivated)
403 if (TAO_debug_level > 0)
404 TAOLIB_DEBUG ((LM_DEBUG,
405 ACE_TEXT ("(%t) TAO_Root_POA::is_user_id_in_map: waiting for servant to deactivate\n")));
407 // We are going to wait on this condition variable; the POA
408 // state may change by the time we get the lock again.
409 // Therefore, indicate to the caller that all conditions
410 // need to be checked again.
411 wait_occurred_restart_call = 1;
413 ++this->waiting_servant_deactivation_;
415 this->poa_->servant_deactivation_condition ().wait ();
417 --this->waiting_servant_deactivation_;
419 return 0;
421 else
423 return 1;
428 CORBA::ULong
429 ServantRetentionStrategyRetain::waiting_servant_deactivation () const
431 return waiting_servant_deactivation_;
434 void
435 ServantRetentionStrategyRetain::deactivate_all_objects ()
437 // If the etherealize_objects parameter is TRUE, the POA has the
438 // RETAIN policy, and a servant manager is registered with the POA,
439 // the etherealize operation on the servant manager will be called
440 // for each active object in the Active Object Map. The apparent
441 // destruction of the POA occurs before any calls to etherealize are
442 // made. Thus, for example, an etherealize method that attempts to
443 // invoke operations on the POA will receive the OBJECT_NOT_EXIST
444 // exception.
446 // We must copy the map entries into a separate place since we
447 // cannot remove entries while iterating through the map.
448 ACE_Array_Base<TAO_Active_Object_Map_Entry *> map_entries
449 (this->active_object_map_->current_size ());
451 size_t counter = 0;
452 TAO_Active_Object_Map::user_id_map::iterator end
453 = this->active_object_map_->user_id_map_->end ();
455 for (TAO_Active_Object_Map::user_id_map::iterator iter
456 = this->active_object_map_->user_id_map_->begin ();
457 iter != end;
458 ++iter)
460 TAO_Active_Object_Map::user_id_map::value_type map_pair = *iter;
461 TAO_Active_Object_Map_Entry *active_object_map_entry = map_pair.second ();
463 if (!active_object_map_entry->deactivated_)
465 map_entries[counter] = active_object_map_entry;
466 ++counter;
470 for (size_t i = 0;
471 i < counter;
472 ++i)
474 this->deactivate_map_entry (map_entries[i]);
478 PortableServer::ObjectId *
479 ServantRetentionStrategyRetain::servant_to_user_id (
480 PortableServer::Servant servant)
482 // This operation requires the RETAIN and either the UNIQUE_ID or
483 // IMPLICIT_ACTIVATION policies; if not present, the WrongPolicy
484 // exception is raised.
485 if (!((!this->poa_->allow_multiple_activations ()
486 || this->poa_->allow_implicit_activation ())))
488 throw PortableServer::POA::WrongPolicy ();
492 * If the POA has both the RETAIN and the UNIQUE_ID policy and the
493 * specified servant is active, the Object Id associated with that
494 * servant is returned.
496 * If the POA has both the RETAIN and the IMPLICIT_ACTIVATION policy and
497 * either the POA has the MULTIPLE_ID policy or the specified servant is
498 * not active, the servant is activated using a POA-generated Object Id
499 * and the Interface Id associated with the servant, and that Object Id
500 * is returned.
504 // If the POA has the UNIQUE_ID policy and the specified servant is
505 // active, the Object Id associated with that servant is returned.
506 PortableServer::ObjectId_var user_id;
507 if (!this->poa_->allow_multiple_activations () &&
508 this->active_object_map_->
509 find_user_id_using_servant (servant, user_id.out ()) != -1)
511 return user_id._retn ();
514 // If the POA has the IMPLICIT_ACTIVATION policy and either the POA
515 // has the MULTIPLE_ID policy or the specified servant is not
516 // active, the servant is activated using a POA-generated Object Id
517 // and the Interface Id associated with the servant, and that Object
518 // Id is returned.
519 if (this->poa_->allow_implicit_activation ())
521 // If we reach here, then we either have the MULTIPLE_ID policy
522 // or we have the UNIQUE_ID policy and we are not in the active
523 // object map.
524 PortableServer::ObjectId_var user_id;
525 if (this->active_object_map_->
526 bind_using_system_id_returning_user_id (servant,
527 this->poa_->server_priority (),
528 user_id.out ()) != 0)
530 throw ::CORBA::OBJ_ADAPTER ();
534 // Everything is finally ok
537 // Inform the custom servant dispatching (CSD) strategy that the
538 // sevant is activated.
539 this->poa_->servant_activated_hook (servant, user_id.in ());
541 // ATTENTION: Trick locking here, see class header for details
542 Non_Servant_Upcall non_servant_upcall (*this->poa_);
543 ACE_UNUSED_ARG (non_servant_upcall);
545 // If this operation causes the object to be activated, _add_ref
546 // is invoked at least once on the Servant argument before
547 // returning. Otherwise, the POA does not increment or decrement
548 // the reference count of the Servant passed to this function.
549 servant->_add_ref ();
551 return user_id._retn ();
555 * Otherwise, the ServantNotActive exception is raised.
557 throw PortableServer::POA::ServantNotActive ();
560 PortableServer::ObjectId *
561 ServantRetentionStrategyRetain::servant_to_system_id_i (
562 PortableServer::Servant servant,
563 CORBA::Short &priority)
565 // This operation requires the RETAIN and either the UNIQUE_ID or
566 // IMPLICIT_ACTIVATION policies; if not present, the WrongPolicy
567 // exception is raised.
568 if (!((!this->poa_->allow_multiple_activations ()
569 || this->poa_->allow_implicit_activation ())))
571 throw PortableServer::POA::WrongPolicy ();
574 // This operation has three possible behaviors.
576 // If the POA has the UNIQUE_ID policy and the specified servant is
577 // active, the Object Id associated with that servant is returned.
578 PortableServer::ObjectId_var system_id;
579 if (!this->poa_->allow_multiple_activations () &&
580 this->active_object_map_->
581 find_system_id_using_servant (servant,
582 system_id.out (),
583 priority) != -1)
585 return system_id._retn ();
588 #if defined (CORBA_E_COMPACT) || defined (CORBA_E_MICRO)
589 // CORBA e does not allow implicit activation.
590 // At this point we can throw the WrongPolicy exception.
591 throw PortableServer::POA::WrongPolicy ();
592 #endif /* CORBA_E_COMPACT || CORBA_E_MICRO */
594 // If the POA has the IMPLICIT_ACTIVATION policy and either the POA
595 // has the MULTIPLE_ID policy or the specified servant is not
596 // active, the servant is activated using a POA-generated Object Id
597 // and the Interface Id associated with the servant, and that Object
598 // Id is returned.
599 if (this->poa_->allow_implicit_activation ())
601 // If we reach here, then we either have the MULTIPLE_ID policy
602 // or we have the UNIQUE_ID policy and we are not in the active
603 // object map.
604 PortableServer::ObjectId_var system_id;
605 if (this->active_object_map_->
606 bind_using_system_id_returning_system_id (servant,
607 priority,
608 system_id.out ()) != 0)
610 throw ::CORBA::OBJ_ADAPTER ();
614 // Everything is finally ok
617 // Inform the custom servant dispatching (CSD) strategy that the
618 // sevant is activated.
619 this->poa_->servant_activated_hook (servant, system_id.in ());
621 // ATTENTION: Trick locking here, see class header for details
622 Non_Servant_Upcall non_servant_upcall (*this->poa_);
623 ACE_UNUSED_ARG (non_servant_upcall);
625 // If this operation causes the object to be activated, _add_ref
626 // is invoked at least once on the Servant argument before
627 // returning. Otherwise, the POA does not increment or decrement
628 // the reference count of the Servant passed to this function.
629 servant->_add_ref ();
631 return system_id._retn ();
634 // Otherwise, the ServantNotActive exception is raised.
635 throw PortableServer::POA::ServantNotActive ();
638 CORBA::Object_ptr
639 ServantRetentionStrategyRetain::servant_to_reference (
640 PortableServer::Servant servant)
642 // Note: The allocation of an Object Id value and installation in
643 // the Active Object Map caused by implicit activation may actually
644 // be deferred until an attempt is made to externalize the
645 // reference. The real requirement here is that a reference is
646 // produced that will behave appropriately (that is, yield a
647 // consistent Object Id value when asked politely).
648 CORBA::Short priority = this->poa_->server_priority ();
650 PortableServer::ObjectId_var system_id =
651 this->servant_to_system_id_i (servant, priority);
653 PortableServer::ObjectId user_id;
655 // This operation requires the RETAIN, therefore don't worry about
656 // the NON_RETAIN case.
657 if (this->active_object_map_->
658 find_user_id_using_system_id (system_id.in (), user_id) != 0)
660 throw ::CORBA::OBJ_ADAPTER ();
663 // Remember params for potentially invoking <key_to_object> later.
664 this->poa_->key_to_object_params_.set (
665 system_id,
666 servant->_interface_repository_id (),
667 servant,
669 priority,
670 true);
672 // Ask the ORT to create the object.
673 // @@NOTE:There is a possible deadlock lurking here. We held the
674 // lock, and we are possibly trying to make a call into the
675 // application code. Think what would happen if the app calls us
676 // back. We need to get to this at some point.
677 return this->poa_->invoke_key_to_object_helper_i (
678 servant->_interface_repository_id (), user_id);
681 PortableServer::ObjectId *
682 ServantRetentionStrategyRetain::activate_object (
683 PortableServer::Servant servant,
684 CORBA::Short priority,
685 bool &wait_occurred_restart_call)
687 if (!this->poa_->has_system_id ())
689 throw PortableServer::POA::WrongPolicy ();
692 bool may_activate =
693 this->poa_->is_servant_activation_allowed (servant, wait_occurred_restart_call);
695 if (!may_activate)
697 if (wait_occurred_restart_call)
699 return 0;
701 else
703 throw PortableServer::POA::ServantAlreadyActive ();
707 // Otherwise, the activate_object operation generates an Object Id
708 // and enters the Object Id and the specified servant in the Active
709 // Object Map. The Object Id is returned.
710 PortableServer::ObjectId_var user_id;
711 if (this->active_object_map_->
712 bind_using_system_id_returning_user_id (servant,
713 priority,
714 user_id.out ()) != 0)
716 throw ::CORBA::OBJ_ADAPTER ();
720 // Everything is finally ok
723 // Inform the custom servant dispatching (CSD) strategy that the
724 // sevant is activated.
725 this->poa_->servant_activated_hook (servant, user_id.in ());
727 // ATTENTION: Trick locking here, see class header for details
728 Non_Servant_Upcall non_servant_upcall (*this->poa_);
729 ACE_UNUSED_ARG (non_servant_upcall);
731 // The implementation of activate_object will invoke _add_ref at
732 // least once on the Servant argument before returning. When the POA
733 // no longer needs the Servant, it will invoke _remove_ref on it the
734 // same number of times.
735 servant->_add_ref ();
737 return user_id._retn ();
740 void
741 ServantRetentionStrategyRetain::activate_object_with_id (
742 const PortableServer::ObjectId &id,
743 PortableServer::Servant servant,
744 CORBA::Short priority,
745 bool &wait_occurred_restart_call)
747 // If the POA has the SYSTEM_ID policy and it detects that the
748 // Object Id value was not generated by the system or for this POA,
749 // the activate_object_with_id operation may raise the BAD_PARAM
750 // system exception. An ORB is not required to detect all such
751 // invalid Object Id values, but a portable application must not
752 // invoke activate_object_with_id on a POA that has the SYSTEM_ID
753 // policy with an Object Id value that was not previously generated
754 // by the system for that POA, or, if the POA also has the
755 // PERSISTENT policy, for a previous instantiation of the same POA.
756 if (this->poa_->has_system_id () &&
757 !this->poa_->is_poa_generated_id (id))
759 throw ::CORBA::BAD_PARAM ();
762 // If the CORBA object denoted by the Object Id value is already
763 // active in this POA (there is a servant bound to it in the Active
764 // Object Map), the ObjectAlreadyActive exception is raised.
765 bool priorities_match = true;
766 bool result =
767 this->is_user_id_in_map (id,
768 priority,
769 priorities_match,
770 wait_occurred_restart_call);
772 // @johnny the implementation is not complete, this does the spec also say
773 // If the POA has the UNIQUE_ID policy and the servant is already
774 // in the Active Object Map, the ServantAlreadyActive exception is raised.
775 if (result)
777 throw PortableServer::POA::ObjectAlreadyActive ();
779 else if (wait_occurred_restart_call)
781 // We ended up waiting on a condition variable, the POA state
782 // may have changed while we are waiting. Therefore, we need to
783 // restart this call.
784 return;
787 // If the activate_object_with_id_and_priority operation is invoked
788 // with a different priority to an earlier invocation of one of the
789 // create reference with priority operations, for the same object,
790 // then the ORB shall raise a BAD_INV_ORDER system exception (with a
791 // Standard Minor Exception Code of 1). If the priority value is the
792 // same then the ORB shall return SUCCESS.
793 if (!priorities_match)
795 throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 1,
796 CORBA::COMPLETED_NO);
799 bool const may_activate =
800 this->poa_->is_servant_activation_allowed (servant, wait_occurred_restart_call);
802 if (!may_activate)
804 if (wait_occurred_restart_call)
806 return;
808 else
810 throw PortableServer::POA::ServantAlreadyActive ();
814 // Otherwise, the activate_object_with_id operation enters an
815 // association between the specified Object Id and the specified
816 // servant in the Active Object Map.
817 if (this->active_object_map_->bind_using_user_id (servant,
819 priority) != 0)
821 throw ::CORBA::OBJ_ADAPTER ();
825 // Everything is finally ok
828 // Inform the custom servant dispatching (CSD) strategy that the
829 // sevant is activated.
830 this->poa_->servant_activated_hook (servant, id);
832 // ATTENTION: Trick locking here, see class header for details
833 Non_Servant_Upcall non_servant_upcall (*this->poa_);
834 ACE_UNUSED_ARG (non_servant_upcall);
836 // The implementation of activate_object_with_id will invoke
837 // _add_ref at least once on the Servant argument before
838 // returning. When the POA no longer needs the Servant, it will
839 // invoke _remove_ref on it the same number of times.
840 servant->_add_ref ();
843 CORBA::Object_ptr
844 ServantRetentionStrategyRetain::create_reference (
845 const char *intf,
846 CORBA::Short priority)
848 // This operation creates an object reference that encapsulates a
849 // POA-generated Object Id value and the specified interface
850 // repository id. This operation does not cause an activation to
851 // take place. The resulting reference may be passed to clients, so
852 // that subsequent requests on those references will cause the
853 // appropriate servant manager to be invoked, if one is
854 // available. The generated Object Id value may be obtained by
855 // invoking POA::reference_to_id with the created reference.
857 PortableServer::ObjectId_var system_id;
858 PortableServer::ObjectId user_id;
860 if (this->active_object_map_->
861 bind_using_system_id_returning_system_id (0,
862 priority,
863 system_id.out ()) != 0)
865 throw ::CORBA::OBJ_ADAPTER ();
868 // Find user id from system id.
869 if (this->active_object_map_->
870 find_user_id_using_system_id (system_id.in (),
871 user_id) != 0)
873 throw ::CORBA::OBJ_ADAPTER ();
876 // Remember params for potentially invoking <key_to_object> later.
877 this->poa_->key_to_object_params_.set (system_id,
878 intf,
881 priority,
882 true);
884 return this->poa_->invoke_key_to_object_helper_i (intf,
885 user_id);
888 #if !defined (CORBA_E_MICRO)
889 CORBA::Object_ptr
890 ServantRetentionStrategyRetain::create_reference_with_id (
891 const PortableServer::ObjectId &oid,
892 const char *intf,
893 CORBA::Short priority)
895 // This operation creates an object reference that encapsulates the
896 // specified Object Id and interface repository Id values. This
897 // operation does not cause an activation to take place. The
898 // resulting reference may be passed to clients, so that subsequent
899 // requests on those references will cause the object to be
900 // activated if necessary, or the default servant used, depending on
901 // the applicable policies.
903 PortableServer::Servant servant = 0;
904 PortableServer::ObjectId_var system_id;
906 // @@ We need something that can find the system id using
907 // appropriate strategy, at the same time, return the servant if
908 // one is available. Before we have that function,
909 // <create_reference_with_id_i> basically generates broken
910 // collocated object when DIRECT collocation strategy is used.
912 if (this->active_object_map_->
913 find_system_id_using_user_id (oid,
914 priority,
915 system_id.out ()) != 0)
917 throw ::CORBA::OBJ_ADAPTER ();
920 // Remember params for potentially invoking <key_to_object> later.
921 this->poa_->key_to_object_params_.set (system_id,
922 intf,
923 servant,
925 priority,
926 true);
928 return this->poa_->invoke_key_to_object_helper_i (intf, oid);
930 #endif
933 ServantRetentionStrategyRetain::rebind_using_user_id_and_system_id (
934 PortableServer::Servant servant,
935 const PortableServer::ObjectId &user_id,
936 const PortableServer::ObjectId &system_id,
937 TAO::Portable_Server::Servant_Upcall &servant_upcall)
939 TAO_Active_Object_Map_Entry *entry = 0;
940 int result = this->active_object_map_->
941 rebind_using_user_id_and_system_id (servant,
942 user_id,
943 system_id,
944 entry);
945 servant_upcall.active_object_map_entry(entry);
947 return result;
950 CORBA::Boolean
951 ServantRetentionStrategyRetain::servant_has_remaining_activations (
952 PortableServer::Servant servant)
954 return this->active_object_map_->remaining_activations (servant);
957 TAO_Active_Object_Map *
958 ServantRetentionStrategyRetain::get_active_object_map() const
960 return this->active_object_map_.get();
966 TAO_END_VERSIONED_NAMESPACE_DECL