Beispiel #1
1
//
// handle_input
//
int CUTS_TCPIP_Event_Handler::handle_input (ACE_HANDLE fd)
{
  // Set the ACE_HANDLE as a socket stream.
  ACE_SOCK_Stream stream (fd);


  // @todo Since the header size is constant, we can create free list
  //       of the message blocks that are used to read the header from
  //       the stream.

  // Read the event from the stream. The first chunk of the event
  // is be the header information, which is of constrant size.
  static const ssize_t header_size = 4 +        // magic
                                     4 +        // byte order
                                     2 +        // version (x.x)
                                     2 +        // padding
                                     16 +       // UUID
                                     4 +        // event id
                                     4;         // payload size

  ACE_Message_Block header (header_size);
  ssize_t retcode = stream.recv_n (header.wr_ptr (), header_size);

  if (retcode != header_size)
    ACE_ERROR_RETURN ((LM_ERROR,
           "%T (%t) - %M - invalid TCP/IP header\n"),
          -1);

  // Reflect the number of bytes read from the stream.
  header.wr_ptr (header_size);

  // Extract the header from the message block.
  CUTS_TCPIP_SPEC spec;
  ACE_CDR::ULong datasize;

  ACE_InputCDR input (header.rd_ptr (), header_size);

  // Read the SPEC and the datasize from the packet.
  input >> spec;
  input >> datasize;

  if (!input.good_bit ())
    ACE_ERROR_RETURN ((LM_ERROR,
           "%T (%t) - %M - failed to read TCP/IP header\n"),
          -1);

  // Construct a chain of message blocks to read the payload associated
  // with the received event.
  ACE_Message_Block * mb = 0;
  ACE_NEW_RETURN (mb, ACE_Message_Block (ACE_CDR::DEFAULT_BUFSIZE), -1);

  ssize_t read_count;
  ACE_Message_Block * head = mb;
  ACE_Auto_Ptr <ACE_Message_Block> auto_clean (head);

  for (size_t remaining = datasize; 0 != remaining; )
  {
    // Determine how much should be read in this attempt.
    read_count =
      ACE_CDR::DEFAULT_BUFSIZE < remaining ?
      ACE_CDR::DEFAULT_BUFSIZE : remaining;

    // Read the data from the stream.
    retcode = stream.recv_n (mb->wr_ptr (), read_count);

    if (retcode != read_count)
      ACE_ERROR_RETURN ((LM_ERROR,
                          "%T - %M - %m\n"),
                          -1);


    // Substract the amount from the remaining count.
    mb->wr_ptr (read_count);
    remaining -= read_count;

    if (0 != remaining)
    {
      // Allocate a new block for the chain.
      ACE_Message_Block * temp = 0;

      ACE_NEW_RETURN (temp,
                      ACE_Message_Block (ACE_CDR::DEFAULT_BUFSIZE),
                      -1);

      // Insert new block in the chain and move forward.
      mb->cont (temp);
      mb = temp;
    }
  }

  // Since we have made it this far, we have successfully read the
  // event and its payload from the socket. Now, pass the message
  // the object manger, so it can dispatch it accordingly.

  if (this->obj_mgr_ != 0)
  {
    iCCM::TCPIP_Servant * svnt = 0;
    int retval = this->obj_mgr_->find_object (spec.uuid_, svnt);

    if (0 == retval)
    {
      // Signal the object to handle the event.
      ACE_InputCDR ev (head, input.byte_order ());
      retval = svnt->handle_event (spec.event_id_, ev);

      if (-1 == retval)
        ACE_ERROR ((LM_ERROR,
                    "%T (%t) - %M - failed to handle event [%s]\n",
                    spec.uuid_.to_string ()->c_str ()));
    }
    else
      ACE_ERROR ((LM_ERROR,
                  "%T (%t) - %M - failed to locate object with id [%s]\n",
                  spec.uuid_.to_string ()->c_str ()));
  }

  // Release the message block.
  // head->release ();

  return 0;
}
Beispiel #2
0
void release_cfentries(ACE_Message_Block& mb_hdr)
{
  ACE_Message_Block* cf = mb_hdr.cont();
  mb_hdr.cont(mb_hdr.cont()->cont());
  cf->cont(0);
  cf->release();
}
Beispiel #3
0
int main(int argc, char** argv)
{
    ACE_Message_Block* head = new ACE_Message_Block(BUFSIZ);
    ACE_Message_Block* mblk = head;

    while(1)
    {
        size_t nbytesRead = 0;
        ssize_t nbytes = ACE::read_n(ACE_STDIN, mblk->wr_ptr(), mblk->size(), &nbytesRead);

        mblk->wr_ptr(nbytesRead); // Need to adjust the ptr by user if we directly modify the momoey in the message block ...

        mblk->cont(new ACE_Message_Block(BUFSIZ));
        mblk = mblk->cont();

        // nbytes will be zero if encount EOF or error
        // even nbytes is zero the nbytesRead could still not be zero
        if (nbytes <= 0)
        {
            log("Receive EOF\n");
            break;
        }
    }

    for (mblk = head; mblk != 0; mblk = mblk->cont())
    {
        ACE::write_n(ACE_STDOUT, mblk->rd_ptr(), mblk->length());
    }

    head->release(); // Thie releases all the memory in the chain.

    return 0;
}
Beispiel #4
0
int
Task::handle_input( ACE_HANDLE h )
{
    const size_t size = 2000;
    ACE_Message_Block * mb = new ACE_Message_Block( size );
    ACE_Message_Block * pfrom = new ACE_Message_Block( sizeof( ACE_INET_Addr ) );
	ACE_INET_Addr * addr = new ( pfrom->wr_ptr() ) ACE_INET_Addr();

    int res = 0;
	if ( mcast_handler_ && ( h == mcast_handler_->get_handle() ) ) {

		mb->msg_type( constants::MB_MCAST );
		res = mcast_handler_->recv( mb->wr_ptr(), size, *addr );

	}
	if ( res == (-1) ) {
		DWORD err = GetLastError();
		(void)err;
		ACE_Message_Block::release( mb );
		ACE_Message_Block::release( pfrom );
		return 0;
	}
	mb->length( res );
	mb->cont( pfrom );

	putq( mb );

	return 0;
}
int UDPGenerator::readdatagram(int header_size)
{
    ACE_Message_Block* msg = 0;/*{{{*/
    ACE_NEW_RETURN (msg, ACE_Message_Block (1024), -1);

    msg->size (header_size); // size of header to read is 20 bytes

    // create a message block to read the message body
    ACE_Message_Block* body = 0;
    ACE_NEW_RETURN (body, ACE_Message_Block (1024), -1);
    // The message body will not exceed 1024 bytes, at least not in this test.

    msg->cont (body);

    // ok lets do the asynch read
    size_t number_of_bytes_recvd = 0;

    int res = rd_.recv (
                  msg,
                  number_of_bytes_recvd,
                  0,
                  PF_INET,
                  this->act_);
    /*}}}*/
    switch (res)/*{{{*/
    {
    case 0:
        // this is a good error.  The proactor will call our handler when the
        // read has completed.
        break;
    case 1:
        // actually read something, we will handle it in the handler callback
        ACE_DEBUG ((LM_DEBUG, "********************\n"));
        ACE_DEBUG ((LM_DEBUG,
                    "%s = %d\n",
                    "bytes recieved immediately",
                    number_of_bytes_recvd));
        ACE_DEBUG ((LM_DEBUG, "********************\n"));
        res = 0;
        break;
    case -1:
        // Something else went wrong.
        ACE_ERROR ((LM_ERROR,
                    "%p\n",
                    "ACE_Asynch_Read_Dgram::recv"));
        // the handler will not get called in this case so lets clean up our msg
        msg->release ();
        break;
    default:
        // Something undocumented really went wrong.
        ACE_ERROR ((LM_ERROR,
                    "%p\n",
                    "ACE_Asynch_Read_Dgram::recv"));
        msg->release ();
        break;
    }/*}}}*/

    return res;
}
Beispiel #6
0
void
PConnection::trace_buffers(const Buffer_Info& buf_info,
                           size_t xfer_bytes,
                           bool   flg_read)
{
  int   iovcnt = buf_info.get_iov_count ();
  if (iovcnt < 0)   // ACE_Message_Block
    {
      ACE_Message_Block * mb = buf_info.get_message_block_ptr();

      for (int i=0; 
            xfer_bytes != 0 && mb != 0 ;
            mb = mb->cont (), ++i)
      {
        char * ptr = flg_read ? mb->wr_ptr () : mb->rd_ptr ();
        size_t len = flg_read ? mb->length () : (ptr - mb->base ());
        if (len > xfer_bytes)
            len = xfer_bytes;

        ptr -= len;
        xfer_bytes -=len;

        ACE_DEBUG ((LM_DEBUG,
          ACE_TEXT ("message_block [%d] length=%d:\n"), i, (int)len));

        ACE_HEX_DUMP ((LM_DEBUG, ptr, len));
      }
    }
  else if (iovcnt > 0) // iovec 
    {
      iovec *iov = buf_info.get_iov ();
      for (int i=0; xfer_bytes != 0 && i < iovcnt; ++i)
      {
        char * ptr = (char*) iov[i].iov_base;
        size_t len = iov[i].iov_len;
        if (len > xfer_bytes)
            len = xfer_bytes;

        ptr -= len;
        xfer_bytes -=len;

        ACE_DEBUG ((LM_DEBUG,
          ACE_TEXT ("iov[%d] length=%d:\n"), i, (int)len));

        ACE_HEX_DUMP ((LM_DEBUG, ptr, len));
      }
    }
  else // simple  buffer
    {
      char *ptr = buf_info.get_buffer ();
      ACE_DEBUG ((LM_DEBUG,
          ACE_TEXT ("buffer length=%d:\n"), (int)xfer_bytes));

      ACE_HEX_DUMP ((LM_DEBUG, ptr, xfer_bytes));
    }
  ACE_DEBUG ((LM_DEBUG,
    ACE_TEXT ("**** end of buffers ****************\n")));
}
Beispiel #7
0
int
ACE_RMCast_Fragment_Tester::data (ACE_RMCast::Data &data)
{
  ACE_UINT32 sequence_number = data.sequence_number;
  ACE_UINT32 message_size = data.total_size;
  size_t offset = data.fragment_offset;
  ACE_Message_Block *mb = data.payload;

  if (this->received_bytes_ == 0)
    {
      this->received_.size (message_size);
      this->received_.wr_ptr (message_size);
      this->message_sequence_number_ =  sequence_number;
    }
  else
    {
      if (this->message_sequence_number_ != sequence_number)
        ACE_ERROR_RETURN ((LM_ERROR,
                           ACE_TEXT ("Mismatched sequence number\n")),
                          -1);
      if (this->received_.length () != message_size)
        ACE_ERROR_RETURN ((LM_ERROR,
                           ACE_TEXT ("Mismatched sequence size\n")),
                          -1);
    }

  size_t payload_size = mb->length ();
  size_t fragment_size = payload_size;
  if (payload_size > 0)
    {
      ACE_OS::memcpy (this->received_.rd_ptr () + offset,
                      mb->rd_ptr (),
                      payload_size);
      this->received_bytes_ += payload_size;
      offset += payload_size;
    }

  for (const ACE_Message_Block *i = mb->cont (); i != 0; i = i->cont ())
    {
      payload_size = i->length ();
      // ACE_DEBUG ((LM_DEBUG,
      //         "offset = %d , payload = %d\n", offset, payload_size));
      fragment_size += payload_size;
      ACE_OS::memcpy (this->received_.rd_ptr () + offset,
                      i->rd_ptr (), payload_size);
      this->received_bytes_ += payload_size;
      offset += payload_size;
    }

  if (fragment_size > this->fragment_.max_fragment_size ())
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT ("Invalid fragment size\n")),
                      -1);

  return 0;
}
int AC_Input_Handler::handle_input (ACE_HANDLE handle) {
  ACE_Message_Block *mblk = 0;
  Logging_Handler logging_handler (handle);

  if (logging_handler.recv_log_record (mblk) != -1)
    {
      if (output_handler_->put (mblk->cont ()) != -1)
        {
          mblk->cont (0);
          mblk->release ();
          return 0; // Success return.
        }
      else
        {
          mblk->release ();
        }
    }
    
  return -1; // Error return.
}
Beispiel #9
0
int TCPConnectionHandler::scheduleSend (ACE_Message_Block * buffer)
{
  // link buffer to the end of buffers list
  if (buffers_)
    {
      ACE_Message_Block *lastBuffer = buffers_;
      while (lastBuffer->cont ())
        lastBuffer = lastBuffer->cont () ;
      lastBuffer->cont (buffer);
    }
  else
    buffers_ = buffer;

  if (0 > sendBuffers ())
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT (" (%P) %p\n"),
                       ACE_TEXT ("Cannot schedule TCP send.")),
                      -1);
  return 0;
}
Beispiel #10
0
void
ACE_RMCast_Reassembly_Tester::initialize (ACE_Message_Block *mb)
{
  for (ACE_Message_Block *i = mb; i != 0; i = i->cont ())
    {
      char z = 0;
      for (char *j = i->rd_ptr (); j != i->wr_ptr (); ++j)
        {
          *j = ++z;
        }
    }
}
Beispiel #11
0
//get file and store it into ACE message block.
bool ZIP_Wrapper::get_file (char* archive_path, char* filename,
                            ACE_Message_Block &file)
{
  bool return_code = true;
  unzFile uf=0;
  uf = unzOpen(archive_path);
  /* locate the desired file in the zip file and set it as current file*/
  int j=unzLocateFile(uf, filename, 0);
  if (j==UNZ_END_OF_LIST_OF_FILE)
    {
      DANCE_ERROR (DANCE_LOG_ERROR,
                   (LM_DEBUG, ACE_TEXT("File not found in zip archive")));
      return false;
    }
  else if (j==UNZ_OK)
    {
      int k=unzOpenCurrentFile(uf);
      if (k!=UNZ_OK)
        {
          DANCE_ERROR (DANCE_LOG_ERROR,
                       (LM_DEBUG, ACE_TEXT("Error in opening the current")
                        ACE_TEXT(" file using unzOpenCurrentFile")));
          return false;
        }
      else
        {
          int num_read = 0;
          ACE_Message_Block* head = &file;

          //read the file into the ACE_Message_Block
          do
            {
              if (head->space () == 0)
                {
                  ACE_Message_Block* next = 0;
                  ACE_NEW_RETURN (next, ACE_Message_Block (BUFSIZ), false);
                  head = head->cont ();
                }
              num_read = unzReadCurrentFile(archive_path, head->wr_ptr(),
                                                  head->space());
              if (num_read > 0)
                head->wr_ptr (num_read);
            } while (num_read > 0);
          if (num_read < 0)
            return_code = false;
          unzCloseCurrentFile(uf);
          unzClose(uf);
          return return_code;
        }
    }
  return return_code;
}
void
displayChain(ACE_Message_Block* chain)
{
  //std::cout << "DISPLAYING CHAIN" << std::endl;
  for (ACE_Message_Block* current = chain; current; current = current->cont()) {
    if (current->length() > 0) {
      //std::cout << "DISPLAYING BLOCK" << std::endl;
      ACE_TCHAR buffer[4096];
      ACE::format_hexdump(current->base(), current->length(), buffer, sizeof(buffer));
      std::cout << buffer << std::endl;
    }
  }
}
Beispiel #13
0
  virtual int put (ACE_Message_Block *mblk, ACE_Time_Value *) 
  {
  
    for (ACE_Message_Block *temp = mblk;      temp != 0;   temp = temp->cont ())    
    {     
    	 if (temp->msg_type () != ACE_Message_Block::MB_STOP)
      {
      	format_data(temp);
      }
    }
    
    return put_next (mblk);
 } 
