Public Member Functions | Private Attributes

TAO_Synch_Queued_Message Class Reference

Specialize TAO_Queued_Message for synchronous requests, i.e. twoways and oneways sent with reliability better than SYNC_NONE. More...

#include <Synch_Queued_Message.h>

Inheritance diagram for TAO_Synch_Queued_Message:
Inheritance graph
[legend]
Collaboration diagram for TAO_Synch_Queued_Message:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 TAO_Synch_Queued_Message (const ACE_Message_Block *contents, TAO_ORB_Core *oc, ACE_Allocator *alloc=0, bool is_heap_allocated=false)
 Constructor.
virtual ~TAO_Synch_Queued_Message (void)
 Destructor.
const ACE_Message_Blockcurrent_block (void) const
Implement the Template Methods from TAO_Queued_Message

virtual size_t message_length (void) const
 Return the length of the message.
virtual int all_data_sent (void) const
 Return 1 if all the data has been sent.
virtual void fill_iov (int iovcnt_max, int &iovcnt, iovec iov[]) const
 Fill up an io vector using the connects of the message.
virtual void bytes_transferred (size_t &byte_count)
 Update the internal state, data has been sent.
virtual TAO_Queued_Messageclone (ACE_Allocator *alloc)
 Clone this element.
virtual void destroy (void)
 Reclaim resources.
virtual void copy_if_necessary (const ACE_Message_Block *chain)
 Provide a hook for copying the underlying data.

Private Attributes

ACE_Message_Blockcontents_
 The contents of the message.
ACE_Message_Blockcurrent_block_
 The current message block.
bool own_contents_
 Do we own the contents_ message block?

Detailed Description

Specialize TAO_Queued_Message for synchronous requests, i.e. twoways and oneways sent with reliability better than SYNC_NONE.

Reliable requests block the sending thread until the message is sent, likewise, the sending thread must be informed if the connection is closed or the message times out.

In contrast oneway (and AMI) requests sent with the SYNC_NONE policy are simple discarded if the connection fails or they timeout.

Another important difference is the management of the data buffer: one SYNC_NONE messages the buffer is immediately copied into a newly allocated buffer, and must be deallocated. Other types of requests use the memory allocated by the sending thread.

Definition at line 47 of file Synch_Queued_Message.h.


Constructor & Destructor Documentation

TAO_Synch_Queued_Message::TAO_Synch_Queued_Message ( const ACE_Message_Block contents,
TAO_ORB_Core oc,
ACE_Allocator alloc = 0,
bool  is_heap_allocated = false 
)

Constructor.

Parameters:
contents The message block chain that must be sent.
alloc The allocator that is used to allocate objects of this type.

Definition at line 16 of file Synch_Queued_Message.cpp.

  : TAO_Queued_Message (oc, alloc, is_heap_allocated)
  , contents_ (const_cast<ACE_Message_Block*> (contents))
  , current_block_ (contents_)
  , own_contents_ (is_heap_allocated)
{
}

TAO_Synch_Queued_Message::~TAO_Synch_Queued_Message ( void   )  [virtual]

Destructor.

Definition at line 28 of file Synch_Queued_Message.cpp.

{

}


Member Function Documentation

int TAO_Synch_Queued_Message::all_data_sent ( void   )  const [virtual]

Return 1 if all the data has been sent.

Implements TAO_Queued_Message.

Definition at line 51 of file Synch_Queued_Message.cpp.

{
  return this->current_block_ == 0;
}

void TAO_Synch_Queued_Message::bytes_transferred ( size_t &  byte_count  )  [virtual]

Update the internal state, data has been sent.

After the TAO_Transport class completes a successful (or partially successful) I/O operation it must update the state of all the messages queued. This callback method is used by each message to update its state and determine if all the data has been sent already.

Parameters:
byte_count The number of bytes succesfully sent. The TAO_Queued_Message should decrement this value by the number of bytes that must still be sent.
Returns:
Returns 1 if the TAO_Queued_Message has any more data to send.

Implements TAO_Queued_Message.

Definition at line 83 of file Synch_Queued_Message.cpp.

{
  this->state_changed_i (TAO_LF_Event::LFS_ACTIVE);

  while (this->current_block_ != 0 && byte_count > 0)
    {
      size_t const l = this->current_block_->length ();

      if (byte_count < l)
        {
          this->current_block_->rd_ptr (byte_count);
          byte_count = 0;
          return;
        }

      byte_count -= l;
      this->current_block_->rd_ptr (l);
      this->current_block_ = this->current_block_->cont ();

      while (this->current_block_ != 0
             && this->current_block_->length () == 0)
        {
          this->current_block_ = this->current_block_->cont ();
        }
    }

  if (this->current_block_ == 0)
    this->state_changed (TAO_LF_Event::LFS_SUCCESS,
                         this->orb_core_->leader_follower ());
}

TAO_Queued_Message * TAO_Synch_Queued_Message::clone ( ACE_Allocator allocator  )  [virtual]

Clone this element.

Implements TAO_Queued_Message.

Definition at line 115 of file Synch_Queued_Message.cpp.

