1 #include "tao/orbconf.h"
3 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
5 #include "tao/ORB_Constants.h"
6 #include "tao/PortableServer/ServantLocatorC.h"
7 #include "tao/PortableServer/RequestProcessingStrategyServantLocator.h"
8 #include "tao/PortableServer/Root_POA.h"
9 #include "tao/PortableServer/POA_Current_Impl.h"
10 #include "tao/PortableServer/Servant_Upcall.h"
11 #include "tao/PortableServer/Non_Servant_Upcall.h"
12 #include "tao/PortableServer/Servant_Base.h"
14 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
18 namespace Portable_Server
21 RequestProcessingStrategyServantLocator::strategy_cleanup()
24 Non_Servant_Upcall
non_servant_upcall (*this->poa_
);
25 ACE_UNUSED_ARG (non_servant_upcall
);
27 this->servant_locator_
= PortableServer::ServantLocator::_nil ();
30 RequestProcessingStrategy::strategy_cleanup ();
33 PortableServer::ServantManager_ptr
34 RequestProcessingStrategyServantLocator::get_servant_manager ()
36 return PortableServer::ServantManager::_duplicate (this->servant_locator_
.in ());
40 RequestProcessingStrategyServantLocator::set_servant_manager (
41 PortableServer::ServantManager_ptr imgr
)
43 // This operation sets the default servant manager associated with the
44 // POA. This operation may only be invoked once after a POA has been
45 // created. Attempting to set the servant manager after one has already
46 // been set will result in the BAD_INV_ORDER system exception with
47 // standard minor code 6 being raised (see 11.3.9.12 of the corba spec)
48 if (!CORBA::is_nil (this->servant_locator_
.in ()))
50 throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID
| 6,
54 this->servant_locator_
= PortableServer::ServantLocator::_narrow (imgr
);
56 this->validate_servant_manager (this->servant_locator_
.in ());
60 RequestProcessingStrategyServantLocator::locate_servant (
61 const PortableServer::ObjectId
&system_id
,
62 PortableServer::Servant
&servant
)
64 TAO_Servant_Location location
= this->poa_
->servant_present (system_id
, servant
);
66 if (location
== TAO_Servant_Location::Not_Found
)
68 if (!CORBA::is_nil (this->servant_locator_
.in ()))
70 location
= TAO_Servant_Location::Servant_Manager
;
77 PortableServer::Servant
78 RequestProcessingStrategyServantLocator::locate_servant (
79 const char *operation
,
80 const PortableServer::ObjectId
&system_id
,
81 TAO::Portable_Server::Servant_Upcall
&servant_upcall
,
82 TAO::Portable_Server::POA_Current_Impl
&poa_current_impl
,
83 bool &/*wait_occurred_restart_call*/)
85 PortableServer::Servant servant
= this->poa_
->find_servant (system_id
,
94 // If the POA has the USE_SERVANT_MANAGER policy, a servant manager
95 // has been associated with the POA so the POA will invoke incarnate
96 // or preinvoke on it to find a servant that may handle the
97 // request. (The choice of method depends on the NON_RETAIN or
98 // RETAIN policy of the POA.) If no servant manager has been
99 // associated with the POA, the POA raises the OBJ_ADAPTER system
102 // If a servant manager is located and invoked, but the servant
103 // manager is not directly capable of incarnating the object, it
104 // (the servant manager) may deal with the circumstance in a variety
105 // of ways, all of which are the application's responsibility. Any
106 // system exception raised by the servant manager will be returned
107 // to the client in the reply. In addition to standard CORBA
108 // exceptions, a servant manager is capable of raising a
109 // ForwardRequest exception. This exception includes an object
113 this->validate_servant_manager (this->servant_locator_
.in ());
115 // No serialization of invocations of preinvoke or
116 // postinvoke may be assumed; there may be multiple
117 // concurrent invocations of preinvoke for the same
120 // The same thread will be used to preinvoke the object,
121 // process the request, and postinvoke the object.
123 // @@ Note that it is possible for some other thread to
124 // reset the servant locator once the lock is released.
125 // However, this possiblility also exists for postinvoke()
126 // which is also called outside the lock.
128 // Release the object adapter lock.
129 this->poa_
->object_adapter().lock ().release ();
131 // We have released the object adapter lock. Record this
133 servant_upcall
.state (TAO::Portable_Server::Servant_Upcall::OBJECT_ADAPTER_LOCK_RELEASED
);
135 PortableServer::ServantLocator::Cookie cookie
= 0;
137 this->servant_locator_
->preinvoke (poa_current_impl
.object_id (),
144 throw ::CORBA::OBJ_ADAPTER (CORBA::OMGVMCID
| 7, CORBA::COMPLETED_NO
);
147 // Remember the cookie
148 servant_upcall
.locator_cookie (cookie
);
150 // Remember operation name.
151 servant_upcall
.operation (operation
);
158 RequestProcessingStrategyServantLocator::cleanup_servant (
159 PortableServer::Servant servant
,
160 const PortableServer::ObjectId
&user_id
)
164 // ATTENTION: Trick locking here, see class header for details
165 Non_Servant_Upcall
non_servant_upcall (*this->poa_
);
166 ACE_UNUSED_ARG (non_servant_upcall
);
170 servant
->_remove_ref ();
174 // Ignore exceptions from servant cleanup.
178 // This operation causes the association of the Object Id specified
179 // by the oid parameter and its servant to be removed from the
180 // Active Object Map.
181 if (this->poa_
->unbind_using_user_id (user_id
) != 0)
183 throw ::CORBA::OBJ_ADAPTER ();
188 RequestProcessingStrategyServantLocator::etherealize_objects (
189 CORBA::Boolean
/*etherealize_objects*/)
194 RequestProcessingStrategyServantLocator::post_invoke_servant_cleanup(
195 const PortableServer::ObjectId
&system_id
,
196 const TAO::Portable_Server::Servant_Upcall
&servant_upcall
)
198 // @todo This method seems to misbehave according to the corba spec, see
199 // section 11.3.7.2. It says that when postinvoke raises an system
200 // exception the methods normal return is overrriden, the request completes
201 // with the exception
203 if (!CORBA::is_nil (this->servant_locator_
.in ()) &&
204 servant_upcall
.servant())
208 servant_locator_
->postinvoke (system_id
,
210 servant_upcall
.operation (),
211 servant_upcall
.locator_cookie (),
212 servant_upcall
.servant ());
214 catch (const ::CORBA::Exception
&)
216 // Ignore errors from servant locator ....
223 TAO_END_VERSIONED_NAMESPACE_DECL
225 #endif /* TAO_HAS_MINIMUM_POA == 0 */