1 #include "tao/PortableServer/POAManager.h"
2 #include "tao/PortableServer/POAManagerFactory.h"
3 #include "tao/PortableServer/Root_POA.h"
4 #include "tao/PortableServer/poa_macros.h"
5 #include "tao/Server_Strategy_Factory.h"
6 #include "tao/ORB_Core.h"
7 #include "tao/IORInterceptor_Adapter.h"
9 #if !defined (__ACE_INLINE__)
10 # include "tao/PortableServer/POAManager.inl"
11 #endif /* ! __ACE_INLINE__ */
13 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
15 TAO_POA_Manager::TAO_POA_Manager (
16 TAO_Object_Adapter
&object_adapter
,
17 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
19 const ::CORBA::PolicyList
&policies
,
20 PortableServer::POAManagerFactory_ptr poa_manager_factory
)
24 : state_ (PortableServer::POAManager::HOLDING
),
25 lock_ (object_adapter
.lock ()),
27 object_adapter_ (object_adapter
),
28 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
29 id_ (id
== 0 ? this->generate_manager_id () : CORBA::string_dup (id
)),
30 poa_manager_factory_ (* dynamic_cast <TAO_POAManager_Factory
*> (poa_manager_factory
)),
33 poa_manager_factory_
._add_ref ();
36 id_ (id
== 0 ? this->generate_manager_id () : CORBA::string_dup (id
))
42 TAO_POA_Manager::~TAO_POA_Manager ()
44 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
45 poa_manager_factory_
._remove_ref ();
50 TAO_POA_Manager::get_id ()
52 return CORBA::string_dup (this->id_
.in ());
56 TAO_POA_Manager::activate_i ()
58 // This operation changes the state of the POA manager to active. If
59 // issued while the POA manager is in the inactive state, the
60 // AdapterInactive exception is raised. Entering the active state
61 // enables the associated POAs to process requests.
63 if (this->state_
== PortableServer::POAManager::INACTIVE
)
65 throw PortableServer::POAManager::AdapterInactive ();
69 this->state_
= PortableServer::POAManager::ACTIVE
;
70 // Find the poas that applied the custom servant dispatching
71 // strategy to launch the dispatching threads.
73 for (POA_COLLECTION::iterator iterator
= this->poa_collection_
.begin ();
74 iterator
!= this->poa_collection_
.end ();
77 (*iterator
)->poa_activated_hook ();
81 this->adapter_manager_state_changed (this->state_
);
85 TAO_POA_Manager::deactivate_i (CORBA::Boolean etherealize_objects
,
86 CORBA::Boolean wait_for_completion
)
88 // Is the @a wait_for_completion semantics for this thread correct?
89 TAO_Root_POA::check_for_valid_wait_for_completions (this->object_adapter_
.orb_core (),
92 // This operation changes the state of the POA manager to
93 // inactive. If issued while the POA manager is in the inactive
94 // state, this operation has not effect. Entering the
95 // inactive state causes the associated POAs to reject requests that
96 // have not begun to be executed as well as any new requests.
98 if (this->state_
== PortableServer::POAManager::INACTIVE
)
104 this->state_
= PortableServer::POAManager::INACTIVE
;
107 // After changing the state, if the etherealize_objects parameter is:
109 // a) TRUE - the POA manager will cause all associated POAs that
110 // have the RETAIN and USE_SERVANT_MANAGER policies to perform the
111 // etherealize operation on the associated servant manager for all
114 // b) FALSE - the etherealize operation is not called. The purpose
115 // is to provide developers with a means to shut down POAs in a
116 // crisis (for example, unrecoverable error) situation.
118 // If the wait_for_completion parameter is FALSE, this operation
119 // will return immediately after changing the state. If the
120 // parameter is TRUE and the current thread is not in an invocation
121 // context dispatched by some POA belonging to the same ORB as this
122 // POA, this operation does not return until there are no actively
123 // executing requests in any of the POAs associated with this POA
124 // manager (that is, all requests that were started prior to the
125 // state change have completed) and, in the case of a TRUE
126 // etherealize_objects, all invocations of etherealize have
127 // completed for POAs having the RETAIN and USE_SERVANT_MANAGER
128 // policies. If the parameter is TRUE and the current thread is in
129 // an invocation context dispatched by some POA belonging to the
130 // same ORB as this POA the BAD_INV_ORDER exception is raised and
131 // the state is not changed.
133 for (POA_COLLECTION::iterator iterator
= this->poa_collection_
.begin ();
134 iterator
!= this->poa_collection_
.end ();
137 TAO_Root_POA
*poa
= *iterator
;
138 // Notify the poas that applied the custom servant dispatching
139 // strategy to stop the dispatching threads.
140 poa
->poa_deactivated_hook ();
142 poa
->deactivate_all_objects_i (etherealize_objects
, wait_for_completion
);
145 // If the ORB::shutdown operation is called, it makes a call on
146 // deactivate with a TRUE etherealize_objects parameter for each POA
147 // manager known in the process; the wait_for_completion parameter
148 // to deactivate will be the same as the similarly named parameter
150 this->adapter_manager_state_changed (this->state_
);
154 TAO_POA_Manager::adapter_manager_state_changed (PortableServer::POAManager::State state
)
156 PortableInterceptor::AdapterState adapter_state
=
157 static_cast<PortableInterceptor::AdapterState
> (state
);
159 TAO_IORInterceptor_Adapter
*ior_adapter
=
160 this->object_adapter_
.orb_core ().ior_interceptor_adapter ();
164 ior_adapter
->adapter_manager_state_changed (this->id_
.in (),
169 #if (TAO_HAS_MINIMUM_POA == 0)
172 TAO_POA_Manager::hold_requests_i (CORBA::Boolean wait_for_completion
)
174 // Is the <wait_for_completion> semantics for this thread correct?
175 TAO_Root_POA::check_for_valid_wait_for_completions (this->object_adapter_
.orb_core (),
176 wait_for_completion
);
178 // This operation changes the state of the POA manager to
179 // holding. If issued while the POA manager is in the inactive
180 // state, the AdapterInactive exception is raised. Entering the
181 // holding state causes the associated POAs to queue incoming
182 // requests. Any requests that have been queued but have not
183 // started executing will continue to be queued while in the holding
185 if (this->state_
== PortableServer::POAManager::INACTIVE
)
187 throw PortableServer::POAManager::AdapterInactive ();
191 this->state_
= PortableServer::POAManager::HOLDING
;
194 // If the wait_for_completion parameter is FALSE, this operation
195 // returns immediately after changing the state. If the parameter is
196 // TRUE and the current thread is not in an invocation context
197 // dispatched by some POA belonging to the same ORB as this POA,
198 // this operation does not return until either there are no actively
199 // executing requests in any of the POAs associated with this POA
200 // manager (that is, all requests that were started prior to the
201 // state change have completed) or the state of the POA manager is
202 // changed to a state other than holding. If the parameter is TRUE
203 // and the current thread is in an invocation context dispatched by
204 // some POA belonging to the same ORB as this POA the BAD_INV_ORDER
205 // exception is raised and the state is not changed.
206 if (wait_for_completion
)
208 for (POA_COLLECTION::iterator iterator
= this->poa_collection_
.begin ();
209 iterator
!= this->poa_collection_
.end ();
212 TAO_Root_POA
*poa
= *iterator
;
213 poa
->wait_for_completions (wait_for_completion
);
217 this->adapter_manager_state_changed (this->state_
);
221 TAO_POA_Manager::discard_requests_i (CORBA::Boolean wait_for_completion
)
223 // Is the <wait_for_completion> semantics for this thread correct?
224 TAO_Root_POA::check_for_valid_wait_for_completions (this->object_adapter_
.orb_core (),
225 wait_for_completion
);
227 // This operation changes the state of the POA manager to
228 // discarding. If issued while the POA manager is in the inactive
229 // state, the AdapterInactive exception is raised. Entering the
230 // discarding state causes the associated POAs to discard incoming
231 // requests. In addition, any requests that have been queued but
232 // have not started executing are discarded. When a request is
233 // discarded, a TRANSIENT system exception is returned to the
235 if (this->state_
== PortableServer::POAManager::INACTIVE
)
237 throw PortableServer::POAManager::AdapterInactive ();
241 this->state_
= PortableServer::POAManager::DISCARDING
;
244 // If the wait_for_completion parameter is FALSE, this operation
245 // returns immediately after changing the state. If the
246 // parameter is TRUE and the current thread is not in an
247 // invocation context dispatched by some POA belonging to the
248 // same ORB as this POA, this operation does not return until
249 // either there are no actively executing requests in any of the
250 // POAs associated with this POA manager (that is, all requests
251 // that were started prior to the state change have completed)
252 // or the state of the POA manager is changed to a state other
253 // than discarding. If the parameter is TRUE and the current
254 // thread is in an invocation context dispatched by some POA
255 // belonging to the same ORB as this POA the BAD_INV_ORDER
256 // exception is raised and the state is not changed.
258 if (wait_for_completion
)
260 for (POA_COLLECTION::iterator iterator
= this->poa_collection_
.begin ();
261 iterator
!= this->poa_collection_
.end ();
264 TAO_Root_POA
*poa
= *iterator
;
265 poa
->wait_for_completions (wait_for_completion
);
269 this->adapter_manager_state_changed (this->state_
);
272 #endif /* TAO_HAS_MINIMUM_POA == 0 */
275 TAO_POA_Manager::remove_poa (TAO_Root_POA
*poa
)
277 int const result
= this->poa_collection_
.remove (poa
);
279 // The #if really only needs to go around the
280 // "this->poa_manager_factory_.remove_poamanager (this);" line, but it's
281 // moved out as an optimization for now. If additional non-CORBA/e and
282 // non-minimum POA code needs to go in that clause the #if would have to
285 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
288 if (this->poa_collection_
.is_empty ())
290 this->poa_manager_factory_
.remove_poamanager (this);
298 TAO_POA_Manager::register_poa (TAO_Root_POA
*poa
)
300 return this->poa_collection_
.insert (poa
);
304 TAO_POA_Manager::check_state ()
306 if (state_
== PortableServer::POAManager::ACTIVE
)
308 // When a POA manager is in the active state, the associated
309 // POAs will receive and start processing requests (assuming
310 // that appropriate thread resources are available).
314 if (state_
== PortableServer::POAManager::DISCARDING
)
316 // When a POA manager is in the discarding state, the associated
317 // POAs will discard all incoming requests (whose processing has
318 // not yet begun). When a request is discarded, the TRANSIENT
319 // system exception, with standard minor code 1, must be
320 // returned to the client-side to indicate that the request
321 // should be re-issued. (Of course, an ORB may always reject a
322 // request for other reasons and raise some other system
326 CORBA::SystemException::_tao_minor_code (
329 CORBA::COMPLETED_NO
);
332 if (state_
== PortableServer::POAManager::HOLDING
)
334 // When a POA manager is in the holding state, the associated
335 // POAs will queue incoming requests. The number of requests
336 // that can be queued is an implementation limit. If this limit
337 // is reached, the POAs may discard requests and return the
338 // TRANSIENT system exception, with standard minor code 1, to
339 // the client to indicate that the client should reissue the
340 // request. (Of course, an ORB may always reject a request for
341 // other reasons and raise some other system exception.)
343 // Since there is no queuing in TAO, we immediately raise a
344 // TRANSIENT exception.
345 throw ::CORBA::TRANSIENT (
346 CORBA::SystemException::_tao_minor_code (TAO_POA_HOLDING
, 1),
347 CORBA::COMPLETED_NO
);
350 if (state_
== PortableServer::POAManager::INACTIVE
)
352 // The inactive state is entered when the associated POAs are to
353 // be shut down. Unlike the discarding state, the inactive state
354 // is not a temporary state. When a POA manager is in the
355 // inactive state, the associated POAs will reject new
356 // requests. The rejection mechanism used is specific to the
357 // vendor. The GIOP location forwarding mechanism and
358 // CloseConnection message are examples of mechanisms that could
359 // be used to indicate the rejection. If the client is
360 // co-resident in the same process, the ORB could raise the
361 // OBJ_ADAPTER system exception, with standard minor code 1, to
362 // indicate that the object implementation is unavailable.
363 throw ::CORBA::OBJ_ADAPTER (
364 CORBA::SystemException::_tao_minor_code (TAO_POA_INACTIVE
, 1),
365 CORBA::COMPLETED_NO
);
370 TAO_POA_Manager::_get_orb ()
372 return CORBA::ORB::_duplicate (this->object_adapter_
.orb_core ().orb ());
375 TAO_END_VERSIONED_NAMESPACE_DECL