{
  TAO_Synch_Queued_Message *qm = 0;

  // Clone the message block.
  // NOTE: We wantedly do the cloning from <current_block_> instead of
  // starting from <contents_> since we dont want to clone blocks that
  // have already been sent on the wire. Waste of memory and
  // associated copying.
  ACE_Message_Block *mb = this->current_block_->clone ();

  if (alloc)
    {
      ACE_NEW_MALLOC_RETURN (qm,
                             static_cast<TAO_Synch_Queued_Message *> (
                               alloc->malloc (sizeof (TAO_Synch_Queued_Message))),
                             TAO_Synch_Queued_Message (mb,
                                                       this->orb_core_,
                                                       alloc,
                                                       true),
                             0);
    }
  else
    {
      ACE_NEW_RETURN (qm,
                      TAO_Synch_Queued_Message (mb, this->orb_core_, 0, true),
                      0);
    }

  return qm;
}

void TAO_Synch_Queued_Message::copy_if_necessary ( const ACE_Message_Block chain  )  [virtual]

Provide a hook for copying the underlying data.

Parameters:
chain For use in determining origin of underlying data. This parameter must not be modified (through const_cast).

Implements TAO_Queued_Message.

Definition at line 176 of file Synch_Queued_Message.cpp.

{
  if (!this->own_contents_)
    {
      // Go through the message block chain looking for the message block
      // that matches our "current" message block.
      for (const ACE_Message_Block* mb = chain; mb != 0; mb = mb->cont ())
        {
          if (mb == this->current_block_)
            {
              // Once we have found the message block, we need to
              // clone the current block so that if another thread comes
              // in and calls reset() on the output stream (via another
              // invocation on the transport), it doesn't cause the rest
              // of our message to be released.
              this->own_contents_ = true;
              this->contents_ = this->current_block_->clone ();
              this->current_block_ = this->contents_;
              break;
            }
        }
    }
}

const ACE_Message_Block * TAO_Synch_Queued_Message::current_block ( void   )  const

Definition at line 34 of file Synch_Queued_Message.cpp.

{
  return this->current_block_;
}

void TAO_Synch_Queued_Message::destroy ( void   )  [virtual]

Reclaim resources.

Reliable messages are allocated from the stack, thus they do not be deallocated. Asynchronous (SYNC_NONE) messages are allocated from the heap (or a pool), they need to be reclaimed explicitly.

Implements TAO_Queued_Message.

Definition at line 148 of file Synch_Queued_Message.cpp.

{
  if (this->own_contents_)
    {
      ACE_Message_Block::release (this->contents_);
      this->current_block_ = 0;
      this->contents_ = 0;
    }

  if (this->is_heap_created_)
    {
      // If we have an allocator release the memory to the allocator
      // pool.
      if (this->allocator_)
        {
          ACE_DES_FREE (this,
                        this->allocator_->free,
                        TAO_Synch_Queued_Message);

        }
      else // global release..
        {
          delete this;
        }
    }
}

void TAO_Synch_Queued_Message::fill_iov ( int  iovcnt_max,
int &  iovcnt,
iovec  iov[] 
) const [virtual]

Fill up an io vector using the connects of the message.

Different versions of this class represent the message using either a single buffer, or a message block. This method allows a derived class to fill up the contents of an io vector, the TAO_Transport class uses this method to group as many messages as possible in an iovector before sending them to the OS I/O subsystem.

Parameters:
iovcnt_max The number of elements in iov
iovcnt The number of elements already used by iov, this method should update this counter
iov The io vector

Implements TAO_Queued_Message.

Definition at line 57 of file Synch_Queued_Message.cpp.

{
  ACE_ASSERT (iovcnt_max > iovcnt);

  for (const ACE_Message_Block *message_block = this->current_block_;
       message_block != 0 && iovcnt < iovcnt_max;
       message_block = message_block->cont ())
    {
      size_t const message_block_length = message_block->length ();

      // Check if this block has any data to be sent.
      if (message_block_length > 0)
        {
              // Collect the data in the iovec.
          iov[iovcnt].iov_base = message_block->rd_ptr ();
          iov[iovcnt].iov_len  = static_cast<u_long> (message_block_length);

          // Increment iovec counter.
          ++iovcnt;
        }
    }
}

size_t TAO_Synch_Queued_Message::message_length ( void   )  const [virtual]

Return the length of the message.

If the message has been partially sent it returns the number of bytes that are still not sent.

Implements TAO_Queued_Message.

Definition at line 40 of file Synch_Queued_Message.cpp.

{
  if (this->current_block_ == 0)
    {
      return 0;
    }

  return this->current_block_->total_length ();
}


Member Data Documentation

The contents of the message.

The message is normally generated by a TAO_OutputCDR stream. The application marshals the payload, possibly generating a chain of message block connected via the 'cont()' field.

Definition at line 86 of file Synch_Queued_Message.h.

The current message block.

The message may be set in multiple writev() operations. This point keeps track of the next message to send out.

Definition at line 93 of file Synch_Queued_Message.h.

Do we own the contents_ message block?

This flag differs from the is_heap_allocated_ flag in that it only applies to the contents_ message block and not the TAO_Synch_Queued_Message object itself.

Definition at line 101 of file Synch_Queued_Message.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines