Changes to attempt to silence bcc64x
[ACE_TAO.git] / TAO / tao / PortableServer / Upcall_Wrapper.cpp
blob7b1036012b4a179b86fba345c8ec73ccd4783698
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"
15 #include "tao/CDR.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
23 void
24 TAO::Upcall_Wrapper::upcall (TAO_ServerRequest & server_request,
25 TAO::Argument * const args[],
26 size_t nargs,
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
70 // args instead.
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 */
79 try
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,
87 the_args,
88 the_nargs,
89 servant_upcall,
90 exceptions,
91 nexceptions);
94 // Don't bother performing the upcall if an interceptor caused a
95 // location forward.
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);
103 else
104 #endif /* TAO_HAS_INTERCEPTORS */
106 // The actual upcall.
107 command.execute ();
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);
118 else
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,
136 the_args,
137 the_nargs,
138 servant_upcall,
139 exceptions,
140 nexceptions);
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,
160 the_args,
161 the_nargs,
162 servant_upcall,
163 exceptions,
164 nexceptions);
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);
180 return;
182 else
184 throw;
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);
215 void
216 TAO::Upcall_Wrapper::pre_upcall (TAO_InputCDR & cdr,
217 TAO::Argument * const * args,
218 size_t nargs)
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.
226 try {
227 TAO::Argument * const * const begin = args + 1; // Skip the return value.
228 TAO::Argument * const * const end = args + nargs;
229 errno = 0;
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 ();
240 catch (...) {
241 cdr.reset_vt_indirect_maps ();
242 throw;
246 void
247 TAO::Upcall_Wrapper::post_upcall (TAO_ServerRequest& server_request,
248 TAO::Argument * const * args,
249 size_t nargs)
251 TAO_OutputCDR & cdr = (*server_request.outgoing ());
252 TAO::Argument * const * const begin = args;
253 TAO::Argument * const * const end = args + nargs;
255 try {
256 errno = 0;
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 ();
270 #endif
272 catch (...) {
273 #ifdef TAO_HAS_VALUETYPE_OUT_INDIRECTION
274 cdr.reset_vt_indirect_maps ();
275 #endif
276 throw;
280 TAO_END_VERSIONED_NAMESPACE_DECL