---
name: "ACE_Message_Block"
section: "3"
platform: "linux"
package: "libace-doc"
version: "5.0.7-4"
release: "Debian 2.2 (Potato)"
platforms: ["linux"]
url: "https://new.carta.tech/ACE_Message_Block"
---

# 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
