Reference

ACE_Message_Block(3)

Stores messages for use throughout ACE (particularly ACE_Message_Queue).

NAME

ACE_Message_Block - Stores messages for use throughout ACE (particularly ACE_Message_Queue).

SYNOPSIS

#include <ace/Message_Block.h>
class ACE_Message_Block
{
  public:
    friend class ACE_Data_Block;
        enum{ MB_DATA = 0x01,
        MB_PROTO = 0x02,
        MB_BREAK = 0x03,
        MB_PASSFP = 0x04,
        MB_EVENT = 0x05,
        MB_SIG = 0x06,
        MB_IOCTL = 0x07,
        MB_SETOPTS = 0x08,
        MB_IOCACK = 0x81,
        MB_IOCNAK = 0x82,
        MB_PCPROTO = 0x83,
        MB_PCSIG = 0x84,
        MB_READ = 0x85,
        MB_FLUSH = 0x86,
        MB_STOP = 0x87,
        MB_START = 0x88,
        MB_HANGUP = 0x89,
        MB_ERROR = 0x8a,
        MB_PCEVENT = 0x8b,
        MB_NORMAL = 0x00,
        MB_PRIORITY = 0x80,
        MB_USER = 0x200 };
        
    typedef int ACE_Message_Type;
    typedef u_long Message_Flags;
    enum{ DONT_DELETE = 01, USER_FLAGS = 0x1000 };
    ACE_Message_Block (ACE_Allocator *message_block_allocator = 0);
    ACE_Message_Block (
        ACE_Data_Block *,
        ACE_Allocator *message_block_allocator = 0
        );
    ACE_Message_Block (
        const char *data,
        size_t size = 0,
        u_long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY
        );
    ACE_Message_Block (
        size_t size,
        ACE_Message_Type type = MB_DATA,
        ACE_Message_Block *cont = 0,
        const char *data = 0,
        ACE_Allocator *allocator_strategy = 0,
        ACE_Lock *locking_strategy = 0,
        u_long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY,
        const ACE_Time_Value & execution_time = ACE_Time_Value::zero,
        const ACE_Time_Value & deadline_time = ACE_Time_Value::max_time,
        ACE_Allocator *data_block_allocator = 0,
        ACE_Allocator *message_block_allocator = 0
        );
    int init (const char *data, size_t size = 0);
    int init (
        size_t size,
        ACE_Message_Type type = MB_DATA,
        ACE_Message_Block *cont = 0,
        const char *data = 0,
        ACE_Allocator *allocator_strategy = 0,
        ACE_Lock *locking_strategy = 0,
        u_long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY,
        const ACE_Time_Value & execution_time = ACE_Time_Value::zero,
        const ACE_Time_Value & deadline_time = ACE_Time_Value::max_time,
        ACE_Allocator *data_block_allocator = 0,
        ACE_Allocator *message_block_allocator = 0
        );
    virtual ~ACE_Message_Block (void);
    ACE_Message_Type msg_type (void) const;
    void msg_type (ACE_Message_Type type);
    int is_data_msg (void) const;
    ACE_Message_Type msg_class (void) const;
    Message_Flags set_flags (Message_Flags more_flags);
    Message_Flags clr_flags (Message_Flags less_flags);
    Message_Flags flags (void) const;
    u_long msg_priority (void) const;
    void msg_priority (u_long priority);
    const ACE_Time_Value & msg_execution_time (void) const;
    void msg_execution_time (const ACE_Time_Value & et);
    const ACE_Time_Value & msg_deadline_time (void) const;
    void msg_deadline_time (const ACE_Time_Value & dt);
    virtual ACE_Message_Block *clone (Message_Flags mask = 0) const;
    ACE_Message_Block *duplicate (void) const;
    static ACE_Message_Block *duplicate (const ACE_Message_Block *mb);
    ACE_Message_Block *release (void);
    static ACE_Message_Block *release (ACE_Message_Block *mb);
    int copy (const char *buf, size_t n);
    int copy (const char *buf);
    char *base (void) const;
    void base (char *data, size_t size, Message_Flags = DONT_DELETE);
    char *end (void) const;
    char *rd_ptr (void) const;
    void rd_ptr (char *ptr);
    void rd_ptr (size_t n);
    char *wr_ptr (void) const;
    void wr_ptr (char *ptr);
    void wr_ptr (size_t n);
    size_t length (void) const;
    void length (size_t n);
    size_t total_length (void) const;
    size_t total_size (void) const;
    size_t size (void) const;
    int size (size_t length);
    size_t space (void) const;
    void crunch (void);
    ACE_Data_Block *data_block (void) const;
    void data_block (ACE_Data_Block *);
    ACE_Data_Block *replace_data_block (ACE_Data_Block*);
    ACE_Message_Block *cont (void) const;
    void cont (ACE_Message_Block *);
    ACE_Message_Block *next (void) const;
    void next (ACE_Message_Block *);
    ACE_Message_Block *prev (void) const;
    void prev (ACE_Message_Block *);
    ACE_Lock *locking_strategy (void);
    ACE_Lock *locking_strategy (ACE_Lock *);
    int reference_count (void) const;
    void dump (void) const;
    ACE_ALLOC_HOOK_DECLARE;
  protected:
    ACE_Message_Block (
        size_t size,
        ACE_Message_Type type,
        ACE_Message_Block *cont,
        const char *data,
        ACE_Allocator *allocator_strategy,
        ACE_Lock *locking_strategy,
        Message_Flags flags,
        u_long priority,
        const ACE_Time_Value & execution_time,
        const ACE_Time_Value & deadline_time,
        ACE_Data_Block *db,
        ACE_Allocator *data_block_allocator,
        ACE_Allocator *message_block_allocator
        );
    int release_i (ACE_Lock *lock);
    int init_i (
        size_t size,
        ACE_Message_Type type,
        ACE_Message_Block *cont,
        const char *data,
        ACE_Allocator *allocator_strategy,
        ACE_Lock *locking_strategy,
        Message_Flags flags,
        u_long priority,
        const ACE_Time_Value & execution_time,
        const ACE_Time_Value & deadline_time,
        ACE_Data_Block *db,
        ACE_Allocator *data_block_allocator,
        ACE_Allocator *message_block_allocator
        );
    size_t rd_ptr_;
    size_t wr_ptr_;
    u_long priority_;
    ACE_Time_Value execution_time_;
    ACE_Time_Value deadline_time_;
    ACE_Message_Block *cont_;
    ACE_Message_Block *next_;
    ACE_Message_Block *prev_;
    ACE_Data_Block *data_block_;
    ACE_Allocator *message_block_allocator_;
  private:
    ACE_Message_Block &operator= (const ACE_Message_Block &);
    ACE_Message_Block (const ACE_Message_Block &);
};

