ServerInterceptorAdapter.cpp

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

Generated on Thu Nov 9 12:53:59 2006 for TAO_PI_Server by doxygen 1.3.6