示例#1
0
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);
}
示例#2
0
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;
}