1 #include "tao/PortableServer/Upcall_Wrapper.h"
2 #include "tao/PortableServer/Upcall_Command.h"
3 #include "tao/PortableServer/Collocated_Arguments_Converter.h"
4 #include "tao/SystemException.h"
6 #if TAO_HAS_INTERCEPTORS == 1
7 # include "tao/ServerRequestInterceptor_Adapter.h"
8 # include "tao/ORB_Core.h"
9 #endif /* TAO_HAS_INTERCEPTORS == 1 */
11 #include "tao/PortableInterceptorC.h"
12 #include "tao/PortableInterceptor.h"
14 #include "tao/TAO_Server_Request.h"
16 #include "tao/Argument.h"
17 #include "tao/operation_details.h"
18 #include "ace/Log_Msg.h"
19 #include "tao/debug.h"
21 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
24 TAO::Upcall_Wrapper::upcall (TAO_ServerRequest
& server_request
,
25 TAO::Argument
* const args
[],
27 TAO::Upcall_Command
& command
28 #if TAO_HAS_INTERCEPTORS == 1
29 , TAO::Portable_Server::Servant_Upcall
*servant_upcall
30 , CORBA::TypeCode_ptr
const * exceptions
31 , CORBA::ULong nexceptions
32 #endif /* TAO_HAS_INTERCEPTORS == 1 */
35 if (server_request
.collocated ()
36 && server_request
.operation_details ()->cac () != 0)
38 server_request
.operation_details ()->cac ()->convert_request (
39 server_request
, args
, nargs
);
42 if (server_request
.incoming ())
44 this->pre_upcall (*server_request
.incoming (), args
, nargs
);
47 #if TAO_HAS_INTERCEPTORS == 1
49 // Make sure that, for the collocated case, we use the client-side
50 // arguments. For the non-collocated case, we will use the server-side
51 // arguments since they got set up in our pre_upcall() method. Note that
52 // our pre_upcall() method doesn't get invoked in the collocated case,
53 // and is the reason why we need to provide the client-side args instead
54 // of the (never set or initialized) server-side args.
56 // Before the following logic was added, the
57 // $TAO_ROOT/tests/Portable_Interceptors/Collocated/run_test.pl
58 // showed that the server-side request interceptor was getting bogus
59 // values when it took a look at the request arguments. Some
60 // additional testing revealed that this only occurred in the
61 // collocated request case.
63 // By default, we assume that we will use the server-side args.
64 TAO::Argument
* const * the_args
= args
;
65 size_t the_nargs
= nargs
;
67 if (server_request
.collocated())
69 // It is a collocated request so we need to use the client-side
71 the_args
= server_request
.operation_details()->args();
72 the_nargs
= server_request
.operation_details()->args_num();
75 TAO::ServerRequestInterceptor_Adapter
*interceptor_adapter
=
76 server_request
.orb_core ()->serverrequestinterceptor_adapter ();
77 #endif /* TAO_HAS_INTERCEPTORS */
82 #if TAO_HAS_INTERCEPTORS == 1
83 if (interceptor_adapter
!= 0)
85 // Invoke intermediate server side interception points.
86 interceptor_adapter
->receive_request (server_request
,
94 // Don't bother performing the upcall if an interceptor caused a
96 CORBA::Object_var forward_to
= server_request
.forward_location ();
97 if (!server_request
.is_forwarded ())
99 if (interceptor_adapter
!= 0)
101 interceptor_adapter
->execute_command (server_request
, command
);
104 #endif /* TAO_HAS_INTERCEPTORS */
106 // The actual upcall.
109 #if TAO_HAS_INTERCEPTORS == 1
111 #endif /* TAO_HAS_INTERCEPTORS */
113 #if TAO_HAS_INTERCEPTORS == 1
114 if (interceptor_adapter
== 0)
116 server_request
.pi_reply_status (PortableInterceptor::SUCCESSFUL
);
120 // Do not execute the send_reply() interception point if an
121 // interceptor caused a location forward. The send_other()
122 // interception point should already have been executed by the
123 // ServerRequestInterceptor_Adapter object.
125 // It should actually be safe to call this interception point,
126 // regardless, since the interceptor flow stack should have been
127 // emptied by the send_other() interception point. Note that
128 // we'd still need to avoid resetting the reply status to
129 // SUCCESSFUL, however.
130 CORBA::Object_var forward_to_after
= server_request
.forward_location ();
131 if (!server_request
.is_forwarded ())
133 // No location forward by interceptors and successful upcall.
134 server_request
.pi_reply_status (PortableInterceptor::SUCCESSFUL
);
135 interceptor_adapter
->send_reply (server_request
,
143 #endif /* TAO_HAS_INTERCEPTORS */
145 catch ( ::CORBA::Exception
& ex
)
147 // Just assume the current exception is a system exception, the
148 // status can only change when the interceptor changes this
149 // and this is only done when the sri_adapter is available. If we
150 // don't have an sri_adapter we just rethrow the exception
151 PortableInterceptor::ReplyStatus status
=
152 PortableInterceptor::SYSTEM_EXCEPTION
;
154 #if TAO_HAS_INTERCEPTORS == 1
155 server_request
.caught_exception (&ex
);
157 if (interceptor_adapter
!= 0)
159 interceptor_adapter
->send_exception (server_request
,
166 status
= server_request
.pi_reply_status ();
168 #endif /* TAO_HAS_INTERCEPTORS */
170 if (status
== PortableInterceptor::SYSTEM_EXCEPTION
171 || status
== PortableInterceptor::USER_EXCEPTION
)
173 if (server_request
.collocated ()
174 && server_request
.operation_details ()->cac () != 0)
176 // If we have a cac it will handle the exception and no
177 // need to do any further processing
178 server_request
.operation_details ()->cac ()->handle_corba_exception (
179 server_request
, &ex
);
189 if (server_request
.response_expected ()
190 && !server_request
.sync_with_server ())
192 server_request
.init_reply ();
195 #if TAO_HAS_INTERCEPTORS == 1
196 // Don't bother marshaling inout/out/return values if an interceptor
197 // caused a location forward.
198 if (!server_request
.is_forwarded ())
199 #endif /* TAO_HAS_INTERCEPTORS == 1 */
201 if (server_request
.outgoing ())
203 this->post_upcall (server_request
, args
, nargs
);
207 if (server_request
.collocated ()
208 && server_request
.operation_details ()->cac () != 0)
210 server_request
.operation_details ()->cac ()->convert_reply (
211 server_request
, args
, nargs
);
216 TAO::Upcall_Wrapper::pre_upcall (TAO_InputCDR
& cdr
,
217 TAO::Argument
* const * args
,
220 // Demarshal the operation "in" and "inout" arguments, if any.
222 // NOTE: The TAO::Argument corresponding to the return value is
223 // always the first element in the array, regardless of
224 // whether or not the return type is void.
227 TAO::Argument
* const * const begin
= args
+ 1; // Skip the return value.
228 TAO::Argument
* const * const end
= args
+ nargs
;
230 for (TAO::Argument
* const * i
= begin
; i
!= end
; ++i
)
232 if (!(*i
)->demarshal (cdr
))
234 TAO_InputCDR::throw_skel_exception (errno
);
238 cdr
.reset_vt_indirect_maps ();
241 cdr
.reset_vt_indirect_maps ();
247 TAO::Upcall_Wrapper::post_upcall (TAO_ServerRequest
& server_request
,
248 TAO::Argument
* const * args
,
251 TAO_OutputCDR
& cdr
= (*server_request
.outgoing ());
252 TAO::Argument
* const * const begin
= args
;
253 TAO::Argument
* const * const end
= args
+ nargs
;
257 for (TAO::Argument
* const * i
= begin
; i
!= end
; ++i
)
259 if (!(*i
)->marshal (cdr
))
261 TAO_OutputCDR::throw_skel_exception (errno
);
265 // Reply body marshaling completed. No other fragments to send.
266 cdr
.more_fragments (false);
268 #ifdef TAO_HAS_VALUETYPE_OUT_INDIRECTION
269 cdr
.reset_vt_indirect_maps ();
273 #ifdef TAO_HAS_VALUETYPE_OUT_INDIRECTION
274 cdr
.reset_vt_indirect_maps ();
280 TAO_END_VERSIONED_NAMESPACE_DECL