Upcall_Wrapper.cpp

Go to the documentation of this file.
00001 // Upcall_Wrapper.cpp,v 1.17 2006/04/20 12:37:17 jwillemsen Exp
00002 
00003 #include "tao/PortableServer/Upcall_Wrapper.h"
00004 #include "tao/PortableServer/Upcall_Command.h"
00005 
00006 #if TAO_HAS_INTERCEPTORS == 1
00007 # include "tao/ServerRequestInterceptor_Adapter.h"
00008 # include "tao/PortableInterceptorC.h"
00009 # include "tao/ORB_Core.h"
00010 #endif  /* TAO_HAS_INTERCEPTORS == 1 */
00011 
00012 #include "tao/PortableInterceptor.h"
00013 
00014 #include "tao/TAO_Server_Request.h"
00015 #include "tao/CDR.h"
00016 #include "tao/Argument.h"
00017 #include "tao/operation_details.h"
00018 #include "ace/Log_Msg.h"
00019 
00020 ACE_RCSID (PortableServer,
00021            Upcall_Wrapper,
00022            "Upcall_Wrapper.cpp,v 1.17 2006/04/20 12:37:17 jwillemsen Exp")
00023 
00024 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00025 
00026 void
00027 TAO::Upcall_Wrapper::upcall (TAO_ServerRequest & server_request,
00028                              TAO::Argument * const args[],
00029                              size_t nargs,
00030                              TAO::Upcall_Command & command
00031 
00032 #if TAO_HAS_INTERCEPTORS == 1
00033                              , void * servant_upcall
00034                              , CORBA::TypeCode_ptr const * exceptions
00035                              , CORBA::ULong nexceptions
00036 #endif  /* TAO_HAS_INTERCEPTORS == 1 */
00037 
00038                              ACE_ENV_ARG_DECL
00039                              )
00040 {
00041   if (server_request.incoming ())
00042     {
00043       this->pre_upcall (*server_request.incoming (),
00044                         args,
00045                         nargs
00046                         ACE_ENV_ARG_PARAMETER);
00047       ACE_CHECK;
00048     }
00049 
00050 #if TAO_HAS_INTERCEPTORS == 1
00051 
00052   // Make sure that, for the collocated case, we use the client-side
00053   // arguments.  For the non-collocated case, we will use the server-side
00054   // arguments since they got set up in our pre_upcall() method.  Note that
00055   // our pre_upcall() method doesn't get invoked in the collocated case,
00056   // and is the reason why we need to provide the client-side args instead
00057   // of the (never set or initialized) server-side args.
00058   //
00059   // Before the following logic was added, the
00060   // $TAO_ROOT/tests/Portable_Interceptors/Collocated/run_test.pl
00061   // showed that the server-side request interceptor was getting bogus
00062   // values when it took a look at the request arguments.  Some
00063   // additional testing revealed that this only occurred in the
00064   // collocated request case.
00065 
00066   // By default, we assume that we will use the server-side args.
00067   TAO::Argument * const * the_args = args;
00068   size_t the_nargs = nargs;
00069 
00070   if (server_request.collocated())
00071     {
00072       // It is a collocated request so we need to use the client-side
00073       // args instead.
00074       the_args = server_request.operation_details()->args();
00075       the_nargs = server_request.operation_details()->args_num();
00076     }
00077 
00078   TAO::ServerRequestInterceptor_Adapter *interceptor_adapter =
00079     server_request.orb_core ()->serverrequestinterceptor_adapter ();
00080 
00081   ACE_TRY
00082     {
00083       {
00084         if (interceptor_adapter != 0)
00085           {
00086             // Invoke intermediate server side interception points.
00087             interceptor_adapter->receive_request (server_request,
00088                                                   the_args,
00089                                                   the_nargs,
00090                                                   servant_upcall,
00091                                                   exceptions,
00092                                                   nexceptions
00093                                                   ACE_ENV_ARG_PARAMETER);
00094             ACE_TRY_CHECK;
00095           }
00096 
00097         // Don't bother performing the upcall if an interceptor caused a
00098         // location forward.
00099         CORBA::Object_var forward_to = server_request.forward_location ();
00100         if (CORBA::is_nil (forward_to.in ()))
00101           {
00102             if (interceptor_adapter != 0)
00103               {
00104                 interceptor_adapter->execute_command (server_request,
00105                                                       command
00106                                                       ACE_ENV_ARG_PARAMETER);
00107                 ACE_TRY_CHECK;
00108               }
00109             else
00110 #endif /* TAO_HAS_INTERCEPTORS */
00111               {
00112                 // The actual upcall.
00113                 command.execute (ACE_ENV_SINGLE_ARG_PARAMETER);
00114                 TAO_INTERCEPTOR_CHECK;
00115               }
00116 
00117 #if TAO_HAS_INTERCEPTORS == 1
00118           }
00119       }
00120 
00121       if (interceptor_adapter == 0)
00122         {
00123           server_request.reply_status (PortableInterceptor::SUCCESSFUL);
00124         }
00125       else
00126         {
00127           // Do not execute the send_reply() interception point if an
00128           // interceptor caused a location forward.  The send_other()
00129           // interception point should already have been executed by the
00130           // ServerRequestInterceptor_Adapter object.
00131           //
00132           // It should actually be safe to call this interception point,
00133           // regardless, since the interceptor flow stack should have been
00134           // emptied by the send_other() interception point.  Note that
00135           // we'd still need to avoid resetting the reply status to
00136           // SUCCESSFUL, however.
00137           CORBA::Object_var forward_to_after = server_request.forward_location ();
00138           if (CORBA::is_nil (forward_to_after.in ()))
00139             {
00140               // No location forward by interceptors and successful upcall.
00141               server_request.reply_status (PortableInterceptor::SUCCESSFUL);
00142               interceptor_adapter->send_reply (server_request,
00143                                                the_args,
00144                                                the_nargs,
00145                                                servant_upcall,
00146                                                exceptions,
00147                                                nexceptions
00148                                                ACE_ENV_ARG_PARAMETER);
00149               ACE_TRY_CHECK;
00150             }
00151         }
00152     }
00153   ACE_CATCHANY
00154     {
00155       // Just assume the current exception is a system exception, the
00156       // status can only change when the interceptor changes this
00157       // and this is only done when the sri_adapter is available. If we
00158       // don't have an sri_adapter we just rethrow the exception
00159       PortableInterceptor::ReplyStatus status =
00160         PortableInterceptor::SYSTEM_EXCEPTION;
00161 
00162       server_request.caught_exception (&ACE_ANY_EXCEPTION);
00163 
00164       if (interceptor_adapter != 0)
00165         {
00166           interceptor_adapter->send_exception (server_request,
00167                                                the_args,
00168                                                the_nargs,
00169                                                servant_upcall,
00170                                                exceptions,
00171                                                nexceptions
00172                                                ACE_ENV_ARG_PARAMETER);
00173           ACE_TRY_CHECK;
00174 
00175           status =
00176             server_request.reply_status ();
00177         }
00178 
00179       if (status == PortableInterceptor::SYSTEM_EXCEPTION
00180           || status == PortableInterceptor::USER_EXCEPTION)
00181         {
00182           ACE_RE_THROW;
00183         }
00184     }
00185 # if defined (ACE_HAS_EXCEPTIONS) \
00186   && defined (ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS)
00187   ACE_CATCHALL
00188     {
00189       // Just assume the current exception is a system exception, the
00190       // status can only change when the interceptor changes this
00191       // and this is only done when the sri_adapter is available. If we
00192       // don't have an sri_adapter we just rethrow the exception
00193       PortableInterceptor::ReplyStatus status =
00194         PortableInterceptor::SYSTEM_EXCEPTION;
00195 
00196       CORBA::UNKNOWN ex;
00197 
00198       server_request.caught_exception (&ex);
00199 
00200       if (interceptor_adapter != 0)
00201         {
00202           interceptor_adapter->send_exception (server_request,
00203                                                the_args,
00204                                                the_nargs,
00205                                                servant_upcall,
00206                                                exceptions,
00207                                                nexceptions
00208                                                ACE_ENV_ARG_PARAMETER);
00209           ACE_TRY_CHECK;
00210 
00211           status =
00212             server_request.reply_status ();
00213         }
00214 
00215       if (status == PortableInterceptor::SYSTEM_EXCEPTION)
00216         ACE_TRY_THROW (ex);
00217     }
00218 # endif  /* ACE_HAS_EXCEPTIONS && ACE_HAS_BROKEN_UNEXPECTED_EXCEPTIONS */
00219   ACE_ENDTRY;
00220   ACE_CHECK;
00221 #endif  /* TAO_HAS_INTERCEPTORS == 1 */
00222 
00223   if (server_request.response_expected ()
00224       && !server_request.sync_with_server ())
00225     {
00226       server_request.init_reply ();
00227     }
00228 
00229 #if TAO_HAS_INTERCEPTORS == 1
00230   // Don't bother marshaling inout/out/return values if an interceptor
00231   // caused a location forward.
00232  CORBA::Object_var forward_to_end = server_request.forward_location ();
00233   if (CORBA::is_nil (forward_to_end.in ()))
00234 #endif  /* TAO_HAS_INTERCEPTORS == 1 */
00235     {
00236       if (server_request.outgoing ())
00237         {
00238           this->post_upcall (*server_request.outgoing (),
00239                              args,
00240                              nargs
00241                              ACE_ENV_ARG_PARAMETER);
00242           ACE_CHECK;
00243         }
00244     }
00245 }
00246 
00247 void
00248 TAO::Upcall_Wrapper::pre_upcall (TAO_InputCDR & cdr,
00249                                  TAO::Argument * const * args,
00250                                  size_t nargs
00251                                  ACE_ENV_ARG_DECL)
00252 {
00253   // Demarshal the operation "in" and "inout" arguments, if any.
00254 
00255   // NOTE:  The TAO::Argument corresponding to the return value is
00256   //        always the first element in the array, regardless of
00257   //        whether or not the return type is void.
00258 
00259   ACE_ASSERT (nargs != 0);
00260 
00261   TAO::Argument * const * const begin = args + 1;  // Skip the return value.
00262   TAO::Argument * const * const end   = args + nargs;
00263 
00264   for (TAO::Argument * const * i = begin; i != end; ++i)
00265     {
00266       if (!(*i)->demarshal (cdr))
00267         {
00268           TAO_InputCDR::throw_skel_exception (errno
00269                                               ACE_ENV_ARG_PARAMETER);
00270           ACE_CHECK;
00271         }
00272     }
00273 }
00274 
00275 void
00276 TAO::Upcall_Wrapper::post_upcall (TAO_OutputCDR & cdr,
00277                                   TAO::Argument * const * args,
00278                                   size_t nargs
00279                                   ACE_ENV_ARG_DECL)
00280 {
00281   // Marshal the operation "inout" and "out" arguments and return
00282   // value, if any.
00283 
00284   TAO::Argument * const * const begin = args;
00285   TAO::Argument * const * const end   = args + nargs;
00286 
00287   for (TAO::Argument * const * i = begin; i != end; ++i)
00288     {
00289       if (!(*i)->marshal (cdr))
00290         {
00291           TAO_OutputCDR::throw_skel_exception (errno
00292                                                ACE_ENV_ARG_PARAMETER);
00293           ACE_CHECK;
00294         }
00295     }
00296 
00297  // Reply body marshaling completed.  No other fragments to send.
00298   cdr.more_fragments (false);
00299 }
00300 
00301 TAO_END_VERSIONED_NAMESPACE_DECL
00302 

Generated on Thu Nov 9 12:40:45 2006 for TAO_PortableServer by doxygen 1.3.6