void ReplicaController::send_reply ( PortableInterceptor::ServerRequestInfo_ptr ri) { FT::FTRequestServiceContext_var ftr ( extract_context (ri)); ACE_DEBUG ((LM_DEBUG, "(%P|%t) Sending reply for %s with rid %i\n", ftr->client_id.in (), ftr->retention_id)); // Prepare reply for logging. CORBA::Any_var result = ri->result (); TAO_OutputCDR cdr; result->impl ()->marshal_value (cdr); Dynamic::ParameterList_var pl = ri->arguments (); CORBA::ULong len = pl->length (); for (CORBA::ULong index = 0; index != len ; ++index) { //@@ No chance for PARAM_OUT if ((*pl)[index].mode == CORBA::PARAM_INOUT) { (*pl)[index].argument.impl ()->marshal_value (cdr); } } CORBA::OctetSeq_var reply; ACE_NEW (reply.out (), CORBA::OctetSeq (cdr.total_length ())); reply->length (cdr.total_length ()); CORBA::Octet* buf = reply->get_buffer (); // @@ What if this throws an exception?? We don't have any way to // check whether this succeeded for (ACE_Message_Block const* mb = cdr.begin (); mb != 0; mb = mb->cont ()) { ACE_OS::memcpy (buf, mb->rd_ptr (), mb->length ()); buf += mb->length (); } // Logging the reply and state update. // // First send message to members. // { // Extract state update. CORBA::OctetSeq_var oid = ri->object_id (); PortableInterceptor::AdapterName_var an = ri->adapter_name (); CORBA::Any_var state = ri->get_slot (state_slot_id ()); CORBA::TypeCode_var tc = state->type (); if (tc->kind () == CORBA::tk_null) { ACE_DEBUG ((LM_DEBUG, "Slot update is void\n")); PortableServer::POA_var poa = resolve_poa (an.in ()); PortableServer::ServantBase_var servant = poa->id_to_servant (oid.in ()); Checkpointable* target = dynamic_cast<Checkpointable*> (servant.in ()); if (target) { CORBA::Any_var tmp = target->get_state (); if (tmp.ptr () != 0) state = tmp._retn (); } } TAO_OutputCDR cdr; cdr << oid.in (); cdr << an.in (); cdr << ftr->client_id.in (); cdr << ftr->retention_id; cdr << reply.in (); cdr << state.in (); size_t size = cdr.total_length (); CORBA::OctetSeq_var msg; ACE_NEW (msg.out (), CORBA::OctetSeq (size)); msg->length (size); { CORBA::Octet* buf = msg->get_buffer (); for (ACE_Message_Block const* mb = cdr.begin (); mb != 0; mb = mb->cont ()) { ACE_OS::memcpy (buf, mb->rd_ptr (), mb->length ()); buf += mb->length (); } } CORBA::Octet* buf = msg->get_buffer (); // Crash point 1. // if (crash_point == 1 && ftr->retention_id > 2) ACE_OS::exit (1); try { while (true) { try { group_->send (buf, size); ACE_DEBUG ((LM_DEBUG, "Sent log record of length %i\n", size)); break; } catch (ACE_TMCast::Group::Aborted const&) { ACE_DEBUG ((LM_DEBUG, "Retrying to send log record.\n")); } } } catch (ACE_TMCast::Group::Failed const&) { ACE_DEBUG ((LM_DEBUG, "Group failure. Perhaps, I am alone in the group.\n")); } } // Now perform local logging. // RecordId rid (ftr->client_id.in (), ftr->retention_id); // This is slow but eh-safe ;-). // log_.insert (rid, reply); // Crash point 2. // if (crash_point == 2 && ftr->retention_id > 2) ACE_OS::exit (1); }
int TAO_Object_Adapter::dispatch (TAO::ObjectKey &key, TAO_ServerRequest &request, CORBA::Object_out forward_to) { if (key.length() < TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE || ACE_OS::memcmp (key.get_buffer (), &TAO_Root_POA::objectkey_prefix[0], TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE) != 0) { return TAO_Adapter::DS_MISMATCHED_KEY; } int result = 0; #if TAO_HAS_INTERCEPTORS == 1 TAO::ServerRequestInterceptor_Adapter *sri_adapter = orb_core_.serverrequestinterceptor_adapter (); try { if (sri_adapter != 0) { #if TAO_HAS_EXTENDED_FT_INTERCEPTORS == 1 CORBA::OctetSeq_var ocs; sri_adapter->tao_ft_interception_point (request, 0, // args 0, // nargs 0, // servant_upcall 0, // exceptions 0, // nexceptions ocs.out ()); /// If we have a cached result, just go ahead and send the reply /// and let us return if (ocs.ptr () != 0) { // request.result_seq ( request.send_cached_reply (ocs.inout ()); return TAO_Adapter::DS_OK; } // If a PortableInterceptor::ForwardRequest exception was // thrown, then set the forward_to object reference and return // with the appropriate return status. forward_to.ptr () = request.forward_location (); if (request.is_forwarded ()) { return TAO_Adapter::DS_FORWARD; } #endif /*TAO_HAS_EXTENDED_FT_INTERCEPTORS*/ // The receive_request_service_contexts() interception point // must be invoked before the operation is dispatched to the // servant. sri_adapter->receive_request_service_contexts (request, 0, // args 0, // nargs 0, // servant_upcall 0, // exceptions 0); // nexceptions // If a PortableInterceptor::ForwardRequest exception was // thrown, then set the forward_to object reference and return // with the appropriate return status. forward_to.ptr () = request.forward_location (); if (request.is_forwarded ()) { return TAO_Adapter::DS_FORWARD; } } #endif /* TAO_HAS_INTERCEPTORS == 1 */ result = this->dispatch_servant (key, request, forward_to); #if TAO_HAS_INTERCEPTORS == 1 if (result == TAO_Adapter::DS_FORWARD) { request.reply_status (GIOP::LOCATION_FORWARD); request.pi_reply_status (PortableInterceptor::LOCATION_FORWARD); request.forward_location (forward_to.ptr ()); if (sri_adapter != 0) { sri_adapter->send_other (request, 0, // args 0, // nargs 0, // servant_upcall 0, // exceptions 0 // nexceptions ); } } } catch ( ::CORBA::Exception& ex) { // Just assume the current exception is a system exception, the // status can only change when the interceptor changes this // and this is only done when the sri_adapter is available. If we // don't have an sri_adapter we just rethrow the exception PortableInterceptor::ReplyStatus status = PortableInterceptor::SYSTEM_EXCEPTION; if (sri_adapter != 0) { request.caught_exception (&ex); sri_adapter->send_exception (request, 0, // args 0, // nargs 0, // servant_upcall 0, // exceptions 0); // nexceptions status = request.pi_reply_status (); } // Only re-throw the exception if it hasn't been transformed by // the send_exception() interception point (e.g. to a // LOCATION_FORWARD). if (status == PortableInterceptor::SYSTEM_EXCEPTION || status == PortableInterceptor::USER_EXCEPTION) { throw; } } #endif /* TAO_HAS_INTERCEPTORS == 1 */ return result; }