Use =default for skeleton copy constructor
[ACE_TAO.git] / TAO / tao / Messaging / AMH_Response_Handler.cpp
blob9567e23fe2fdc1b3b60dac3e2d92c825f98c079c
1 #include "tao/Messaging/AMH_Response_Handler.h"
2 #include "tao/TAO_Server_Request.h"
3 #include "tao/Transport.h"
4 #include "tao/CDR.h"
5 #include "tao/ORB_Core.h"
6 #include "tao/ORB.h"
7 #include "tao/GIOP_Message_Base.h"
8 #include "tao/Pluggable_Messaging_Utils.h"
9 #include "tao/GIOP_Utils.h"
10 #include "tao/debug.h"
11 #include "tao/Buffer_Allocator_T.h"
12 #include "tao/SystemException.h"
13 #include "tao/PortableServer/ForwardRequestC.h"
15 #include "ace/Copy_Disabled.h"
17 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
19 TAO_AMH_Response_Handler::TAO_AMH_Response_Handler ()
20 : reply_status_ (GIOP::NO_EXCEPTION)
21 , mesg_base_ (0)
22 , request_id_ (0)
23 , response_expected_ (false)
24 , transport_ (nullptr)
25 , orb_core_ (nullptr)
26 , argument_flag_ (1)
27 , rh_reply_status_ (TAO_RS_UNINITIALIZED)
28 , allocator_ (nullptr)
32 TAO_AMH_Response_Handler::~TAO_AMH_Response_Handler ()
34 this->transport_->remove_reference ();
36 // Since we are destroying the object we put a huge lock around the
37 // whole destruction process (just paranoid).
39 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
41 if (!this->response_expected_) //oneway ?
43 return;
46 // If the ResponseHandler is being destroyed before a reply has
47 // been sent to the client, we send a system exception
48 // CORBA::NO_RESPONSE, with minor code to indicate the problem.
49 if (this->rh_reply_status_ == TAO_RS_SENT)
51 return;
55 // If sending the exception to the client fails, then we just give
56 // up, release the transport and return.
57 try
59 CORBA::NO_RESPONSE ex (CORBA::SystemException::_tao_minor_code
60 (TAO_AMH_REPLY_LOCATION_CODE,
61 EFAULT),
62 CORBA::COMPLETED_NO);
63 this->_tao_rh_send_exception (ex);
65 catch (...)
70 void
71 TAO_AMH_Response_Handler::init(TAO_ServerRequest &server_request,
72 TAO_AMH_BUFFER_ALLOCATOR* allocator)
74 mesg_base_ = server_request.mesg_base_;
75 request_id_ = server_request.request_id_;
76 response_expected_ = server_request.response_expected_;
77 transport_ = server_request.transport ();
78 orb_core_ = server_request.orb_core ();
79 allocator_ = allocator;
81 TAO_GIOP_Message_Version v;
82 server_request.outgoing()->get_version(v);
83 this->_tao_out.set_version(v.major, v.minor);
84 this->transport_->assign_translators (0, &this->_tao_out);
85 this->transport_->add_reference ();
88 void
89 TAO_AMH_Response_Handler::_tao_rh_init_reply ()
92 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
93 if (this->rh_reply_status_ != TAO_RS_UNINITIALIZED)
95 // Looks like someone is trying to call an AMH method
96 // more than once
98 // We assume that the servant has already processed the
99 // request and is now trying to send back the reply. Hence we
100 // say that the operation has completed but let the server
101 // anyway that it is not doing something right.
102 throw ::CORBA::BAD_INV_ORDER
103 (CORBA::SystemException::_tao_minor_code
104 (TAO_AMH_REPLY_LOCATION_CODE,
105 EEXIST),
106 CORBA::COMPLETED_YES);
110 // Construct our reply generator.
111 TAO_Pluggable_Reply_Params_Base reply_params;
112 reply_params.request_id_ = this->request_id_;
113 reply_params.service_context_notowned (&(this->reply_service_context_.service_info ()));
114 reply_params.argument_flag_ = this->argument_flag_;
115 reply_params.reply_status (this->reply_status_);
118 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
120 this->mesg_base_->generate_reply_header (this->_tao_out, reply_params);
122 // We are done initialising the reply
123 this->rh_reply_status_ = TAO_RS_INITIALIZED;
128 void
129 TAO_AMH_Response_Handler::_tao_rh_send_reply ()
132 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
134 // If the reply has not been initialised, raise an exception to the
135 // server-app saying it is not doing something right.
136 if (this->rh_reply_status_ != TAO_RS_INITIALIZED)
138 throw ::CORBA::BAD_INV_ORDER (
139 CORBA::SystemException::_tao_minor_code (
140 TAO_AMH_REPLY_LOCATION_CODE,
141 ENOTSUP),
142 CORBA::COMPLETED_YES);
144 this->rh_reply_status_ = TAO_RS_SENDING;
147 // Send the message.
148 int result = this->transport_->send_message (this->_tao_out,
151 TAO_Message_Semantics (TAO_Message_Semantics::TAO_REPLY));
153 if (result == -1)
155 if (TAO_debug_level > 0)
157 // No exception but some kind of error, yet a response
158 // is required.
159 TAOLIB_ERROR ((
160 LM_ERROR,
161 ACE_TEXT ("TAO: (%P|%t) %p: cannot send NO_EXCEPTION reply\n"),
162 ACE_TEXT ("TAO_AMH_Response_Handler::_tao_rh_send_reply")
168 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
169 this->rh_reply_status_ = TAO_RS_SENT;
173 void
174 TAO_AMH_Response_Handler::_tao_rh_send_exception (const CORBA::Exception &ex)
177 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
178 if (this->rh_reply_status_ != TAO_RS_UNINITIALIZED)
180 throw ::CORBA::BAD_INV_ORDER (
181 CORBA::SystemException::_tao_minor_code (
182 TAO_AMH_REPLY_LOCATION_CODE,
183 ENOTSUP),
184 CORBA::COMPLETED_YES);
186 this->rh_reply_status_ = TAO_RS_SENDING;
189 TAO_Pluggable_Reply_Params_Base reply_params;
190 reply_params.request_id_ = this->request_id_;
191 reply_params.svc_ctx_.length (0);
192 reply_params.service_context_notowned (&this->reply_service_context_.service_info ());
193 reply_params.argument_flag_ = true;
194 // @@ It appears as if there should be a more efficient way to do
195 // this: the caller already knows this because it is part of the
196 // ExceptionHolder information.
198 #if !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) && (TAO_HAS_MINIMUM_POA == 0)
199 const PortableServer::ForwardRequest *fr =
200 PortableServer::ForwardRequest::_downcast (&ex);
201 if (fr != 0)
203 reply_params.reply_status (GIOP::LOCATION_FORWARD);
204 if (this->mesg_base_->generate_reply_header (this->_tao_out,
205 reply_params) == -1)
207 throw ::CORBA::INTERNAL ();
209 this->_tao_out << fr->forward_reference;
211 else
212 #endif
214 if (CORBA::SystemException::_downcast (&ex))
216 reply_params.reply_status (GIOP::SYSTEM_EXCEPTION);
218 else
220 reply_params.reply_status (GIOP::USER_EXCEPTION);
222 if (this->mesg_base_->generate_exception_reply (this->_tao_out,
223 reply_params,
224 ex) == -1)
226 throw ::CORBA::INTERNAL ();
229 // Send the Exception
230 if (this->transport_->send_message (this->_tao_out,
233 TAO_Message_Semantics (TAO_Message_Semantics::TAO_REPLY)) == -1)
235 if (TAO_debug_level > 0)
236 TAOLIB_ERROR ((LM_ERROR,
237 ACE_TEXT ("TAO: (%P|%t|%N|%l): ")
238 ACE_TEXT ("TAO_AMH_Response_Handler:")
239 ACE_TEXT (" could not send exception reply\n")));
243 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
244 this->rh_reply_status_ = TAO_RS_SENT;
248 void
249 TAO_AMH_Response_Handler::_tao_rh_send_location_forward (CORBA::Object_ptr fwd,
250 CORBA::Boolean is_perm)
253 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
254 if (this->rh_reply_status_ != TAO_RS_UNINITIALIZED)
256 throw ::CORBA::BAD_INV_ORDER (
257 CORBA::SystemException::_tao_minor_code (
258 TAO_AMH_REPLY_LOCATION_CODE,
259 ENOTSUP),
260 CORBA::COMPLETED_YES);
262 this->rh_reply_status_ = TAO_RS_SENDING;
265 TAO_Pluggable_Reply_Params_Base reply_params;
266 reply_params.request_id_ = this->request_id_;
267 reply_params.svc_ctx_.length (0);
268 reply_params.service_context_notowned (&this->reply_service_context_.service_info ());
269 reply_params.argument_flag_ = true;
270 if (is_perm)
272 reply_params.reply_status (GIOP::LOCATION_FORWARD_PERM);
274 else
276 reply_params.reply_status (GIOP::LOCATION_FORWARD);
279 if (this->mesg_base_->generate_reply_header (this->_tao_out,
280 reply_params) == -1)
282 throw ::CORBA::INTERNAL ();
285 if (!(this->_tao_out << fwd))
287 if (TAO_debug_level > 0)
288 TAOLIB_ERROR ((LM_ERROR,
289 ACE_TEXT ("TAO (%P|%t) ERROR: Unable to marshal ")
290 ACE_TEXT ("forward reference.\n")));
291 return;
294 // Send the Exception
295 if (this->transport_->send_message (this->_tao_out,
298 TAO_Message_Semantics (TAO_Message_Semantics::TAO_REPLY)) == -1)
300 if (TAO_debug_level > 0)
301 TAOLIB_ERROR ((LM_ERROR,
302 ACE_TEXT ("TAO: (%P|%t|%N|%l): ")
303 ACE_TEXT ("TAO_AMH_Response_Handler: could not send ")
304 ACE_TEXT ("location forward reply\n")));
308 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
309 this->rh_reply_status_ = TAO_RS_SENT;
313 void
314 TAO_AMH_Response_Handler::_remove_ref ()
316 if (--this->refcount_ == 0)
318 if (this->allocator_)
320 TAO::TAO_Buffer_Allocator<TAO_AMH_Response_Handler, TAO_AMH_BUFFER_ALLOCATOR> allocator (this->allocator_);
322 allocator.release (this);
324 else
326 delete this;
331 namespace TAO
333 void
334 ARH_Refcount_Functor::operator () (TAO_AMH_Response_Handler *arh) noexcept
336 (void) arh->_remove_ref ();
340 TAO_END_VERSIONED_NAMESPACE_DECL