ACE_Message_Queue).
#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);void crunch (void);void reset (void);char *base (void) const;void base (char *data, size_t size, Message_Flags = DONT_DELETE);char *end (void) const;char *mark (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 total_capacity (void) const;size_t capacity (void) const;size_t space (void) const;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 &);};
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).
ACE_Message_Block (ACE_Allocator *message_block_allocator = 0);
ACE_Message_Block (
ACE_Data_Block *,
ACE_Allocator *message_block_allocator = 0
);
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
);
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
);
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);
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
);
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);
Note that release is designed to release the continuation
chain; the destructor is not. See release for details.
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;
normal messages and high-priority messages).
Message_Flags set_flags (Message_Flags more_flags);
more_flags into the existing message flags and
return the new value.
Message_Flags clr_flags (Message_Flags less_flags);
less_flags and return
the new value.
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);
_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);
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);
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.
int copy (const char *buf, size_t n);
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);
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.
void crunch (void);
Message_Block to align with the base.
void reset (void);
char *base (void) const;
void base (char *data, size_t size, Message_Flags = DONT_DELETE);
char *end (void) const;
char *mark (void) const;
char *rd_ptr (void) const;
void rd_ptr (char *ptr);
ptr.
void rd_ptr (size_t n);
n bytes.
char *wr_ptr (void) const;
void wr_ptr (char *ptr);
ptr.
void wr_ptr (size_t n);
n bytes. This is used to compute
the length of a message.
= Message length is wr_ptr - rd_ptr.
size_t length (void) const;
void length (size_t n);
size_t total_length (void) const;
Message_Blocks, including chained
Message_Blocks.
= Set/get Message_Block size info.
size_t total_size (void) const;
Message_Blocks, including
chained Message_Blocks.
size_t size (void) const;
Message_Block (i.e.,
does not consider the bytes in chained Message_Blocks).
int size (size_t length);
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 total_capacity (void) const;
Message_Block, including
chained Message_Blocks.
size_t capacity (void) const;
Message_Block.
size_t space (void) const;
wr_ptr_ in the
top-level Message_Block.
= ACE_Data_Block methods.
ACE_Data_Block *data_block (void) const;
ACE_Message_Block
still references the block; this call does not change the reference
count.
void data_block (ACE_Data_Block *);
ACE_Data_Block is released
as a result of this call. If you need to keep the original block, call
replace_data_block instead. Upon return, this ACE_Message_Block
holds a pointer to the new ACE_Data_Block, taking over the reference
you held on it prior to the call.
ACE_Data_Block *replace_data_block (ACE_Data_Block*);
ACE_Data_Block
is returned, and not released (as it is with data_block).
ACE_Message_Block *cont (void) const;
void cont (ACE_Message_Block *);
= Pointer to the Message_Block directly ahead in the ACE_Message_Queue.
ACE_Message_Block *next (void) const;
void next (ACE_Message_Block *);
= Pointer to the Message_Block directly behind in the ACE_Message_Queue.
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;
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_;
schmidt@cs.wustl.edu