Upcall_Wrapper.cpp

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

Generated on Tue Feb 2 17:40:54 2010 for TAO_PortableServer by  doxygen 1.4.7