Updated logging to include the class/method so that it is more obvious where these...
[ACE_TAO.git] / TAO / tao / PortableServer / RequestProcessingStrategyServantLocator.cpp
blob01458939b75e0ff10f70d1e2f1e70c52e4f330d4
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
16 namespace TAO
18 namespace Portable_Server
20 RequestProcessingStrategyServantLocator::RequestProcessingStrategyServantLocator ()
24 void
25 RequestProcessingStrategyServantLocator::strategy_cleanup()
28 Non_Servant_Upcall non_servant_upcall (*this->poa_);
29 ACE_UNUSED_ARG (non_servant_upcall);
31 this->servant_locator_ = PortableServer::ServantLocator::_nil ();
34 RequestProcessingStrategy::strategy_cleanup ();
37 PortableServer::ServantManager_ptr
38 RequestProcessingStrategyServantLocator::get_servant_manager ()
40 return PortableServer::ServantManager::_duplicate (this->servant_locator_.in ());
43 void
44 RequestProcessingStrategyServantLocator::set_servant_manager (
45 PortableServer::ServantManager_ptr imgr)
47 // This operation sets the default servant manager associated with the
48 // POA. This operation may only be invoked once after a POA has been
49 // created. Attempting to set the servant manager after one has already
50 // been set will result in the BAD_INV_ORDER system exception with
51 // standard minor code 6 being raised (see 11.3.9.12 of the corba spec)
52 if (!CORBA::is_nil (this->servant_locator_.in ()))
54 throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 6,
55 CORBA::COMPLETED_NO);
58 this->servant_locator_ = PortableServer::ServantLocator::_narrow (imgr);
60 this->validate_servant_manager (this->servant_locator_.in ());
63 TAO_SERVANT_LOCATION
64 RequestProcessingStrategyServantLocator::locate_servant (
65 const PortableServer::ObjectId &system_id,
66 PortableServer::Servant &servant)
68 TAO_SERVANT_LOCATION location =
69 this->poa_->servant_present (system_id, servant);
71 if (location == TAO_SERVANT_NOT_FOUND)
73 if (!CORBA::is_nil (this->servant_locator_.in ()))
75 location = TAO_SERVANT_MANAGER;
79 return location;
82 PortableServer::Servant
83 RequestProcessingStrategyServantLocator::locate_servant (
84 const char *operation,
85 const PortableServer::ObjectId &system_id,
86 TAO::Portable_Server::Servant_Upcall &servant_upcall,
87 TAO::Portable_Server::POA_Current_Impl &poa_current_impl,
88 bool &/*wait_occurred_restart_call*/)
90 PortableServer::Servant servant = this->poa_->find_servant (system_id,
91 servant_upcall,
92 poa_current_impl);
94 if (servant != 0)
96 return servant;
99 // If the POA has the USE_SERVANT_MANAGER policy, a servant manager
100 // has been associated with the POA so the POA will invoke incarnate
101 // or preinvoke on it to find a servant that may handle the
102 // request. (The choice of method depends on the NON_RETAIN or
103 // RETAIN policy of the POA.) If no servant manager has been
104 // associated with the POA, the POA raises the OBJ_ADAPTER system
105 // exception.
107 // If a servant manager is located and invoked, but the servant
108 // manager is not directly capable of incarnating the object, it
109 // (the servant manager) may deal with the circumstance in a variety
110 // of ways, all of which are the application's responsibility. Any
111 // system exception raised by the servant manager will be returned
112 // to the client in the reply. In addition to standard CORBA
113 // exceptions, a servant manager is capable of raising a
114 // ForwardRequest exception. This exception includes an object
115 // reference.
118 this->validate_servant_manager (this->servant_locator_.in ());
120 // No serialization of invocations of preinvoke or
121 // postinvoke may be assumed; there may be multiple
122 // concurrent invocations of preinvoke for the same
123 // ObjectId.
125 // The same thread will be used to preinvoke the object,
126 // process the request, and postinvoke the object.
128 // @@ Note that it is possible for some other thread to
129 // reset the servant locator once the lock is released.
130 // However, this possiblility also exists for postinvoke()
131 // which is also called outside the lock.
133 // Release the object adapter lock.
134 this->poa_->object_adapter().lock ().release ();
136 // We have released the object adapter lock. Record this
137 // for later use.
138 servant_upcall.state (TAO::Portable_Server::Servant_Upcall::OBJECT_ADAPTER_LOCK_RELEASED);
140 PortableServer::ServantLocator::Cookie cookie = 0;
141 servant =
142 this->servant_locator_->preinvoke (poa_current_impl.object_id (),
143 this->poa_,
144 operation,
145 cookie);
147 if (servant == 0)
149 throw ::CORBA::OBJ_ADAPTER (CORBA::OMGVMCID | 7, CORBA::COMPLETED_NO);
152 // Remember the cookie
153 servant_upcall.locator_cookie (cookie);
155 // Remember operation name.
156 servant_upcall.operation (operation);
158 // Success
159 return servant;
162 void
163 RequestProcessingStrategyServantLocator::cleanup_servant (
164 PortableServer::Servant servant,
165 const PortableServer::ObjectId &user_id)
167 if (servant)
169 // ATTENTION: Trick locking here, see class header for details
170 Non_Servant_Upcall non_servant_upcall (*this->poa_);
171 ACE_UNUSED_ARG (non_servant_upcall);
175 servant->_remove_ref ();
177 catch (...)
179 // Ignore exceptions from servant cleanup.
183 // This operation causes the association of the Object Id specified
184 // by the oid parameter and its servant to be removed from the
185 // Active Object Map.
186 if (this->poa_->unbind_using_user_id (user_id) != 0)
188 throw ::CORBA::OBJ_ADAPTER ();
192 void
193 RequestProcessingStrategyServantLocator::etherealize_objects (
194 CORBA::Boolean /*etherealize_objects*/)
198 void
199 RequestProcessingStrategyServantLocator::post_invoke_servant_cleanup(
200 const PortableServer::ObjectId &system_id,
201 const TAO::Portable_Server::Servant_Upcall &servant_upcall)
203 // @todo This method seems to misbehave according to the corba spec, see
204 // section 11.3.7.2. It says that when postinvoke raises an system
205 // exception the methods normal return is overrriden, the request completes
206 // with the exception
208 if (!CORBA::is_nil (this->servant_locator_.in ()) &&
209 servant_upcall.servant())
213 servant_locator_->postinvoke (system_id,
214 this->poa_,
215 servant_upcall.operation (),
216 servant_upcall.locator_cookie (),
217 servant_upcall.servant ());
219 catch (const ::CORBA::Exception&)
221 // Ignore errors from servant locator ....
228 TAO_END_VERSIONED_NAMESPACE_DECL
230 #endif /* TAO_HAS_MINIMUM_POA == 0 */