예제 #1
0
void
TAO_ECG_CDR_Message_Sender::send_message  (const TAO_OutputCDR &cdr,
                                           const ACE_INET_Addr &addr)
{
  if (this->endpoint_rptr_.get () == 0)
    {
      ORBSVCS_ERROR ((LM_ERROR, "Attempt to invoke send_message() "
                            "on non-initialized sender object.\n"));
      throw CORBA::INTERNAL ();
    }

  CORBA::ULong max_fragment_payload = this->mtu () -
    TAO_ECG_CDR_Message_Sender::ECG_HEADER_SIZE;
  // ACE_ASSERT (max_fragment_payload != 0);

#if defined (ACE_HAS_BROKEN_DGRAM_SENDV)
  const int TAO_WRITEV_MAX = ACE_IOV_MAX - 1;
#else
  const int TAO_WRITEV_MAX = ACE_IOV_MAX;
#endif /* ACE_HAS_BROKEN_DGRAM_SENDV */
  iovec iov[TAO_WRITEV_MAX];

  CORBA::ULong total_length;
  CORBA::ULong fragment_count =
    this->compute_fragment_count (cdr.begin (),
                                  cdr.end (),
                                  TAO_WRITEV_MAX,
                                  max_fragment_payload,
                                  total_length);

  CORBA::ULong request_id = this->endpoint_rptr_->next_request_id ();

  // Reserve the first iovec for the header...
  int iovcnt = 1;
  CORBA::ULong fragment_id = 0;
  CORBA::ULong fragment_offset = 0;
  CORBA::ULong fragment_size = 0;
  for (const ACE_Message_Block* b = cdr.begin ();
       b != cdr.end ();
       b = b->cont ())
    {
      CORBA::ULong l = b->length ();

      char* rd_ptr = b->rd_ptr ();

      iov[iovcnt].iov_base = rd_ptr;
      iov[iovcnt].iov_len  = l;
      fragment_size += l;
      ++iovcnt;
      while (fragment_size > max_fragment_payload)
        {
          // This fragment is full, we have to send it...

          // First adjust the last iov entry:
          CORBA::ULong last_mb_length =
            max_fragment_payload - (fragment_size - l);
          iov[iovcnt - 1].iov_len = last_mb_length;

          this->send_fragment (addr,
                               request_id,
                               total_length,
                               max_fragment_payload,
                               fragment_offset,
                               fragment_id,
                               fragment_count,
                               iov,
                               iovcnt);
          ++fragment_id;
          fragment_offset += max_fragment_payload;

          // Reset, but don't forget that the last Message_Block
              // may need to be sent in multiple fragments..
          l -= last_mb_length;
          rd_ptr += last_mb_length;
          iov[1].iov_base = rd_ptr;
          iov[1].iov_len = l;
          fragment_size = l;
          iovcnt = 2;
        }
      if (fragment_size == max_fragment_payload)
        {
          // We filled a fragment, but this time it was filled
          // exactly, the treatment is a little different from the
          // loop above...
          this->send_fragment (addr,
                               request_id,
                               total_length,
                               max_fragment_payload,
                               fragment_offset,
                               fragment_id,
                               fragment_count,
                               iov,
                               iovcnt);
          ++fragment_id;
          fragment_offset += max_fragment_payload;

          iovcnt = 1;
          fragment_size = 0;
        }
      if (iovcnt == TAO_WRITEV_MAX)
        {
          // Now we ran out of space in the iovec, we must send a
          // fragment to work around that....
          this->send_fragment (addr,
                               request_id,
                               total_length,
                               fragment_size,
                               fragment_offset,
                               fragment_id,
                               fragment_count,
                               iov,
                               iovcnt);
          ++fragment_id;
          fragment_offset += fragment_size;

          iovcnt = 1;
          fragment_size = 0;
        }
    }
  // There is something left in the iovvec that we must send
  // also...
  if (iovcnt != 1)
    {
      // Now we ran out of space in the iovec, we must send a
      // fragment to work around that....
      this->send_fragment (addr,
                           request_id,
                           total_length,
                           fragment_size,
                           fragment_offset,
                           fragment_id,
                           fragment_count,
                           iov,
                           iovcnt);
      ++fragment_id;
      fragment_offset += fragment_size;

      // reset, not needed here...
      // iovcnt = 1;
      // fragment_size = 0;
    }
  // ACE_ASSERT (total_length == fragment_offset);
  // ACE_ASSERT (fragment_id == fragment_count);

}
예제 #2
0
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  int status = 0;

  for (CORBA::ULong i = 16; i != 64; ++i)
    {
      ACE_Message_Block mb (i + ACE_CDR::MAX_ALIGNMENT);
      ACE_CDR::mb_align (&mb);
      mb.wr_ptr (i);

      CORBA::Double dbl = i;

      TAO_OutputCDR cdr;
      cdr.write_ulong (i); // length
      cdr.write_octet_array_mb (&mb);
      cdr.write_double (dbl);
      cdr.write_double (dbl);

      TAO_InputCDR input (cdr);

      CORBA::ULong len;

      input.read_ulong (len);

      if (len != i)
        {
          ACE_DEBUG ((LM_DEBUG,
                      "ERROR: mismatched lengths,"
                      " got %d, expected %d\n",
                      len, i));
        }

      ACE_Message_Block read_mb (len + ACE_CDR::MAX_ALIGNMENT);
      ACE_CDR::mb_align (&mb);
      mb.wr_ptr (len);
      input.read_char_array (mb.rd_ptr (), len);

      CORBA::Double read_dbl;
      if (input.read_double (read_dbl) == 0)
        ACE_DEBUG ((LM_DEBUG, "Failure reading double...\n"));

      if (!ACE::is_equal (read_dbl, dbl))
        {
          status = 1;
          ACE_DEBUG ((LM_DEBUG,
                      "ERROR: mismatched doubles,"
                      " got %f, expected %f\n",
                      read_dbl, dbl));
          for (const ACE_Message_Block *j = cdr.begin ();
               j != cdr.end ();
               j = j->cont ())
            {
              ACE_HEX_DUMP ((LM_DEBUG,
                             j->rd_ptr (),
                             j->length (),
                             ACE_TEXT("Output CDR stream")));
            }
          TAO_InputCDR debug (cdr);
          ACE_HEX_DUMP ((LM_DEBUG,
                         debug.rd_ptr (),
                         debug.length (),
                         ACE_TEXT("Input CDR stream")));
        }
    }

  return status;
}