ServerInterceptorAdapter.cpp

Go to the documentation of this file.
00001 // $Id: ServerInterceptorAdapter.cpp 81175 2008-03-31 16:19:46Z vzykov $
00002 
00003 #include "tao/PI_Server/ServerInterceptorAdapter.h"
00004 
00005 #if TAO_HAS_INTERCEPTORS == 1
00006 
00007 ACE_RCSID (PI_Server,
00008            ServerInterceptorAdapter,
00009            "$Id: ServerInterceptorAdapter.cpp 81175 2008-03-31 16:19:46Z vzykov $")
00010 
00011 #include "tao/PI_Server/ServerRequestInfo.h"
00012 #include "tao/PI_Server/PICurrent_Guard.h"
00013 
00014 #include "tao/ServerRequestInterceptor_Adapter.h"
00015 #include "tao/TAO_Server_Request.h"
00016 #include "tao/ORB_Core.h"
00017 #include "tao/PI/PICurrent_Impl.h"
00018 #include "tao/PortableServer/Upcall_Command.h"
00019 #include "tao/PortableInterceptor.h"
00020 
00021 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00022 
00023 TAO::ServerRequestInterceptor_Adapter_Impl::ServerRequestInterceptor_Adapter_Impl (void)
00024 {
00025 }
00026 
00027 #if TAO_HAS_EXTENDED_FT_INTERCEPTORS == 1
00028 void
00029 TAO::ServerRequestInterceptor_Adapter_Impl::tao_ft_interception_point (
00030   TAO_ServerRequest &server_request,
00031   TAO::Argument * const args[],
00032   size_t nargs,
00033   void * servant_upcall,
00034   CORBA::TypeCode_ptr const * exceptions,
00035   CORBA::ULong nexceptions,
00036   CORBA::OctetSeq_out oc)
00037 {
00038   // This method implements one of the "starting" server side
00039   // interception point.
00040 
00041   try
00042     {
00043       oc = 0;
00044 
00045       bool is_remote_request = !server_request.collocated ();
00046       TAO::ServerRequestInfo request_info (server_request,
00047                                           args,
00048                                           nargs,
00049                                           servant_upcall,
00050                                           exceptions,
00051                                           nexceptions);
00052 
00053       for (size_t i = 0 ; i < this->interceptor_list_.size(); ++i)
00054         {
00055           ServerRequestInterceptor_List::RegisteredInterceptor& registered =
00056             this->interceptor_list_.registered_interceptor (i);
00057 
00058           if (registered.details_.should_be_processed (is_remote_request))
00059             {
00060               registered.interceptor_->
00061                 tao_ft_interception_point (&request_info, oc);
00062             }
00063 
00064           if (oc != 0)
00065             {
00066               (void) this->send_other (server_request,
00067                                        args,
00068                                        nargs,
00069                                        servant_upcall,
00070                                        exceptions,
00071                                        nexceptions);
00072 
00073               return;
00074             }
00075 
00076           // The starting interception point completed successfully.
00077           // Push the interceptor on to the flow stack.
00078           ++server_request.interceptor_count ();
00079         }
00080     }
00081   catch (const ::PortableInterceptor::ForwardRequest& exc)
00082     {
00083       server_request.forward_location (exc.forward.in ());
00084       server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
00085       server_request.reply_status (GIOP::LOCATION_FORWARD);
00086       (void) this->send_other (server_request,
00087                                args,
00088                                nargs,
00089                                servant_upcall,
00090                                exceptions,
00091                                nexceptions);
00092     }
00093 }
00094 
00095 void
00096 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request_service_contexts (
00097   TAO_ServerRequest &server_request,
00098   TAO::Argument * const args[],
00099   size_t nargs,
00100   void * servant_upcall,
00101   CORBA::TypeCode_ptr const * exceptions,
00102   CORBA::ULong nexceptions)
00103 {
00104   // This method implements one of the "intermediate" server side
00105   // interception point.
00106 
00107   if (this->interceptor_list_.size() != server_request.interceptor_count ())
00108     {
00109       // This method (i.e. the receive_request() interception point)
00110       // should only be invoked if all of the interceptors registered
00111       // with the ORB were pushed on to the flow stack by one of the
00112       // starting endpoints (such as
00113       // tao_ft_interception_point()).  If the above condition
00114       // evaluates to "true," then it is likely that a starting
00115       // interception point was never invoked.  This is of course, an
00116       // internal error that must be corrected.
00117       throw ::CORBA::INTERNAL ();
00118     }
00119 
00120   try
00121     {
00122       // Copy the request scope current (RSC) to the thread scope
00123       // current (TSC) upon leaving this scope, i.e. just after the
00124       // receive_request_service_contexts() completes.  A "guard" is
00125       // used to make the copy also occur if an exception is thrown.
00126       TAO::PICurrent_Guard const pi_guard (server_request,
00127                                            false /* Copy RSC to TSC */);
00128 
00129       bool is_remote_request = !server_request.collocated ();
00130       TAO::ServerRequestInfo request_info (server_request,
00131                                            args,
00132                                            nargs,
00133                                            servant_upcall,
00134                                            exceptions,
00135                                            nexceptions);
00136 
00137       for (size_t i = 0 ; i < server_request.interceptor_count (); ++i)
00138         {
00139           ServerRequestInterceptor_List::RegisteredInterceptor& registered =
00140             this->interceptor_list_.registered_interceptor (i);
00141 
00142           if (registered.details_.should_be_processed (is_remote_request))
00143             {
00144               registered.interceptor_->
00145                 receive_request_service_contexts (&request_info);
00146             }
00147         }
00148     }
00149   catch (const ::PortableInterceptor::ForwardRequest& exc)
00150     {
00151       server_request.forward_location (exc.forward.in ());
00152       server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
00153       server_request.reply_status (GIOP::LOCATION_FORWARD);
00154       (void) this->send_other (server_request,
00155                                args,
00156                                nargs,
00157                                servant_upcall,
00158                                exceptions,
00159                                nexceptions);
00160     }
00161 }
00162 
00163 #elif TAO_HAS_EXTENDED_FT_INTERCEPTORS == 0
00164 
00165 /// NOTE: Yes, we have two versions of this. This is easier than
00166 /// messing around things in the same function, which is harder to
00167 /// read and could make the code buggier.
00168 void
00169 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request_service_contexts (
00170   TAO_ServerRequest &server_request,
00171   TAO::Argument * const args[],
00172   size_t nargs,
00173   void * servant_upcall,
00174   CORBA::TypeCode_ptr const * exceptions,
00175   CORBA::ULong nexceptions)
00176 {
00177   // This method implements one of the "starting" server side
00178   // interception point if extended interceptors are not in place.
00179 
00180   try
00181     {
00182       // Copy the request scope current (RSC) to the thread scope
00183       // current (TSC) upon leaving this scope, i.e. just after the
00184       // receive_request_service_contexts() completes.  A "guard" is
00185       // used to make the copy also occur if an exception is thrown.
00186       TAO::PICurrent_Guard const pi_guard (server_request,
00187                                            false /* Copy RSC to TSC */);
00188 
00189       bool is_remote_request = !server_request.collocated ();
00190 
00191       TAO::ServerRequestInfo request_info (server_request,
00192                                            args,
00193                                            nargs,
00194                                            servant_upcall,
00195                                            exceptions,
00196                                            nexceptions);
00197 
00198       for (size_t i = 0 ; i < this->interceptor_list_.size(); ++i)
00199         {
00200           ServerRequestInterceptor_List::RegisteredInterceptor& registered =
00201             this->interceptor_list_.registered_interceptor (i);
00202 
00203           if (registered.details_.should_be_processed (is_remote_request))
00204             {
00205               registered.interceptor_->
00206                 receive_request_service_contexts (&request_info);
00207             }
00208 
00209           // The starting interception point completed successfully.
00210           // Push the interceptor on to the flow stack.
00211           ++server_request.interceptor_count ();
00212         }
00213     }
00214   catch (const ::PortableInterceptor::ForwardRequest& exc)
00215     {
00216       server_request.forward_location (exc.forward.in ());
00217       server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
00218       server_request.reply_status (GIOP::LOCATION_FORWARD);
00219       (void) this->send_other (server_request,
00220                                args,
00221                                nargs,
00222                                servant_upcall,
00223                                exceptions,
00224                                nexceptions);
00225     }
00226 }
00227 
00228 #endif /*TAO_HAS_EXTENDED_FT_INTERCEPTORS*/
00229 
00230 void
00231 TAO::ServerRequestInterceptor_Adapter_Impl::receive_request (
00232   TAO_ServerRequest &server_request,
00233   TAO::Argument * const args[],
00234   size_t nargs,
00235   void * servant_upcall,
00236   CORBA::TypeCode_ptr const * exceptions,
00237   CORBA::ULong nexceptions
00238   )
00239 {
00240   // This method implements an "intermediate" server side interception
00241   // point.  Interceptors are invoked in the same order they were
00242   // pushed on to the flow stack.
00243 
00244   if (this->interceptor_list_.size() != server_request.interceptor_count ())
00245     {
00246       // This method (i.e. the receive_request() interception point)
00247       // should only be invoked if all of the interceptors registered
00248       // with the ORB were pushed on to the flow stack by one of the
00249       // starting endpoints (such as
00250       // receive_request_service_contexts()).  If the above condition
00251       // evaluates to "true," then it is likely that a starting
00252       // interception point was never invoked.  This is of course, an
00253       // internal error that must be corrected.
00254       throw ::CORBA::INTERNAL ();
00255     }
00256 
00257   TAO::ServerRequestInfo request_info (server_request,
00258                                        args,
00259                                        nargs,
00260                                        servant_upcall,
00261                                        exceptions,
00262                                        nexceptions);
00263 
00264   try
00265     {
00266       bool is_remote_request = !server_request.collocated ();
00267 
00268       for (size_t i = 0; i < server_request.interceptor_count (); ++i)
00269         {
00270           ServerRequestInterceptor_List::RegisteredInterceptor& registered =
00271             this->interceptor_list_.registered_interceptor (i);
00272 
00273           if (registered.details_.should_be_processed (is_remote_request))
00274             {
00275               registered.interceptor_->receive_request (&request_info);
00276             }
00277 
00278           // Note that no interceptors are pushed on to or popped off
00279           // of the flow stack in this interception point since it is
00280           // an intermediate interception point.
00281         }
00282     }
00283   catch (const ::PortableInterceptor::ForwardRequest& exc)
00284     {
00285       server_request.forward_location (exc.forward.in ());
00286       server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
00287       server_request.reply_status (GIOP::LOCATION_FORWARD);
00288       this->send_other (server_request,
00289                         args,
00290                         nargs,
00291                         servant_upcall,
00292                         exceptions,
00293                         nexceptions);
00294     }
00295 
00296 }
00297 
00298 void
00299 TAO::ServerRequestInterceptor_Adapter_Impl::send_reply (
00300   TAO_ServerRequest &server_request,
00301   TAO::Argument * const args[],
00302   size_t nargs,
00303   void * servant_upcall,
00304   CORBA::TypeCode_ptr const * exceptions,
00305   CORBA::ULong nexceptions)
00306 {
00307   // This is an "ending" interception point so we only process the
00308   // interceptors pushed on to the flow stack.
00309 
00310   bool const is_remote_request = !server_request.collocated ();
00311 
00312   // Notice that the interceptors are processed in the opposite order
00313   // they were pushed onto the stack since this is an "ending"
00314   // interception point.
00315 
00316   TAO::ServerRequestInfo request_info (server_request,
00317                                        args,
00318                                        nargs,
00319                                        servant_upcall,
00320                                        exceptions,
00321                                        nexceptions);
00322 
00323   // Unwind the stack.
00324   size_t const len = server_request.interceptor_count ();
00325   for (size_t i = 0; i < len; ++i)
00326     {
00327       // Pop the interceptor off of the flow stack before it is
00328       // invoked.  This is necessary to prevent an interceptor already
00329       // invoked in this "ending" interception point from being
00330       // invoked in another "ending" interception point.
00331       --server_request.interceptor_count ();
00332 
00333       ServerRequestInterceptor_List::RegisteredInterceptor& registered =
00334         this->interceptor_list_.registered_interceptor (
00335           server_request.interceptor_count ());
00336 
00337       if (registered.details_.should_be_processed (is_remote_request))
00338         {
00339           registered.interceptor_->send_reply (&request_info);
00340         }
00341     }
00342 
00343   // The send_reply() interception point does not raise a
00344   // PortableInterceptor::ForwardRequest exception so there is no need
00345   // to attempt to catch it here.
00346 }
00347 
00348 void
00349 TAO::ServerRequestInterceptor_Adapter_Impl::send_exception (
00350   TAO_ServerRequest &server_request,
00351   TAO::Argument * const args[],
00352   size_t nargs,
00353   void * servant_upcall,
00354   CORBA::TypeCode_ptr const * exceptions,
00355   CORBA::ULong nexceptions)
00356 {
00357   // This is an "ending" server side interception point so we only
00358   // process the interceptors pushed on to the flow stack.
00359 
00360   bool is_remote_request = !server_request.collocated ();
00361 
00362   // Notice that the interceptors are processed in the opposite order
00363   // they were pushed onto the stack since this is an "ending" server
00364   // side interception point.
00365 
00366   TAO::ServerRequestInfo request_info (server_request,
00367                                        args,
00368                                        nargs,
00369                                        servant_upcall,
00370                                        exceptions,
00371                                        nexceptions);
00372 
00373   try
00374     {
00375       // Unwind the flow stack.
00376       size_t const len = server_request.interceptor_count ();
00377       for (size_t i = 0; i < len; ++i)
00378         {
00379           // Pop the interceptor off of the flow stack before it is
00380           // invoked.  This is necessary to prevent an interceptor
00381           // already invoked in this "ending" interception point from
00382           // being invoked in another "ending" interception point.
00383           --server_request.interceptor_count ();
00384 
00385           ServerRequestInterceptor_List::RegisteredInterceptor& registered =
00386             this->interceptor_list_.registered_interceptor (
00387               server_request.interceptor_count ());
00388 
00389           if (registered.details_.should_be_processed (is_remote_request))
00390             {
00391               registered.interceptor_->send_exception (&request_info);
00392             }
00393         }
00394     }
00395   catch (const ::PortableInterceptor::ForwardRequest& exc)
00396     {
00397       server_request.forward_location (exc.forward.in ());
00398       server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
00399       server_request.reply_status (GIOP::LOCATION_FORWARD);
00400       this->send_other (server_request,
00401                         args,
00402                         nargs,
00403                         servant_upcall,
00404                         exceptions,
00405                         nexceptions);
00406     }
00407   catch ( ::CORBA::Exception& ex)
00408     {
00409       // The send_exception() interception point in the remaining
00410       // interceptors must be called so call this method (not the
00411       // interceptor's corresponding method) recursively.  The call is
00412       // made recursively since the caught exception must survive
00413       // until the remaining interceptors have been called.
00414       //
00415       // Note that the recursion will stop once the flow stack size
00416       // drops to zero, i.e., once each interceptor has been invoked.
00417       // This prevents infinite recursion from occuring.
00418 
00419       server_request.caught_exception (&ex);
00420 
00421       this->send_exception (server_request,
00422                             args,
00423                             nargs,
00424                             servant_upcall,
00425                             exceptions,
00426                             nexceptions);
00427 
00428       PortableInterceptor::ReplyStatus status =
00429         server_request.pi_reply_status ();
00430 
00431       // Only re-throw the exception if it hasn't been transformed by
00432       // the send_exception() interception point (e.g. to a
00433       // LOCATION_FORWARD).
00434       if (status == PortableInterceptor::SYSTEM_EXCEPTION
00435           || status == PortableInterceptor::USER_EXCEPTION)
00436         throw;
00437     }
00438 }
00439 
00440 void
00441 TAO::ServerRequestInterceptor_Adapter_Impl::send_other (
00442   TAO_ServerRequest &server_request,
00443   TAO::Argument * const args[],
00444   size_t nargs,
00445   void * servant_upcall,
00446   CORBA::TypeCode_ptr const * exceptions,
00447   CORBA::ULong nexceptions)
00448 {
00449   // This is an "ending" server side interception point so we only
00450   // process the interceptors pushed on to the flow stack.
00451 
00452   bool is_remote_request = !server_request.collocated ();
00453 
00454   TAO::ServerRequestInfo request_info (server_request,
00455                                        args,
00456                                        nargs,
00457                                        servant_upcall,
00458                                        exceptions,
00459                                        nexceptions);
00460 
00461   // Notice that the interceptors are processed in the opposite order
00462   // they were pushed onto the stack since this is an "ending" server
00463   // side interception point.
00464 
00465   try
00466     {
00467       // Unwind the flow stack.
00468       size_t const len = server_request.interceptor_count ();
00469       for (size_t i = 0; i < len; ++i)
00470         {
00471           // Pop the interceptor off of the flow stack before it is
00472           // invoked.  This is necessary to prevent an interceptor
00473           // already invoked in this "ending" interception point from
00474           // being invoked in another "ending" interception point.
00475           --server_request.interceptor_count ();
00476 
00477           ServerRequestInterceptor_List::RegisteredInterceptor& registered =
00478             this->interceptor_list_.registered_interceptor (
00479               server_request.interceptor_count ());
00480 
00481           if (registered.details_.should_be_processed (is_remote_request))
00482             {
00483               registered.interceptor_->send_other (&request_info);
00484             }
00485         }
00486     }
00487   catch (const ::PortableInterceptor::ForwardRequest& exc)
00488     {
00489       server_request.forward_location (exc.forward.in ());
00490       server_request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD);
00491       server_request.reply_status (GIOP::LOCATION_FORWARD);
00492       this->send_other (server_request,
00493                         args,
00494                         nargs,
00495                         servant_upcall,
00496                         exceptions,
00497                         nexceptions);
00498     }
00499 }
00500 
00501 void
00502 TAO::ServerRequestInterceptor_Adapter_Impl::add_interceptor (
00503   PortableInterceptor::ServerRequestInterceptor_ptr interceptor)
00504 {
00505   this->interceptor_list_.add_interceptor (interceptor);
00506 }
00507 
00508 void
00509 TAO::ServerRequestInterceptor_Adapter_Impl::add_interceptor (
00510   PortableInterceptor::ServerRequestInterceptor_ptr interceptor,
00511   const CORBA::PolicyList& policies)
00512 {
00513   this->interceptor_list_.add_interceptor (interceptor, policies);
00514 }
00515 
00516 void
00517 TAO::ServerRequestInterceptor_Adapter_Impl::destroy_interceptors (void)
00518 {
00519   this->interceptor_list_.destroy_interceptors ();
00520 }
00521 
00522 TAO::PICurrent_Impl *
00523 TAO::ServerRequestInterceptor_Adapter_Impl::allocate_pi_current (void)
00524 {
00525   TAO::PICurrent_Impl *pi = 0;
00526   ACE_NEW_RETURN (pi,
00527                   TAO::PICurrent_Impl,
00528                   pi);
00529   return pi;
00530 }
00531 
00532 void
00533 TAO::ServerRequestInterceptor_Adapter_Impl::deallocate_pi_current (
00534         TAO::PICurrent_Impl *picurrent)
00535 {
00536   delete picurrent;
00537 }
00538 
00539 void
00540 TAO::ServerRequestInterceptor_Adapter_Impl::execute_command (
00541   TAO_ServerRequest & server_request,
00542   TAO::Upcall_Command & command)
00543 {
00544   TAO::PICurrent_Guard const pi_guard (server_request,
00545                                        true  /* Copy TSC to RSC */);
00546 
00547   // The actual upcall.
00548   command.execute ();
00549 }
00550 
00551 TAO_END_VERSIONED_NAMESPACE_DECL
00552 
00553 #endif  /* TAO_HAS_INTERCEPTORS == 1 */

Generated on Tue Feb 2 17:42:14 2010 for TAO_PI_Server by  doxygen 1.4.7