Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / PI_Server / ServerInterceptorAdapter.cpp
blob93470b44b2d2a2532e857584dd50447a6efcb5ee
1 // -*- C++ -*-
2 #include "tao/PI_Server/ServerInterceptorAdapter.h"
4 #if TAO_HAS_INTERCEPTORS == 1
6 #include "tao/PI_Server/ServerRequestInfo.h"
7 #include "tao/PI_Server/PICurrent_Guard.h"
9 #include "tao/ServerRequestInterceptor_Adapter.h"
10 #include "tao/TAO_Server_Request.h"
11 #include "tao/ORB_Core.h"
12 #include "tao/PI/PICurrent_Impl.h"
13 #include "tao/PortableServer/Upcall_Command.h"
14 #include "tao/PortableInterceptor.h"
16 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
18 TAO::ServerRequestInterceptor_Adapter_Impl::ServerRequestInterceptor_Adapter_Impl ()
22 #if TAO_HAS_EXTENDED_FT_INTERCEPTORS == 1
23 void
24 TAO::ServerRequestInterceptor_Adapter_Impl::tao_ft_interception_point (
25 TAO_ServerRequest &server_request,
26 TAO::Argument * const args[],
27 size_t nargs,
28 TAO::Portable_Server::Servant_Upcall *servant_upcall,
29 CORBA::TypeCode_ptr const * exceptions,
30 CORBA::ULong nexceptions,
31 CORBA::OctetSeq_out oc)
33 // This method implements one of the "starting" server side
34 // interception point.
36 try
38 oc = 0;
40 bool is_remote_request = !server_request.collocated ();
41 TAO::ServerRequestInfo request_info (server_request,
42 args,
43 nargs,
44 servant_upcall,
45 exceptions,
46 nexceptions);
48 for (size_t i = 0 ; i < this->interceptor_list_.size(); ++i)
50 ServerRequestInterceptor_List::RegisteredInterceptor& registered =
51 this->interceptor_list_.registered_interceptor (i);
53 if (registered.details_.should_be_processed (is_remote_request))
55 registered.interceptor_->
56 tao_ft_interception_point (&request_info, oc);
59 if (oc != 0)
61 (void) this->send_other (server_request,
62 args,
63 nargs,
64 servant_upcall,
65 exceptions,
66 nexceptions);
68 return;
71 // The starting interception point completed successfully.
72 // Push the interceptor on to the flow stack.
73 ++server_request.interceptor_count ();
76 catch (const ::PortableInterceptor::ForwardRequest& exc)
78 server_request.forward_location (exc.forward.in ());
79 server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
80 server_request.reply_status (GIOP::LOCATION_FORWARD);
81 (void) this->send_other (server_request,
82 args,
83 nargs,
84 servant_upcall,
85 exceptions,
86 nexceptions);
90 void
91 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request_service_contexts (
92 TAO_ServerRequest &server_request,
93 TAO::Argument * const args[],
94 size_t nargs,
95 TAO::Portable_Server::Servant_Upcall *servant_upcall,
96 CORBA::TypeCode_ptr const * exceptions,
97 CORBA::ULong nexceptions)
99 // This method implements one of the "intermediate" server side
100 // interception point.
102 if (this->interceptor_list_.size() != server_request.interceptor_count ())
104 // This method (i.e. the receive_request() interception point)
105 // should only be invoked if all of the interceptors registered
106 // with the ORB were pushed on to the flow stack by one of the
107 // starting endpoints (such as
108 // tao_ft_interception_point()). If the above condition
109 // evaluates to "true," then it is likely that a starting
110 // interception point was never invoked. This is of course, an
111 // internal error that must be corrected.
112 throw ::CORBA::INTERNAL ();
117 // Copy the request scope current (RSC) to the thread scope
118 // current (TSC) upon leaving this scope, i.e. just after the
119 // receive_request_service_contexts() completes. A "guard" is
120 // used to make the copy also occur if an exception is thrown.
121 TAO::PICurrent_Guard const pi_guard (server_request,
122 false /* Copy RSC to TSC */);
124 bool is_remote_request = !server_request.collocated ();
125 TAO::ServerRequestInfo request_info (server_request,
126 args,
127 nargs,
128 servant_upcall,
129 exceptions,
130 nexceptions);
132 for (size_t i = 0 ; i < server_request.interceptor_count (); ++i)
134 ServerRequestInterceptor_List::RegisteredInterceptor& registered =
135 this->interceptor_list_.registered_interceptor (i);
137 if (registered.details_.should_be_processed (is_remote_request))
139 registered.interceptor_->
140 receive_request_service_contexts (&request_info);
144 catch (const ::PortableInterceptor::ForwardRequest& exc)
146 server_request.forward_location (exc.forward.in ());
147 server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
148 server_request.reply_status (GIOP::LOCATION_FORWARD);
149 (void) this->send_other (server_request,
150 args,
151 nargs,
152 servant_upcall,
153 exceptions,
154 nexceptions);
158 #elif TAO_HAS_EXTENDED_FT_INTERCEPTORS == 0
160 /// NOTE: Yes, we have two versions of this. This is easier than
161 /// messing around things in the same function, which is harder to
162 /// read and could make the code buggier.
163 void
164 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request_service_contexts (
165 TAO_ServerRequest &server_request,
166 TAO::Argument * const args[],
167 size_t nargs,
168 TAO::Portable_Server::Servant_Upcall *servant_upcall,
169 CORBA::TypeCode_ptr const * exceptions,
170 CORBA::ULong nexceptions)
172 // This method implements one of the "starting" server side
173 // interception point if extended interceptors are not in place.
177 // Copy the request scope current (RSC) to the thread scope
178 // current (TSC) upon leaving this scope, i.e. just after the
179 // receive_request_service_contexts() completes. A "guard" is
180 // used to make the copy also occur if an exception is thrown.
181 TAO::PICurrent_Guard const pi_guard (server_request,
182 false /* Copy RSC to TSC */);
184 bool is_remote_request = !server_request.collocated ();
186 TAO::ServerRequestInfo request_info (server_request,
187 args,
188 nargs,
189 servant_upcall,
190 exceptions,
191 nexceptions);
193 for (size_t i = 0 ; i < this->interceptor_list_.size(); ++i)
195 ServerRequestInterceptor_List::RegisteredInterceptor& registered =
196 this->interceptor_list_.registered_interceptor (i);
198 if (registered.details_.should_be_processed (is_remote_request))
200 registered.interceptor_->
201 receive_request_service_contexts (&request_info);
204 // The starting interception point completed successfully.
205 // Push the interceptor on to the flow stack.
206 ++server_request.interceptor_count ();
209 catch (const ::PortableInterceptor::ForwardRequest& exc)
211 server_request.forward_location (exc.forward.in ());
212 server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
213 server_request.reply_status (GIOP::LOCATION_FORWARD);
214 (void) this->send_other (server_request,
215 args,
216 nargs,
217 servant_upcall,
218 exceptions,
219 nexceptions);
223 #endif /*TAO_HAS_EXTENDED_FT_INTERCEPTORS*/
225 void
226 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request (
227 TAO_ServerRequest &server_request,
228 TAO::Argument * const args[],
229 size_t nargs,
230 TAO::Portable_Server::Servant_Upcall *servant_upcall,
231 CORBA::TypeCode_ptr const * exceptions,
232 CORBA::ULong nexceptions)
234 // This method implements an "intermediate" server side interception
235 // point. Interceptors are invoked in the same order they were
236 // pushed on to the flow stack.
238 if (this->interceptor_list_.size() != server_request.interceptor_count ())
240 // This method (i.e. the receive_request() interception point)
241 // should only be invoked if all of the interceptors registered
242 // with the ORB were pushed on to the flow stack by one of the
243 // starting endpoints (such as
244 // receive_request_service_contexts()). If the above condition
245 // evaluates to "true," then it is likely that a starting
246 // interception point was never invoked. This is of course, an
247 // internal error that must be corrected.
248 throw ::CORBA::INTERNAL ();
251 TAO::ServerRequestInfo request_info (server_request,
252 args,
253 nargs,
254 servant_upcall,
255 exceptions,
256 nexceptions);
260 bool const is_remote_request = !server_request.collocated ();
262 for (size_t i = 0; i < server_request.interceptor_count (); ++i)
264 ServerRequestInterceptor_List::RegisteredInterceptor& registered =
265 this->interceptor_list_.registered_interceptor (i);
267 if (registered.details_.should_be_processed (is_remote_request))
269 registered.interceptor_->receive_request (&request_info);
272 // Note that no interceptors are pushed on to or popped off
273 // of the flow stack in this interception point since it is
274 // an intermediate interception point.
277 catch (const ::PortableInterceptor::ForwardRequest& exc)
279 server_request.forward_location (exc.forward.in ());
280 server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
281 server_request.reply_status (GIOP::LOCATION_FORWARD);
282 this->send_other (server_request,
283 args,
284 nargs,
285 servant_upcall,
286 exceptions,
287 nexceptions);
292 void
293 TAO::ServerRequestInterceptor_Adapter_Impl::send_reply (
294 TAO_ServerRequest &server_request,
295 TAO::Argument * const args[],
296 size_t nargs,
297 TAO::Portable_Server::Servant_Upcall *servant_upcall,
298 CORBA::TypeCode_ptr const * exceptions,
299 CORBA::ULong nexceptions)
301 // This is an "ending" interception point so we only process the
302 // interceptors pushed on to the flow stack.
304 bool const is_remote_request = !server_request.collocated ();
306 // Notice that the interceptors are processed in the opposite order
307 // they were pushed onto the stack since this is an "ending"
308 // interception point.
310 TAO::ServerRequestInfo request_info (server_request,
311 args,
312 nargs,
313 servant_upcall,
314 exceptions,
315 nexceptions);
317 // Unwind the stack.
318 size_t const len = server_request.interceptor_count ();
319 for (size_t i = 0; i < len; ++i)
321 // Pop the interceptor off of the flow stack before it is
322 // invoked. This is necessary to prevent an interceptor already
323 // invoked in this "ending" interception point from being
324 // invoked in another "ending" interception point.
325 --server_request.interceptor_count ();
327 ServerRequestInterceptor_List::RegisteredInterceptor& registered =
328 this->interceptor_list_.registered_interceptor (
329 server_request.interceptor_count ());
331 if (registered.details_.should_be_processed (is_remote_request))
333 registered.interceptor_->send_reply (&request_info);
337 // The send_reply() interception point does not raise a
338 // PortableInterceptor::ForwardRequest exception so there is no need
339 // to attempt to catch it here.
342 void
343 TAO::ServerRequestInterceptor_Adapter_Impl::send_exception (
344 TAO_ServerRequest &server_request,
345 TAO::Argument * const args[],
346 size_t nargs,
347 TAO::Portable_Server::Servant_Upcall *servant_upcall,
348 CORBA::TypeCode_ptr const * exceptions,
349 CORBA::ULong nexceptions)
351 // This is an "ending" server side interception point so we only
352 // process the interceptors pushed on to the flow stack.
353 bool const is_remote_request = !server_request.collocated ();
355 // Notice that the interceptors are processed in the opposite order
356 // they were pushed onto the stack since this is an "ending" server
357 // side interception point.
359 TAO::ServerRequestInfo request_info (server_request,
360 args,
361 nargs,
362 servant_upcall,
363 exceptions,
364 nexceptions);
368 // Unwind the flow stack.
369 size_t const len = server_request.interceptor_count ();
370 for (size_t i = 0; i < len; ++i)
372 // Pop the interceptor off of the flow stack before it is
373 // invoked. This is necessary to prevent an interceptor
374 // already invoked in this "ending" interception point from
375 // being invoked in another "ending" interception point.
376 --server_request.interceptor_count ();
378 ServerRequestInterceptor_List::RegisteredInterceptor& registered =
379 this->interceptor_list_.registered_interceptor (
380 server_request.interceptor_count ());
382 if (registered.details_.should_be_processed (is_remote_request))
384 registered.interceptor_->send_exception (&request_info);
388 catch (const ::PortableInterceptor::ForwardRequest& exc)
390 server_request.forward_location (exc.forward.in ());
391 server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
392 server_request.reply_status (GIOP::LOCATION_FORWARD);
393 this->send_other (server_request,
394 args,
395 nargs,
396 servant_upcall,
397 exceptions,
398 nexceptions);
400 catch ( ::CORBA::Exception& ex)
402 // The send_exception() interception point in the remaining
403 // interceptors must be called so call this method (not the
404 // interceptor's corresponding method) recursively. The call is
405 // made recursively since the caught exception must survive
406 // until the remaining interceptors have been called.
408 // Note that the recursion will stop once the flow stack size
409 // drops to zero, i.e., once each interceptor has been invoked.
410 // This prevents infinite recursion from occuring.
412 server_request.caught_exception (&ex);
414 this->send_exception (server_request,
415 args,
416 nargs,
417 servant_upcall,
418 exceptions,
419 nexceptions);
421 PortableInterceptor::ReplyStatus status =
422 server_request.pi_reply_status ();
424 // Only re-throw the exception if it hasn't been transformed by
425 // the send_exception() interception point (e.g. to a
426 // LOCATION_FORWARD).
427 if (status == PortableInterceptor::SYSTEM_EXCEPTION
428 || status == PortableInterceptor::USER_EXCEPTION)
429 throw;
433 void
434 TAO::ServerRequestInterceptor_Adapter_Impl::send_other (
435 TAO_ServerRequest &server_request,
436 TAO::Argument * const args[],
437 size_t nargs,
438 TAO::Portable_Server::Servant_Upcall *servant_upcall,
439 CORBA::TypeCode_ptr const * exceptions,
440 CORBA::ULong nexceptions)
442 // This is an "ending" server side interception point so we only
443 // process the interceptors pushed on to the flow stack.
444 bool const is_remote_request = !server_request.collocated ();
446 TAO::ServerRequestInfo request_info (server_request,
447 args,
448 nargs,
449 servant_upcall,
450 exceptions,
451 nexceptions);
453 // Notice that the interceptors are processed in the opposite order
454 // they were pushed onto the stack since this is an "ending" server
455 // side interception point.
459 // Unwind the flow stack.
460 size_t const len = server_request.interceptor_count ();
461 for (size_t i = 0; i < len; ++i)
463 // Pop the interceptor off of the flow stack before it is
464 // invoked. This is necessary to prevent an interceptor
465 // already invoked in this "ending" interception point from
466 // being invoked in another "ending" interception point.
467 --server_request.interceptor_count ();
469 ServerRequestInterceptor_List::RegisteredInterceptor& registered =
470 this->interceptor_list_.registered_interceptor (
471 server_request.interceptor_count ());
473 if (registered.details_.should_be_processed (is_remote_request))
475 registered.interceptor_->send_other (&request_info);
479 catch (const ::PortableInterceptor::ForwardRequest& exc)
481 server_request.forward_location (exc.forward.in ());
482 server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
483 server_request.reply_status (GIOP::LOCATION_FORWARD);
484 this->send_other (server_request,
485 args,
486 nargs,
487 servant_upcall,
488 exceptions,
489 nexceptions);
493 void
494 TAO::ServerRequestInterceptor_Adapter_Impl::add_interceptor (
495 PortableInterceptor::ServerRequestInterceptor_ptr interceptor)
497 this->interceptor_list_.add_interceptor (interceptor);
500 void
501 TAO::ServerRequestInterceptor_Adapter_Impl::add_interceptor (
502 PortableInterceptor::ServerRequestInterceptor_ptr interceptor,
503 const CORBA::PolicyList& policies)
505 this->interceptor_list_.add_interceptor (interceptor, policies);
508 void
509 TAO::ServerRequestInterceptor_Adapter_Impl::destroy_interceptors ()
511 this->interceptor_list_.destroy_interceptors ();
514 TAO::PICurrent_Impl *
515 TAO::ServerRequestInterceptor_Adapter_Impl::allocate_pi_current ()
517 TAO::PICurrent_Impl *pi = 0;
518 ACE_NEW_RETURN (pi,
519 TAO::PICurrent_Impl,
520 pi);
521 return pi;
524 void
525 TAO::ServerRequestInterceptor_Adapter_Impl::deallocate_pi_current (
526 TAO::PICurrent_Impl *picurrent)
528 delete picurrent;
531 void
532 TAO::ServerRequestInterceptor_Adapter_Impl::execute_command (
533 TAO_ServerRequest & server_request,
534 TAO::Upcall_Command & command)
536 TAO::PICurrent_Guard const pi_guard (server_request,
537 true /* Copy TSC to RSC */);
539 // The actual upcall.
540 command.execute ();
543 TAO_END_VERSIONED_NAMESPACE_DECL
545 #endif /* TAO_HAS_INTERCEPTORS == 1 */