DESCRIPTION

An ACE_Message_Block is modeled after the message data structures used in System V STREAMS. Its purpose is to enable efficient manipulation of arbitrarily-large messages without much incurring memory copying overhead. Here are the main characteristics of an ACE_Message_Block:

1. Contains a pointer to a reference-counted ACE_Data_Block, which in turn points to the actual data buffer. This allows very flexible and efficient sharing of data by multiple ACE_Message_Blocks.

2. One or more ACE_Message_Blocks can be linked to form a ``fragment chain.''

3. ACE_Message_Blocks can be linked together by prev_ and next_ pointers to form a queue of messages (e.g., this is how ACE_Message_Queue works).

Initialization and termination.

ACE_Message_Block (ACE_Allocator *message_block_allocator = 0);

Create an empty message.

ACE_Message_Block (
    ACE_Data_Block *,
    ACE_Allocator *message_block_allocator = 0
    );

Create an ACE_Message_Block that owns the ACE_Data_Block *.

ACE_Message_Block (
    const char *data,
    size_t size = 0,
    u_long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY
    );

Create a Message Block that assumes ownership of data without copying it (i.e., we don't delete it since we don't malloc it!). Note that the size of the Message_Block will be size, but the length will be 0 until wr_ptr is set.

ACE_Message_Block (
    size_t size,
    ACE_Message_Type type = MB_DATA,
    ACE_Message_Block *cont = 0,
    const char *data = 0,
    ACE_Allocator *allocator_strategy = 0,
    ACE_Lock *locking_strategy = 0,
    u_long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY,
    const ACE_Time_Value & execution_time = ACE_Time_Value::zero,
    const ACE_Time_Value & deadline_time = ACE_Time_Value::max_time,
    ACE_Allocator *data_block_allocator = 0,
    ACE_Allocator *message_block_allocator = 0
    );

Create an initialized message of type type containing size bytes. The cont argument initializes the continuation field in the Message_Block. If data == 0 then we create and own the data, using allocator to get the data if it's non-0. If data != 0 we assume ownership of the data (and don't delete it). If locking_strategy is non-0 then this is used to protect regions of code that access shared state (e.g., reference counting) from race conditions. Note that the size of the Message_Block will be size, but the length will be 0 until wr_ptr is set. The data_block_allocator is use to allocate the data blocks while the allocator_strategy is used to allocate the buffers contained by those. The message_block_allocator is used to allocate new Message_Block objects when a duplicate method is called. If a message_block_allocator is given, this Message_Block and future Message_Block objects created by duplicate will be free'ed into this allocator when they are released. Note: if you use this allocator, the Message_Block you created should have been created using this allocator because it will be released to the same allocator.

int init (const char *data, size_t size = 0);

