int TAO_DII_Asynch_Reply_Dispatcher::dispatch_reply ( TAO_Pluggable_Reply_Params ¶ms) { this->reply_status_ = params.reply_status (); this->locate_reply_status_ = params.locate_reply_status (); // Transfer the <params.input_cdr_>'s content to this->reply_cdr_ ACE_Data_Block *db = this->reply_cdr_.clone_from (*params.input_cdr_); // See whether we need to delete the data block by checking the // flags. We cannot be happy that we initally allocated the // datablocks of the stack. If this method is called twice, as is in // some cases where the same invocation object is used to make two // invocations like forwarding, the release becomes essential. if (ACE_BIT_DISABLED (db->flags (), ACE_Message_Block::DONT_DELETE)) db->release (); // Steal the buffer, that way we don't do any unnecesary copies of // this data. CORBA::ULong max = params.svc_ctx_.maximum (); CORBA::ULong len = params.svc_ctx_.length (); IOP::ServiceContext* context_list = params.svc_ctx_.get_buffer (1); this->reply_service_info_.replace (max, len, context_list, 1); if (TAO_debug_level >= 4) { TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P | %t):") ACE_TEXT ("TAO_DII_Asynch_Reply_Dispatcher::dispatch_reply: status = %d\n"), this->reply_status_)); } try { // Call the handler with the reply data. CORBA::Request::_tao_reply_stub (this->reply_cdr_, this->callback_, this->reply_status_); } catch (const CORBA::Exception& ex) { if (TAO_debug_level >= 4) { ex._tao_print_exception ("Exception during reply handler"); } } // This was dynamically allocated. Now the job is done. this->intrusive_remove_ref (this); return 1; }
int TAO_Synch_Reply_Dispatcher::dispatch_reply ( TAO_Pluggable_Reply_Params ¶ms) { if (params.input_cdr_ == 0) return -1; this->reply_status_ = params.reply_status (); this->locate_reply_status_ = params.locate_reply_status (); // Steal the buffer, that way we don't do any unnecesary copies of // this data. CORBA::ULong const max = params.svc_ctx_.maximum (); CORBA::ULong const len = params.svc_ctx_.length (); IOP::ServiceContext* context_list = params.svc_ctx_.get_buffer (true); this->reply_service_info_.replace (max, len, context_list, true); if (this->reply_service_info_.length() > 0) { orb_core_->service_context_registry (). process_service_contexts (this->reply_service_info_, *(params.transport_), 0); } // Must reset the message state, it is possible that the same reply // dispatcher is used because the request must be re-sent. // this->message_state_.reset (0); // Transfer the <params.input_cdr_>'s content to this->reply_cdr_ if (ACE_BIT_DISABLED ((*params.input_cdr_).start()->data_block()->flags(), ACE_Message_Block::DONT_DELETE)) { // Data block is on the heap, so just duplicate it. this->reply_cdr_ = *params.input_cdr_; this->reply_cdr_.clr_mb_flags (ACE_Message_Block::DONT_DELETE); } else { ACE_Data_Block *db = this->reply_cdr_.clone_from (*params.input_cdr_); if (db == 0) { if (TAO_debug_level > 2) { TAOLIB_ERROR ((LM_ERROR, "TAO (%P|%t) - Synch_Reply_Dispatcher::dispatch_reply " "clone_from failed\n")); } return -1; } // See whether we need to delete the data block by checking the // flags. We cannot be happy that we initally allocated the // datablocks of the stack. If this method is called twice, as is in // some cases where the same invocation object is used to make two // invocations like forwarding, the release becomes essential. if (ACE_BIT_DISABLED (db->flags (), ACE_Message_Block::DONT_DELETE)) { db->release (); } } this->state_changed (TAO_LF_Event::LFS_SUCCESS, this->orb_core_->leader_follower ()); return 1; }
// Dispatch the reply. int TAO_Asynch_Reply_Dispatcher::dispatch_reply (TAO_Pluggable_Reply_Params ¶ms) { if (this->timeout_handler_) { // If we had registered timeout handlers just cancel them and // loose ownership of the handlers this->timeout_handler_->cancel (); this->timeout_handler_->remove_reference (); this->timeout_handler_ = 0; // AMI Timeout Handling End } // With Asynch requests the invocation handler can't call idle_after_reply () // since it does not handle the reply. // So we have to do that here in case f.i. the Exclusive TMS left the transport // busy after the send if (this->transport_ != 0) this->transport_->tms ()->idle_after_reply (); if (!params.input_cdr_) return -1; if (!this->try_dispatch_reply ()) return 0; this->reply_status_ = params.reply_status (); this->locate_reply_status_ = params.locate_reply_status (); // Transfer the <params.input_cdr_>'s content to this->reply_cdr_ ACE_Data_Block *db = this->reply_cdr_.clone_from (*params.input_cdr_); if (db == 0) { if (TAO_debug_level > 2) { TAOLIB_ERROR (( LM_ERROR, ACE_TEXT ("TAO_Messaging (%P|%t) - Asynch_Reply_Dispatcher::dispatch_reply ") ACE_TEXT ("clone_from failed\n"))); } return -1; } // See whether we need to delete the data block by checking the // flags. We cannot be happy that we initially allocated the // datablocks of the stack. If this method is called twice, as is in // some cases where the same invocation object is used to make two // invocations like forwarding, the release becomes essential. if (ACE_BIT_DISABLED (db->flags (), ACE_Message_Block::DONT_DELETE)) { db->release (); } if (!CORBA::is_nil (this->reply_handler_.in ())) { // Steal the buffer, that way we don't do any unnecesary copies of // this data. CORBA::ULong const max = params.svc_ctx_.maximum (); CORBA::ULong const len = params.svc_ctx_.length (); IOP::ServiceContext *context_list = params.svc_ctx_.get_buffer (1); this->reply_service_info_.replace (max, len, context_list, 1); if (TAO_debug_level >= 4) { TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO_Messaging (%P|%t) - Asynch_Reply_Dispatcher") ACE_TEXT ("::dispatch_reply status = %d\n"), this->reply_status_)); } CORBA::ULong reply_error = TAO_AMI_REPLY_NOT_OK; switch (this->reply_status_) { case GIOP::NO_EXCEPTION: reply_error = TAO_AMI_REPLY_OK; break; case GIOP::USER_EXCEPTION: reply_error = TAO_AMI_REPLY_USER_EXCEPTION; break; case GIOP::SYSTEM_EXCEPTION: reply_error = TAO_AMI_REPLY_SYSTEM_EXCEPTION; break; case GIOP::LOCATION_FORWARD: reply_error = TAO_AMI_REPLY_LOCATION_FORWARD; break; case GIOP::LOCATION_FORWARD_PERM: reply_error = TAO_AMI_REPLY_LOCATION_FORWARD_PERM; break; default: // @@ Michael: Not even the spec mentions this case. // We have to think about this case. // Handle the forwarding and return so the stub restarts the // request! reply_error = TAO_AMI_REPLY_NOT_OK; break; } try { // Call the Reply Handler's stub. this->reply_handler_stub_ (this->reply_cdr_, this->reply_handler_.in (), reply_error); } catch (const ::CORBA::Exception& ex) { if (TAO_debug_level >= 4) ex._tao_print_exception ("Exception during reply handler"); } } this->intrusive_remove_ref (this); return 1; }