00001
00002
00003 #include "tao/Messaging/AMH_Response_Handler.h"
00004 #include "tao/TAO_Server_Request.h"
00005 #include "tao/Transport.h"
00006 #include "tao/CDR.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/ORB.h"
00009 #include "tao/GIOP_Message_Base.h"
00010 #include "tao/Pluggable_Messaging_Utils.h"
00011 #include "tao/GIOP_Utils.h"
00012 #include "tao/debug.h"
00013 #include "tao/Buffer_Allocator_T.h"
00014 #include "tao/SystemException.h"
00015
00016 #include "ace/Copy_Disabled.h"
00017
00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00019
00020 TAO_AMH_Response_Handler::TAO_AMH_Response_Handler ()
00021 : reply_status_ (GIOP::NO_EXCEPTION)
00022 , mesg_base_ (0)
00023 , request_id_ (0)
00024 , transport_ (0)
00025 , orb_core_ (0)
00026 , argument_flag_ (1)
00027 , rh_reply_status_ (TAO_RS_UNINITIALIZED)
00028 , allocator_ (0)
00029 {
00030 }
00031
00032 TAO_AMH_Response_Handler::~TAO_AMH_Response_Handler (void)
00033 {
00034 this->transport_->remove_reference ();
00035
00036
00037
00038 {
00039 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
00040
00041 if (this->response_expected_ == 0)
00042 {
00043 return;
00044 }
00045
00046
00047
00048
00049 if (this->rh_reply_status_ == TAO_RS_SENT)
00050 {
00051 return;
00052 }
00053 }
00054
00055
00056
00057 try
00058 {
00059 CORBA::NO_RESPONSE ex (CORBA::SystemException::_tao_minor_code
00060 (TAO_AMH_REPLY_LOCATION_CODE,
00061 EFAULT),
00062 CORBA::COMPLETED_NO);
00063 this->_tao_rh_send_exception (ex);
00064 }
00065 catch (...)
00066 {
00067 }
00068 }
00069
00070 void
00071 TAO_AMH_Response_Handler::init(TAO_ServerRequest &server_request,
00072 TAO_AMH_BUFFER_ALLOCATOR* allocator)
00073 {
00074 mesg_base_ = server_request.mesg_base_;
00075 request_id_ = server_request.request_id_;
00076 response_expected_ = server_request.response_expected_;
00077 transport_ = server_request.transport ();
00078 orb_core_ = server_request.orb_core ();
00079 allocator_ = allocator;
00080
00081 TAO_GIOP_Message_Version v;
00082 server_request.outgoing()->get_version(v);
00083 this->_tao_out.set_version(v.major, v.minor);
00084 this->transport_->assign_translators (0, &this->_tao_out);
00085 this->transport_->add_reference ();
00086 }
00087
00088 void
00089 TAO_AMH_Response_Handler::_tao_rh_init_reply (void)
00090 {
00091 {
00092 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
00093 if (this->rh_reply_status_ != TAO_RS_UNINITIALIZED)
00094 {
00095
00096
00097
00098
00099
00100
00101
00102 throw ::CORBA::BAD_INV_ORDER
00103 (CORBA::SystemException::_tao_minor_code
00104 (TAO_AMH_REPLY_LOCATION_CODE,
00105 EEXIST),
00106 CORBA::COMPLETED_YES);
00107 }
00108 }
00109
00110
00111 TAO_Pluggable_Reply_Params_Base reply_params;
00112 reply_params.request_id_ = this->request_id_;
00113 reply_params.service_context_notowned (&(this->reply_service_context_.service_info ()));
00114 reply_params.argument_flag_ = this->argument_flag_;
00115 reply_params.reply_status (this->reply_status_);
00116
00117 {
00118 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
00119
00120 this->mesg_base_->generate_reply_header (this->_tao_out, reply_params);
00121
00122
00123 this->rh_reply_status_ = TAO_RS_INITIALIZED;
00124 }
00125
00126 }
00127
00128 void
00129 TAO_AMH_Response_Handler::_tao_rh_send_reply (void)
00130 {
00131 {
00132 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
00133
00134
00135
00136 if (this->rh_reply_status_ != TAO_RS_INITIALIZED)
00137 {
00138 throw ::CORBA::BAD_INV_ORDER (
00139 CORBA::SystemException::_tao_minor_code (
00140 TAO_AMH_REPLY_LOCATION_CODE,
00141 ENOTSUP),
00142 CORBA::COMPLETED_YES);
00143 }
00144 this->rh_reply_status_ = TAO_RS_SENDING;
00145 }
00146
00147
00148 int result = this->transport_->send_message (this->_tao_out,
00149 0,
00150 TAO_REPLY);
00151
00152 if (result == -1)
00153 {
00154 if (TAO_debug_level > 0)
00155 {
00156
00157
00158 ACE_ERROR ((
00159 LM_ERROR,
00160 ACE_TEXT ("TAO: (%P|%t) %p: cannot send NO_EXCEPTION reply\n"),
00161 ACE_TEXT ("TAO_AMH_Response_Handler::_tao_rh_send_reply")
00162 ));
00163 }
00164 }
00165
00166 {
00167 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
00168 this->rh_reply_status_ = TAO_RS_SENT;
00169 }
00170 }
00171
00172 void
00173 TAO_AMH_Response_Handler::_tao_rh_send_exception (const CORBA::Exception &ex)
00174 {
00175 {
00176 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
00177 if (this->rh_reply_status_ != TAO_RS_UNINITIALIZED)
00178 {
00179 throw ::CORBA::BAD_INV_ORDER (
00180 CORBA::SystemException::_tao_minor_code (
00181 TAO_AMH_REPLY_LOCATION_CODE,
00182 ENOTSUP),
00183 CORBA::COMPLETED_YES);
00184 }
00185 this->rh_reply_status_ = TAO_RS_SENDING;
00186 }
00187
00188 TAO_Pluggable_Reply_Params_Base reply_params;
00189 reply_params.request_id_ = this->request_id_;
00190 reply_params.svc_ctx_.length (0);
00191 reply_params.service_context_notowned (&this->reply_service_context_.service_info ());
00192 reply_params.argument_flag_ = true;
00193
00194
00195
00196 if (CORBA::SystemException::_downcast (&ex))
00197 {
00198 reply_params.reply_status (GIOP::SYSTEM_EXCEPTION);
00199 }
00200 else
00201 {
00202 reply_params.reply_status (GIOP::USER_EXCEPTION);
00203 }
00204
00205 if (this->mesg_base_->generate_exception_reply (this->_tao_out,
00206 reply_params,
00207 ex) == -1)
00208 {
00209 throw ::CORBA::INTERNAL ();
00210 }
00211
00212
00213 if (this->transport_->send_message (this->_tao_out,
00214 0,
00215 TAO_REPLY) == -1)
00216 {
00217 if (TAO_debug_level > 0)
00218 ACE_ERROR ((LM_ERROR,
00219 ACE_TEXT ("TAO: (%P|%t|%N|%l): ")
00220 ACE_TEXT ("TAO_AMH_Response_Handler:")
00221 ACE_TEXT (" could not send exception reply\n")));
00222 }
00223
00224 {
00225 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
00226 this->rh_reply_status_ = TAO_RS_SENT;
00227 }
00228 }
00229
00230 void
00231 TAO_AMH_Response_Handler::_tao_rh_send_location_forward (CORBA::Object_ptr fwd,
00232 CORBA::Boolean is_perm)
00233 {
00234 {
00235 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
00236 if (this->rh_reply_status_ != TAO_RS_UNINITIALIZED)
00237 {
00238 throw ::CORBA::BAD_INV_ORDER (
00239 CORBA::SystemException::_tao_minor_code (
00240 TAO_AMH_REPLY_LOCATION_CODE,
00241 ENOTSUP),
00242 CORBA::COMPLETED_YES);
00243 }
00244 this->rh_reply_status_ = TAO_RS_SENDING;
00245 }
00246
00247
00248 TAO_Pluggable_Reply_Params_Base reply_params;
00249 reply_params.request_id_ = this->request_id_;
00250 reply_params.svc_ctx_.length (0);
00251 reply_params.service_context_notowned
00252 (&this->reply_service_context_.service_info ());
00253 reply_params.argument_flag_ = true;
00254 if (is_perm)
00255 {
00256 reply_params.reply_status (GIOP::LOCATION_FORWARD_PERM);
00257 }
00258 else
00259 {
00260 reply_params.reply_status (GIOP::LOCATION_FORWARD);
00261 }
00262
00263 if (this->mesg_base_->generate_reply_header (this->_tao_out,
00264 reply_params) == -1)
00265 {
00266 throw ::CORBA::INTERNAL ();
00267 }
00268
00269 if (!(this->_tao_out << fwd))
00270 {
00271 if (TAO_debug_level > 0)
00272 ACE_ERROR ((LM_ERROR,
00273 ACE_TEXT ("TAO (%P|%t) ERROR: Unable to marshal ")
00274 ACE_TEXT ("forward reference.\n")));
00275 return;
00276 }
00277
00278
00279 if (this->transport_->send_message (this->_tao_out,
00280 0,
00281 TAO_REPLY) == -1)
00282 {
00283 if (TAO_debug_level > 0)
00284 ACE_ERROR ((LM_ERROR,
00285 ACE_TEXT ("TAO: (%P|%t|%N|%l): ")
00286 ACE_TEXT ("TAO_AMH_Response_Handler: could not send ")
00287 ACE_TEXT ("location forward reply\n")));
00288 }
00289
00290 {
00291 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->mutex_);
00292 this->rh_reply_status_ = TAO_RS_SENT;
00293 }
00294 }
00295
00296 void
00297 TAO_AMH_Response_Handler::_remove_ref (void)
00298 {
00299 if (this->refcount_.decrement () > 0)
00300 return;
00301
00302 if (this->allocator_)
00303 {
00304 TAO::TAO_Buffer_Allocator<TAO_AMH_Response_Handler, TAO_AMH_BUFFER_ALLOCATOR> allocator (this->allocator_);
00305
00306 allocator.release (this);
00307 }
00308 else
00309 {
00310 delete this;
00311 }
00312 }
00313
00314 namespace TAO
00315 {
00316 void
00317 ARH_Refcount_Functor::operator () (TAO_AMH_Response_Handler *arh) throw ()
00318 {
00319 (void) arh->_remove_ref ();
00320 }
00321 }
00322
00323 TAO_END_VERSIONED_NAMESPACE_DECL