Create a Message Block that assumes ownership of data (i.e., doesn't delete it since it didn't malloc it!). Note that the size of the Message_Block will be size, but the length will be 0 until wr_ptr is set.

int init (
    size_t size,
    ACE_Message_Type type = MB_DATA,
    ACE_Message_Block *cont = 0,
    const char *data = 0,
    ACE_Allocator *allocator_strategy = 0,
    ACE_Lock *locking_strategy = 0,
    u_long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY,
    const ACE_Time_Value & execution_time = ACE_Time_Value::zero,
    const ACE_Time_Value & deadline_time = ACE_Time_Value::max_time,
    ACE_Allocator *data_block_allocator = 0,
    ACE_Allocator *message_block_allocator = 0
    );

Create an initialized message of type type containing size bytes. The cont argument initializes the continuation field in the Message_Block. If data == 0 then we create and own the data, using allocator to get the data if it's non-0. If data != 0 we assume ownership of the data (and don't delete it). If locking_strategy is non-0 then this is used to protect regions of code that access shared state (e.g., reference counting) from race conditions. Note that the size of the Message_Block will be size, but the length will be 0 until wr_ptr is set. The data_block_allocator is use to allocate the data blocks while the allocator_strategy is used to allocate the buffers contained by those.

virtual ~ACE_Message_Block (void);

Delete all the resources held in the message.

Note that release is designed to release the continuation chain; the destructor is not. See release for details.

Message Type accessors and mutators.

ACE_Message_Type msg_type (void) const;

Get type of the message.

void msg_type (ACE_Message_Type type);

Set type of the message.

int is_data_msg (void) const;

Find out what type of message this is.

ACE_Message_Type msg_class (void) const;

Find out what class of message this is (there are two classes, normal messages and high-priority messages).

Message flag accessors and mutators.

Message_Flags set_flags (Message_Flags more_flags);

Bitwise-or the more_flags into the existing message flags and return the new value.

Message_Flags clr_flags (Message_Flags less_flags);

Clear the message flag bits specified in less_flags and return the new value.

Message_Flags flags (void) const;

Get the current message flags.

u_long msg_priority (void) const;

Get priority of the message.

void msg_priority (u_long priority);

Set priority of the message.

const ACE_Time_Value & msg_execution_time (void) const;

Get execution time associated with the message.

void msg_execution_time (const ACE_Time_Value & et);

Set execution time associated with the message.

const ACE_Time_Value & msg_deadline_time (void) const;

Get absolute time of deadline associated with the message.

void msg_deadline_time (const ACE_Time_Value & dt);

Set absolute time of deadline associated with the message.

Deep copy and shallow copy methods.

virtual ACE_Message_Block *clone (Message_Flags mask = 0) const;

Return an exact "deep copy" of the message, i.e., create fresh new copies of all the Data_Blocks and continuations.

ACE_Message_Block *duplicate (void) const;

Return a "shallow" copy that increments our reference count by 1.

static ACE_Message_Block *duplicate (const ACE_Message_Block *mb);

Return a "shallow" copy that increments our reference count by 1. This is similar to CORBA's _duplicate method, which is useful if you want to eliminate lots of checks for NULL mb pointers before calling _duplicate on them.

ACE_Message_Block *release (void);

Decrease the shared ACE_Data_Block's reference count by 1. If the ACE_Data_Block's reference count goes to 0, it is deleted. In all cases, this ACE_Message_Block is deleted - it must have come from the heap, or there will be trouble.

release is designed to release the continuation chain; the destructor is not. If we make the destructor release the continuation chain by calling release or delete on the message blocks in the continuation chain, the following code will not work since the message block in the continuation chain is not off the heap:

ACE_Message_Block mb1 (1024);
ACE_Message_Block mb2 (1024);

mb1.cont (&mb2);

And hence, call release on a dynamically allocated message block. This will release all the message blocks in the continuation chain. If you call delete or let the message block fall off the stack, cleanup of the message blocks in the continuation chain becomes the responsibility of the user.

static ACE_Message_Block *release (ACE_Message_Block *mb);

This behaves like the non-static method release, except that it checks if mb is 0. This is similar to CORBA::release, which is useful if you want to eliminate lots of checks for NULL pointers before calling release on them. Returns mb.

Operations on Message data

int copy (const char *buf, size_t n);

Copies n bytes from buf into the Message_Block starting at the wr_ptr offset. Return 0 and increment wr_ptr by n if the method succeeds. Returns -1 if the size of the message is too small, i.e., for this to work correct, end must be = wr_ptr.

int copy (const char *buf);

Copies buf into the Message_Block starting at the wr_ptr offset. This call assumees that buf is NUL-terminated. Return 0 and increment wr_ptr by ACE_OS::strlen (buf) + 1 if the method succeeds. Returns -1 if the size of the message is too small, i.e., for this to work correct, end must be = wr_ptr.

char *base (void) const;