int
Sender::initiate_write_stream (ACE_Message_Block &mb)
{
  // send the odd to the first connection, and the even to the second
  // connection.

  ACE_Message_Block *odd_mb  = &mb;
  ACE_Message_Block *even_mb = mb.cont ();

  split_odd_even_chains (odd_mb, even_mb);

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Sender::initiate_write_stream - (ODD ) writev %d\n"),
              odd_mb->total_length ()));

  if (this->ws_[ODD].writev (*odd_mb, odd_mb->total_length ()) == -1)
    {
      free_chunks_chain (odd_mb);

      if (even_mb)
        free_chunks_chain (even_mb);

      ACE_ERROR_RETURN((LM_ERROR,
                        ACE_TEXT ("%p\n"),
                        ACE_TEXT ("Sender::ACE_Asynch_Stream::writev")),
                       -1);
    }

  ++this->io_count_;

  if (even_mb)
    {
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("Sender::initiate_write_stream - (EVEN) writev %d\n"),
                  even_mb->total_length ()));

      if (this->ws_[EVEN].writev (*even_mb, even_mb->total_length ()) == -1)
        {
          free_chunks_chain (even_mb);

          ACE_ERROR_RETURN((LM_ERROR,
                            ACE_TEXT ("%p\n"),
                            ACE_TEXT ("Sender::ACE_Asynch_Stream::writev")),
                           -1);
        }

      ++this->io_count_;
    }

  return 0;
}
static void
add_to_chunks_chain (ACE_Message_Block *&chunks_chain,
                     ACE_Message_Block *additional_chunks_chain)
{
  if (0 == chunks_chain)
    chunks_chain = additional_chunks_chain;
  else
    {
      ACE_Message_Block *last = 0;
      last_chunk (chunks_chain, last);
      if (last)
        last->cont (additional_chunks_chain);
    }
}
Beispiel #16
0
int TCPConnectionHandler::sendBuffers ()
{
  int result = 0;

  if (buffers_)
    if (0 < (result = peer_.send_n (buffers_))) // remove sent blocks
      {
        totalSent_ += result;
        while (buffers_ &&
               static_cast< size_t > (result) >= buffers_->length ())
          {
            ACE_Message_Block *buffer = buffers_;
            result -= buffers_->length ();
            buffers_= buffers_->cont ();
            buffer->cont (0);
            buffer->release ();
          }

        if (buffers_) // some buffers were not sent, truncate data
          buffers_->rd_ptr (result);
      }

  return result;
}
Beispiel #17
0
void ProactorService::SendInternal(char* pBuffer, int bufferSize)
{			
	ACE_Message_Block* pBlock = NULL;

	ACE_NEW_NORETURN(pBlock, ACE_Message_Block(bufferSize));

	pBlock->copy((const char*)pBuffer, bufferSize);

	if(NULL == pBlock->cont())
	{
		m_AsyncWriter.write(*pBlock, pBlock->length());
	}
	else
	{
		m_AsyncWriter.writev(*pBlock, pBlock->total_length());
	}	
}
static void
run_test (SVC_HANDLER &svc_handler,
          size_t iterations)
{
  // Create a whole slew of message blocks and pass them to the
  // <svc_handler>.
  for (size_t i = 0; i < iterations; i++)
    {
      ACE_Message_Block *mb;
      ACE_NEW (mb,
               ACE_Message_Block (sizeof (ACE_LIB_TEXT("hello "))));

      ACE_Message_Block *cb1;
      ACE_NEW (cb1,
               ACE_Message_Block (sizeof (ACE_LIB_TEXT("there\n"))));

      ACE_Message_Block *cb2;
      ACE_NEW (cb2,
               ACE_Message_Block (sizeof (ACE_LIB_TEXT("there\n"))));

      mb->copy ("hello ",
                ACE_OS::strlen (ACE_LIB_TEXT("hello ")));
      cb1->copy ("there ",
                 ACE_OS::strlen (ACE_LIB_TEXT("there ")));
      mb->cont (cb1);
      cb2->copy ("doug\n",
                ACE_OS::strlen (ACE_LIB_TEXT("doug\n")));
      cb1->cont (cb2);

      // Note that this is a buffered call!
      if (svc_handler.put (mb) == -1)
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p\n"),
                    ACE_TEXT ("put")));
    }

  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("final flush\n")));

  // Make sure to flush everything out before we exit.
  if (svc_handler.flush () == -1)
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("%p\n"),
                ACE_TEXT ("flush")));
}
ssize_t
MulticastSendStrategy::async_send(const iovec iov[], int n)
{
#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
  if (!async_init_) {
    if (-1 == async_writer_.open(*this, link_->socket().get_handle(), 0 /*completion_key*/,
                                 link_->get_proactor())) {
        return -1;
    }
    async_init_ = true;
  }

  ACE_Message_Block* mb = 0;
  size_t total_length = 0;

  for (int i = n - 1; i >= 0; --i) {
    ACE_Message_Block* next =
      new ACE_Message_Block(static_cast<const char*>(iov[i].iov_base),
                            iov[i].iov_len);
    next->wr_ptr(iov[i].iov_len);
    total_length += iov[i].iov_len;
    next->cont(mb);
    mb = next;
  }

  size_t bytes_sent = 0;
  ssize_t result = async_writer_.send(mb, bytes_sent, 0 /*flags*/,
                                      this->link_->config()->group_address_);

  if (result < 0) {
    mb->release();
    return result;
  }

  // framework needs to think we sent the entire datagram
  return total_length;
#else
  ACE_UNUSED_ARG(iov);
  ACE_UNUSED_ARG(n);
  return -1;
#endif
}
ACE_Message_Block*
getchain(size_t blocks, const int* defs)
{
  //std::cout << "Creating a chain with " << blocks << " blocks." << std::endl;

  ACE_Message_Block* head = 0;
  ACE_Message_Block* current = 0;

  for (size_t i = 0; i < blocks; ++i) {
    //std::cout << "Creating new block with " << defs[i] << " bytes." << std::endl;
    ACE_Message_Block* b = new ACE_Message_Block(defs[i]);
    if (head) {
      current->cont(b);
    } else {
      head = b;
    }
    current = b;
  }
  return head;
}
size_t
run_clone_test (const size_t msg_block_count,
                const char * block,
                const size_t msg_block_size)
{
    size_t rc = 0;

    ACE_Message_Block* mb_top = new ACE_Message_Block ();
    ACE_Message_Block* mb = mb_top;

    for (size_t j = 0; j != msg_block_count; ++j)
    {
      ACE_Message_Block* next = new ACE_Message_Block (block, msg_block_size);
      next->wr_ptr (msg_block_size);
      mb->cont (next);
      mb = next;
    }

    ACE_Message_Block* mb_test = mb_top->clone ();
    if (mb_test != 0)
    {
      rc = mb_test->total_size();
      ACE_ERROR ((LM_DEBUG,
                  ACE_TEXT ("(%P|%t) %u top reference_count ()\n"),
                  mb_top->reference_count ()));
      ACE_ERROR ((LM_DEBUG,
                  ACE_TEXT ("(%P|%t) cloned: %@ %d %d\n"),
                  mb_test,
                  mb_test->total_size(),
                  mb_test->total_length()));
      mb_test-> release();
    }

    ACE_ERROR ((LM_DEBUG,
                ACE_TEXT ("(%P|%t) %u top reference_count ()\n"),
                mb_top->reference_count ()));

    mb_top-> release();
    return rc;
}
Beispiel #22
0
int
DeviceProxy::handle_input( ACE_HANDLE )
{
    const size_t size = 1024 * sizeof(long) * 256; // maximum packet

	ACE_Message_Block * mb = new ACE_Message_Block( size );
    ACE_Message_Block * pfrom = new ACE_Message_Block( sizeof( ACE_INET_Addr) );
	ACE_INET_Addr * pFromAddr = new (pfrom->wr_ptr()) ACE_INET_Addr();

	int res = dgram_handler_->recv( mb->wr_ptr(), size, *pFromAddr );
    if (res == (-1)) {
       perror("handle_input dgram.recv");
       ACE_Message_Block::release( mb );
       ACE_Message_Block::release( pfrom );
       return 0;
    }
    mb->length( res );
    mb->cont( pfrom );
    handle_lifecycle_dgram( mb );

	return 0;
}
Beispiel #23
0
int
TAO_Queued_Data::consolidate (void)
{
  // Is this a chain of fragments?
  if (this->state_.more_fragments () && this->msg_block_->cont () != 0)
    {
      // Create a message block big enough to hold the entire chain
      ACE_Message_Block *dest = clone_mb_nocopy_size (
                                      this->msg_block_,
                                      this->msg_block_->total_length ());

      if (0 == dest)
        {
          // out of memory
          return -1;
        }
      // Memory allocation succeeded, the new message block can hold the consolidated
      // message. The following code just copies all the data into this new message block.
      // No further memory allocation will take place.

      // Reset the cont() parameter.  We have cloned the message
      // block but not the chain as we will no longer have chain.
      dest->cont (0);

      // Use ACE_CDR to consolidate the chain for us
      ACE_CDR::consolidate (dest, this->msg_block_);

      // free the original message block chain
      this->msg_block_->release ();

      // Set the message block to the new consolidated message block
      this->msg_block_ = dest;
      this->state_.more_fragments (false);
    }

  return 0;
}
int
Sender::open (const ACE_TCHAR *host,
              u_short port)
{
  // Initialize stuff

  if (this->sock_dgram_.open (ACE_INET_Addr::sap_any) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "ACE_SOCK_Dgram::open"), -1);

  // Initialize the asynchronous read.
  if (this->wd_.open (*this,
                      this->sock_dgram_.get_handle (),
                      this->completion_key_,
                      ACE_Proactor::instance ()) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "ACE_Asynch_Write_Dgram::open"), -1);

  // We are using scatter/gather to send the message header and
  // message body using 2 buffers

  // create a message block for the message header
  ACE_Message_Block* msg = 0;
  ACE_NEW_RETURN (msg, ACE_Message_Block (100), -1);
  const char raw_msg [] = "To be or not to be.";
  // Copy buf into the Message_Block and update the wr_ptr ().
  msg->copy (raw_msg, ACE_OS::strlen (raw_msg) + 1);

  // create a message block for the message body
  ACE_Message_Block* body = 0;
  ACE_NEW_RETURN (body, ACE_Message_Block (100), -1);
  ACE_OS::memset (body->wr_ptr (), 'X', 100);
  body->wr_ptr (100); // always remember to update the wr_ptr ()

  // set body as the cont of msg.  This associates the 2 message blocks so
  // that a send will send the first block (which is the header) up to
  // length (), and use the cont () to get the next block to send.  You can
  // chain up to IOV_MAX message block using this method.
  msg->cont (body);

  // do the asynch send
  size_t number_of_bytes_sent = 0;
  ACE_INET_Addr serverAddr (port, host);
  int res = this->wd_.send (msg, number_of_bytes_sent, 0, serverAddr, this->act_);

  switch (res)
    {
    case 0:
      // this is a good error.  The proactor will call our handler when the
      // send has completed.
      break;
    case 1:
      // actually sent something, we will handle it in the handler callback
      ACE_DEBUG ((LM_DEBUG, "********************\n"));
      ACE_DEBUG ((LM_DEBUG,
                  "%s = %d\n",
                  "bytes sent immediately",
                  number_of_bytes_sent));
      ACE_DEBUG ((LM_DEBUG, "********************\n"));
      res = 0;
      break;
    case -1:
      // Something else went wrong.
      ACE_ERROR ((LM_ERROR,
                  "%p\n",
                  "ACE_Asynch_Write_Dgram::recv"));
      // the handler will not get called in this case so lets clean up our msg
      msg->release ();
      break;
    default:
      // Something undocumented really went wrong.
      ACE_ERROR ((LM_ERROR,
                  "%p\n",
                  "ACE_Asynch_Write_Dgram::recv"));
      msg->release ();
      break;
    }
  return res;
}
int UDPGenerator::writedatagram(const ACE_TCHAR * remotehost,
                                u_short remoteport)
{
    // We are using scatter/gather to send the message header and/*{{{*/
    // message body using 2 buffers

    // create a message block for the message header
    ACE_Message_Block* msg = 0;
    ACE_NEW_RETURN(msg, ACE_Message_Block(100), -1);
    const char rawMsg [] = "To be or not to be.";
    // Copy buf into the Message_Block and update the wr_ptr ().
    msg->copy(rawMsg, ACE_OS::strlen(rawMsg) + 1);

    // create a message block for the message body
    ACE_Message_Block* body = 0;
    ACE_NEW_RETURN(body, ACE_Message_Block(100), -1);
    ACE_OS::memset(body->wr_ptr(), 'X', 100);
    body->wr_ptr(100); // always remember to update the wr_ptr()

    msg->cont(body);

    // do the asynch send
    size_t number_of_bytes_sent = 0;
    ACE_INET_Addr serverAddr(remoteport, remotehost);
    int res = this->wd_.send(
                  msg, number_of_bytes_sent,
                  0,
                  serverAddr,
                  this->act_);

    switch (res)
    {
    case 0:
        // this is a good error.  The proactor will call our handler when the
        // send has completed.
        break;
    case 1:
        // actually sent something, we will handle it in the handler callback
        ACE_DEBUG ((LM_DEBUG, "********************\n"));
        ACE_DEBUG ((LM_DEBUG,
                    "%s = %d\n",
                    "bytes sent immediately",
                    number_of_bytes_sent));
        ACE_DEBUG ((LM_DEBUG, "********************\n"));
        res = 0;
        break;
    case -1:
        // Something else went wrong.
        ACE_ERROR ((LM_ERROR,
                    "%p\n",
                    "ACE_Asynch_Write_Dgram::recv"));
        // the handler will not get called in this case so lets clean up our msg
        msg->release ();
        break;
    default:
        // Something undocumented really went wrong.
        ACE_ERROR ((LM_ERROR,
                    "%p\n",
                    "ACE_Asynch_Write_Dgram::recv"));
        msg->release ();
        break;
    }
    return res;
}/*}}}*/
void OpenDDS::DCPS::DataDurabilityCache::init()
{
  ACE_Allocator * const allocator = this->allocator_.get();
  ACE_NEW_MALLOC(
    this->samples_,
    static_cast<sample_map_type *>(
      allocator->malloc(sizeof(sample_map_type))),
    sample_map_type(allocator));

  typedef DurabilityQueue<sample_data_type> data_queue_type;

  if (this->kind_ == DDS::PERSISTENT_DURABILITY_QOS) {
    // Read data from the filesystem and create the in-memory data structures
    // as if we had called insert() once for each "datawriter" directory.
    using OpenDDS::FileSystemStorage::Directory;
    using OpenDDS::FileSystemStorage::File;
    Directory::Ptr root_dir = Directory::create(this->data_dir_.c_str());
    std::vector<std::string> path(4);  // domain, topic, type, datawriter

    for (Directory::DirectoryIterator domain = root_dir->begin_dirs(),
         domain_end = root_dir->end_dirs(); domain != domain_end; ++domain) {
      path[0] = domain->name();
      DDS::DomainId_t domain_id;
      {
        std::istringstream iss(path[0]);
        iss >> domain_id;
      }

      for (Directory::DirectoryIterator topic = domain->begin_dirs(),
           topic_end = domain->end_dirs(); topic != topic_end; ++topic) {
        path[1] = topic->name();

        for (Directory::DirectoryIterator type = topic->begin_dirs(),
             type_end = topic->end_dirs(); type != type_end; ++type) {
          path[2] = type->name();

          key_type key(domain_id, path[1].c_str(), path[2].c_str(),
                       allocator);
          sample_list_type * sample_list = 0;
          ACE_NEW_MALLOC(sample_list,
                         static_cast<sample_list_type *>(
                           allocator->malloc(sizeof(sample_list_type))),
                         sample_list_type(0, static_cast<data_queue_type *>(0),
                                          allocator));
          this->samples_->bind(key, sample_list, allocator);

          for (Directory::DirectoryIterator dw = type->begin_dirs(),
               dw_end = type->end_dirs(); dw != dw_end; ++dw) {
            path[3] = dw->name();

            size_t old_len = sample_list->size();
            sample_list->size(old_len + 1);
            data_queue_type *& slot = (*sample_list)[old_len];

            // This variable is called "samples" in the insert() method be
            // we already have a "samples_" which is the overall data structure.
            data_queue_type * sample_queue = 0;
            ACE_NEW_MALLOC(sample_queue,
                           static_cast<data_queue_type *>(
                             allocator->malloc(sizeof(data_queue_type))),
                           data_queue_type(allocator));

            slot = sample_queue;
            sample_queue->fs_path_ = path;

            for (Directory::FileIterator file = dw->begin_files(),
                 file_end = dw->end_files(); file != file_end; ++file) {
              std::ifstream is;

              if (!file->read(is)) {
                if (DCPS_debug_level) {
                  ACE_ERROR((LM_ERROR,
                             ACE_TEXT("(%P|%t) DataDurabilityCache::init ")
                             ACE_TEXT("couldn't open file for PERSISTENT ")
                             ACE_TEXT("data: %C\n"), file->name().c_str()));
                }
                continue;
              }

              DDS::Time_t timestamp;
              is >> timestamp.sec >> timestamp.nanosec >> std::noskipws;
              is.get(); // consume separator

              const size_t CHUNK = 4096;
              ACE_Message_Block mb(CHUNK);
              ACE_Message_Block * current = &mb;

              while (!is.eof()) {
                is.read(current->wr_ptr(), current->space());

                if (is.bad()) break;

                current->wr_ptr(is.gcount());

                if (current->space() == 0) {
                  ACE_Message_Block * old = current;
                  current = new ACE_Message_Block(CHUNK);
                  old->cont(current);
                }
              }

              sample_queue->enqueue_tail(
                sample_data_type(timestamp, mb, allocator));

              if (mb.cont()) mb.cont()->release();    // delete the cont() chain
            }
          }
        }
      }
    }
  }

  CORBA::ORB_var orb = TheServiceParticipant->get_ORB();
  this->reactor_ = orb->orb_core()->reactor();
}
int
Receiver::open_addr (const ACE_INET_Addr &localAddr)
{
  ACE_DEBUG ((LM_DEBUG,
              "%N:%l:Receiver::open_addr called\n"));

  // Create a local UDP socket to receive datagrams.
  if (this->sock_dgram_.open (localAddr) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "ACE_SOCK_Dgram::open"), -1);

  // Initialize the asynchronous read.
  if (this->rd_.open (*this,
                      this->sock_dgram_.get_handle (),
                      this->completion_key_,
                      ACE_Proactor::instance ()) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "ACE_Asynch_Read_Dgram::open"), -1);

  // Create a buffer to read into.  We are using scatter/gather to
  // read the message header and message body into 2 buffers

  // create a message block to read the message header
  ACE_Message_Block* msg = 0;
  ACE_NEW_RETURN (msg, ACE_Message_Block (1024), -1);

  // the next line sets the size of the header, even though we
  // allocated a the message block of 1k, by setting the size to 20
  // bytes then the first 20 bytes of the reveived datagram will be
  // put into this message block.
  msg->size (20); // size of header to read is 20 bytes

  // create a message block to read the message body
  ACE_Message_Block* body = 0;
  ACE_NEW_RETURN (body, ACE_Message_Block (1024), -1);
  // The message body will not exceed 1024 bytes, at least not in this test.

  // set body as the cont of msg.  This associates the 2 message
  // blocks so that a read will fill the first block (which is the
  // header) up to size (), and use the cont () block for the rest of
  // the data.  You can chain up to IOV_MAX message block using this
  // method.
  msg->cont (body);

  // ok lets do the asynch read
  size_t number_of_bytes_recvd = 0;

  int res = rd_.recv (msg,
                      number_of_bytes_recvd,
                      0,
                      PF_INET,
                      this->act_);
  switch (res)
    {
    case 0:
      // this is a good error.  The proactor will call our handler when the
      // read has completed.
      break;
    case 1:
      // actually read something, we will handle it in the handler callback
      ACE_DEBUG ((LM_DEBUG, "********************\n"));
      ACE_DEBUG ((LM_DEBUG,
                  "%s = %d\n",
                  "bytes recieved immediately",
                  number_of_bytes_recvd));
      ACE_DEBUG ((LM_DEBUG, "********************\n"));
      res = 0;
      break;
    case -1:
      // Something else went wrong.
      ACE_ERROR ((LM_ERROR,
                  "%p\n",
                  "ACE_Asynch_Read_Dgram::recv"));
      // the handler will not get called in this case so lets clean up our msg
      msg->release ();
      break;
    default:
      // Something undocumented really went wrong.
      ACE_ERROR ((LM_ERROR,
                  "%p\n",
                  "ACE_Asynch_Read_Dgram::recv"));
      msg->release ();
      break;
    }

  return res;
}