Get message data.

void base (char *data, size_t size, Message_Flags = DONT_DELETE);

Set message data (doesn't reallocate).

char *end (void) const;

Return a pointer to 1 past the end of the data in a message.

char *rd_ptr (void) const;

Get the read pointer.

void rd_ptr (char *ptr);

Set the read pointer to ptr.

void rd_ptr (size_t n);

Set the read pointer ahead n bytes.

char *wr_ptr (void) const;

Get the write pointer.

void wr_ptr (char *ptr);

Set the write pointer to ptr.

void wr_ptr (size_t n);

Set the write pointer ahead n bytes. This is used to compute the length of a message.

= Message length is wr_ptr - rd_ptr.

size_t length (void) const;

Get the length of the message

void length (size_t n);

Set the length of the message

size_t total_length (void) const;

Get the length of the Message_Blocks, including chained Message_Blocks.

= Set/get Message_Block size info.

size_t total_size (void) const;

Get the total number of bytes in all Message_Blocks, including chained Message_Blocks.

size_t size (void) const;

Get the number of bytes in the top-level Message_Block (i.e., does not consider the bytes in chained Message_Blocks).

int size (size_t length);

Set the number of bytes in the top-level Message_Block, reallocating space if necessary. However, the rd_ptr_ and wr_ptr_ remain at the original offsets into the buffer, even if it is reallocated. Returns 0 if successful, else -1.

size_t space (void) const;

Get the number of bytes in the top-level Message_Block.

void crunch (void);

Normalizes data in message block to align with the base.

= ACE_Data_Block methods.

ACE_Data_Block *data_block (void) const;

Get the data block.

void data_block (ACE_Data_Block *);

Set the data block (releasing the original one).

ACE_Data_Block *replace_data_block (ACE_Data_Block*);

Set the data block (returning the original one).

The continuation field chains together composite messages.

ACE_Message_Block *cont (void) const;

Get the continuation field.

void cont (ACE_Message_Block *);

Set the continuation field.

= Pointer to the Message_Block directly ahead in the ACE_Message_Queue.

ACE_Message_Block *next (void) const;

Get link to next message.

void next (ACE_Message_Block *);

Set link to next message.

= Pointer to the Message_Block directly behind in the ACE_Message_Queue.

ACE_Message_Block *prev (void) const;

Get link to prev message.

void prev (ACE_Message_Block *);

Set link to prev message.

The locking strategy prevents race conditions.

ACE_Lock *locking_strategy (void);

Get the locking strategy.

ACE_Lock *locking_strategy (ACE_Lock *);

Set a new locking strategy and return the hold one.

int reference_count (void) const;

Get the current reference count.

void dump (void) const;

Dump the state of an object.

ACE_ALLOC_HOOK_DECLARE;

Declare the dynamic allocation hooks.

Internal initialization methods.

ACE_Message_Block (
    size_t size,
    ACE_Message_Type type,
    ACE_Message_Block *cont,
    const char *data,
    ACE_Allocator *allocator_strategy,
    ACE_Lock *locking_strategy,
    Message_Flags flags,
    u_long priority,
    const ACE_Time_Value & execution_time,
    const ACE_Time_Value & deadline_time,
    ACE_Data_Block *db,
    ACE_Allocator *data_block_allocator,
    ACE_Allocator *message_block_allocator
    );

Perform the actual initialization.

int release_i (ACE_Lock *lock);

Internal release implementation Returns 1 if the data block has to be destroyed.

int init_i (
    size_t size,
    ACE_Message_Type type,
    ACE_Message_Block *cont,
    const char *data,
    ACE_Allocator *allocator_strategy,
    ACE_Lock *locking_strategy,
    Message_Flags flags,
    u_long priority,
    const ACE_Time_Value & execution_time,
    const ACE_Time_Value & deadline_time,
    ACE_Data_Block *db,
    ACE_Allocator *data_block_allocator,
    ACE_Allocator *message_block_allocator
    );

Perform the actual initialization.

size_t rd_ptr_;

Pointer to beginning of next read.

size_t wr_ptr_;

Pointer to beginning of next write.

u_long priority_;

Priority of message.

ACE_Time_Value execution_time_;

execution time associated with the message

ACE_Time_Value deadline_time_;

absolute deadline time for message

Links to other ACE_Message_Block *s.

ACE_Message_Block *cont_;

Pointer to next message block in the chain.

ACE_Message_Block *next_;

Pointer to next message in the list.

ACE_Message_Block *prev_;

Pointer to previous message in the list.

ACE_Data_Block *data_block_;

Pointer to the reference counted data structure that contains the actual memory buffer.

ACE_Allocator *message_block_allocator_;

The allocator used to destroy ourselves when release is called and create new message blocks on duplicate.

AUTHOR

Doug Schmidt

LIBRARY

ace