summaryrefslogtreecommitdiff
path: root/ace/Message_Block.h
diff options
context:
space:
mode:
Diffstat (limited to 'ace/Message_Block.h')
-rw-r--r--ace/Message_Block.h1039
1 files changed, 0 insertions, 1039 deletions
diff --git a/ace/Message_Block.h b/ace/Message_Block.h
deleted file mode 100644
index 0fff7705b5c..00000000000
--- a/ace/Message_Block.h
+++ /dev/null
@@ -1,1039 +0,0 @@
-// -*- C++ -*-
-
-//==========================================================================
-/**
- * @file Message_Block.h
- *
- * $Id$
- *
- * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
- */
-//==========================================================================
-
-#ifndef ACE_MESSAGE_BLOCK_H
-#define ACE_MESSAGE_BLOCK_H
-
-#include /**/ "ace/pre.h"
-
-#include "ace/ACE_export.h"
-
-#if !defined (ACE_LACKS_PRAGMA_ONCE)
-# pragma once
-#endif /* ACE_LACKS_PRAGMA_ONCE */
-
-#include "ace/Default_Constants.h"
-#include "ace/Global_Macros.h"
-#include "ace/Time_Value.h"
-
-#include <stdlib.h>
-
-// Forward declaration.
-class ACE_Allocator;
-class ACE_Data_Block;
-class ACE_Lock;
-
-
-/**
- * @class ACE_Message_Block
- *
- * @brief Stores messages for use throughout ACE (particularly
- * <ACE_Message_Queue>).
- *
- * 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 incurring much 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_Block>s.
- * 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).
- */
-class ACE_Export ACE_Message_Block
-{
-public:
- friend class ACE_Data_Block;
-
- enum
- {
- // = Data and proto
- /// Undifferentiated data message
- MB_DATA = 0x01,
- /// Undifferentiated protocol control
- MB_PROTO = 0x02,
-
- // = Control messages
- /// Line break (regular and priority)
- MB_BREAK = 0x03,
- /// Pass file pointer
- MB_PASSFP = 0x04,
- /// Post an event to an event queue
- MB_EVENT = 0x05,
- /// Generate process signal
- MB_SIG = 0x06,
- /// ioctl; set/get params
- MB_IOCTL = 0x07,
- /// Set various stream head options
- MB_SETOPTS = 0x08,
-
- // = Control messages
- /// Acknowledge ioctl (high priority; go to head of queue)
- MB_IOCACK = 0x81,
- /// Negative ioctl acknowledge
- MB_IOCNAK = 0x82,
- /// Priority proto message
- MB_PCPROTO = 0x83,
- /// Generate process signal
- MB_PCSIG = 0x84,
- /// Generate read notification
- MB_READ = 0x85,
- /// Flush your queues
- MB_FLUSH = 0x86,
- /// Stop transmission immediately
- MB_STOP = 0x87,
- /// Restart transmission after stop
- MB_START = 0x88,
- /// Line disconnect
- MB_HANGUP = 0x89,
- /// Fatal error used to set u.u_error
- MB_ERROR = 0x8a,
- /// Post an event to an event queue
- MB_PCEVENT = 0x8b,
-
- // = Message class masks
- /// Normal priority message mask
- MB_NORMAL = 0x00,
- /// High priority control message mask
- MB_PRIORITY = 0x80,
- /// User-defined message mask
- MB_USER = 0x200
- };
-
- typedef int ACE_Message_Type;
- typedef unsigned long Message_Flags;
-
- enum
- {
- /// Don't delete the data on exit since we don't own it.
- DONT_DELETE = 01,
- /// user defined flags start here
- USER_FLAGS = 0x1000
- };
-
- // = Initialization and termination.
- /// Create an empty message.
- ACE_Message_Block (ACE_Allocator *message_block_allocator = 0);
-
- /**
- * Create an <ACE_Message_Block> that owns the <ACE_Data_Block>
- * without copying it. If the <flags> is set to DONT_DELETE we
- * don't delete the ACE_Data_Block. It is left to the client's
- * responsibility to take care of the memory allocated for the
- * data_block
- */
- ACE_Message_Block (ACE_Data_Block *,
- Message_Flags flags = 0,
- ACE_Allocator *message_block_allocator = 0);
-
- /**
- * 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 (const char *data,
- size_t size = 0,
- unsigned long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY);
-
- /**
- * 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 that we have ownership of the <data> till
- * this object ceases to exist (and don't delete it during
- * destruction). 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.
- */
- 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,
- unsigned 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);
-
- /**
- * A copy constructor. This constructor is a bit different. If the
- * incoming Message Block has a data block from the stack this
- * constructor does a deep copy ie. allocates a new data block on
- * the heap and does a copy of the data from the incoming message
- * block. As a final note, the alignment information is used to
- * align the data block if it is created afresh. If the incoming
- * <mb> has a data block has a data block allocated from the heap,
- * then this constructor just duplicates (ie. a shallow copy) the
- * data block of the incoming <mb>.
- */
- ACE_Message_Block (const ACE_Message_Block &mb,
- size_t align);
-
- /**
- * Create a Message Block that assumes it has ownership of <data>,
- * but in reality it doesnt (i.e., cannot 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 (const char *data,
- size_t size = 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 that we have ownership of the <data> till
- * this object ceases to exist (and don't delete it during
- * destruction). 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.
- */
- 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,
- unsigned 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);
-
- /**
- * 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.
- */
- virtual ~ACE_Message_Block (void);
-
- // = Message Type accessors and mutators.
-
- /// Get type of the message.
- ACE_Message_Type msg_type (void) const;
-
- /// Set type of the message.
- void msg_type (ACE_Message_Type type);
-
- /// Find out what type of message this is.
- int is_data_msg (void) const;
-
- /// Find out what class of message this is (there are two classes,
- /// <normal> messages and <high-priority> messages).
- ACE_Message_Type msg_class (void) const;
-
- // = Message flag accessors and mutators.
- /// Bitwise-or the <more_flags> into the existing message flags and
- /// return the new value.
- Message_Flags set_flags (Message_Flags more_flags);
-
- /// Clear the message flag bits specified in <less_flags> and return
- /// the new value.
- Message_Flags clr_flags (Message_Flags less_flags);
-
- /// Get the current message flags.
- Message_Flags flags (void) const;
-
- // = Data Block flag accessors and mutators.
- /// Bitwise-or the <more_flags> into the existing message flags and
- /// return the new value.
- /* @todo: I think the following set of methods could not be used at
- * all. May be they are useless. Let us have it so that we dont
- * mess up memory management of the Message_Block. Somebody correct
- * me if I am totally totally wrong..
- */
- Message_Flags set_self_flags (ACE_Message_Block::Message_Flags more_flags);
-
- /// Clear the message flag bits specified in <less_flags> and return
- /// the new value.
- Message_Flags clr_self_flags (ACE_Message_Block::Message_Flags less_flags);
-
- /// Get the current message flags.
- Message_Flags self_flags (void) const;
-
- /// Get priority of the message.
- unsigned long msg_priority (void) const;
-
- /// Set priority of the message.
- void msg_priority (unsigned long priority);
-
- /// Get execution time associated with the message.
- const ACE_Time_Value &msg_execution_time (void) const;
-
- /// Set execution time associated with the message.
- void msg_execution_time (const ACE_Time_Value &et);
-
- /// Get absolute time of deadline associated with the message.
- const ACE_Time_Value &msg_deadline_time (void) const;
-
- /// Set absolute time of deadline associated with the message.
- void msg_deadline_time (const ACE_Time_Value &dt);
-
- // = Deep copy and shallow copy methods.
-
- /// Return an exact "deep copy" of the message, i.e., create fresh
- /// new copies of all the Data_Blocks and continuations.
- virtual ACE_Message_Block *clone (Message_Flags mask = 0) const;
-
- /// Return a "shallow" copy that increments our reference count by 1.
- virtual ACE_Message_Block *duplicate (void) const;
-
- /**
- * 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.
- */
- static ACE_Message_Block *duplicate (const ACE_Message_Block *mb);
-
- /**
- * 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.
- *
- * @retval 0, always, and the object this method was invoked on is no
- * longer valid.
- */
- virtual ACE_Message_Block *release (void);
-
- /**
- * 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>.
- */
- static ACE_Message_Block *release (ACE_Message_Block *mb);
-
- // = Operations on Message data
-
- /**
- * Copies data into this ACE_Message_Block. Data is copied into the
- * block starting at the current write pointer.
- *
- * @param buf Pointer to the buffer to copy from.
- * @param n The number of bytes to copy.
- *
- * @retval 0 on success; the write pointer is advanced by @arg n.
- * @retval -1 if the amount of free space following the write pointer
- * in the block is less than @arg n. Free space can be checked
- * by calling space().
- */
- int copy (const char *buf, size_t n);
-
- /**
- * Copies a 0-terminated character string into this ACE_Message_Block.
- * The string is copied into the block starting at the current write
- * pointer. The 0-terminator is included in the copied data.
- *
- * @param buf Pointer to the character string to copy from.
- *
- * @retval 0 on success; the write pointer is advanced by the string's
- * length, including the 0 terminator.
- * @retval -1 if the amount of free space following the write pointer
- * in the block is less than required to hold the entire string.
- * Free space can be checked by calling space().
- */
- int copy (const char *buf);
-
- /// Normalizes data in the top-level <Message_Block> to align with the base,
- /// i.e., it "shifts" the data pointed to by <rd_ptr> down to the <base> and
- /// then readjusts <rt_ptr> to point to <base> and <wr_ptr> to point
- /// to <base> + the length of the moved data.
- void crunch (void);
-
- /// Resets the Message Block data to contain nothing, i.e., sets the
- /// read and write pointers to align with the base.
- void reset (void);
-
- /// Access all the allocators in the message block.
- /// @@todo: Not sure whether we would need finer control while
- /// trying to access allocators ie. a method for every allocator.
- /**
- * This method returns the allocators only from the first message
- * block in the chain.
- *
- * @param allocator_strategy Strategy used to allocate the
- * underlying buffer
- *
- * @param data_block_allocator Strategy used to allocate the
- * underlying data block
- *
- * @param message_block_allocator Strategy used to allocate the
- * message block
- */
- void access_allocators (ACE_Allocator *&allocator_strategy,
- ACE_Allocator *&data_block_allocator,
- ACE_Allocator *&message_block_allocator);
-
- /// Reset all the allocators in the message block.
- /// @@todo: Not sure whether we would need finer control while
- /// trying to reset allocators ie. a method for every allocator.
- /**
- * This method resets the allocators in all the message blocks in
- * the chain.
- */
- void reset_allocators (ACE_Allocator *allocator_strategy = 0,
- ACE_Allocator *data_block_allocator = 0,
- ACE_Allocator *message_block_allocator = 0);
-
- /// Get message data.
- char *base (void) const;
-
- /// Set message data (doesn't reallocate).
- void base (char *data,
- size_t size,
- Message_Flags = DONT_DELETE);
-
- /// Return a pointer to 1 past the end of the allocated data in a message.
- char *end (void) const;
-
- /**
- * Return a pointer to 1 past the end of the allotted data in a message.
- * Allotted data may be less than allocated data if a value smaller than
- * capacity() to is passed to size().
- */
- char *mark (void) const;
-
- /// Get the read pointer.
- char *rd_ptr (void) const;
-
- /// Set the read pointer to <ptr>.
- void rd_ptr (char *ptr);
-
- /// Set the read pointer ahead <n> bytes.
- void rd_ptr (size_t n);
-
- /// Get the write pointer.
- char *wr_ptr (void) const;
-
- /// Set the write pointer to <ptr>.
- void wr_ptr (char *ptr);
-
- /// Set the write pointer ahead <n> bytes. This is used to compute
- /// the <length> of a message.
- void wr_ptr (size_t n);
-
- /** @name Message length and size operations
- *
- * Message length is (wr_ptr - rd_ptr).
- *
- * Message size is capacity of the message, including data outside
- * the [rd_ptr,wr_ptr] range.
- */
- //@{
- /// Get the length of the message
- size_t length (void) const;
-
- /// Set the length of the message
- void length (size_t n);
-
- /// Get the length of the <Message_Block>s, including chained
- /// <Message_Block>s.
- size_t total_length (void) const;
-
- /// Get the total number of bytes in all <Message_Block>s, including
- /// chained <Message_Block>s.
- size_t total_size (void) const;
-
- /// Get the total number of bytes and total length in all
- /// <Message_Block>s, including chained <Message_Block>s.
- void total_size_and_length (size_t &mb_size,
- size_t &mb_length) const;
-
- /// Get the number of bytes in the top-level <Message_Block> (i.e.,
- /// does not consider the bytes in chained <Message_Block>s).
- size_t size (void) const;
-
- /**
- * 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.
- */
- int size (size_t length);
-
- /// Get the number of allocated bytes in all <Message_Block>, including
- /// chained <Message_Block>s.
- size_t total_capacity (void) const;
-
- /// Get the number of allocated bytes in the top-level <Message_Block>.
- size_t capacity (void) const;
-
- /// Get the number of bytes available after the <wr_ptr_> in the
- /// top-level <Message_Block>.
- size_t space (void) const;
- //@}
-
- // = <ACE_Data_Block> methods.
-
- /**
- * Get a pointer to the data block. Note that the <ACE_Message_Block>
- * still references the block; this call does not change the reference
- * count.
- */
- ACE_Data_Block *data_block (void) const;
-
- /**
- * Set a new data block pointer. The original <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.
- */
- void data_block (ACE_Data_Block *);
-
- /// Set a new data block pointer. A pointer to the original <ACE_Data_Block>
- /// is returned, and not released (as it is with <data_block>).
- ACE_Data_Block *replace_data_block (ACE_Data_Block*);
-
- // = The continuation field chains together composite messages.
- /// Get the continuation field.
- ACE_Message_Block *cont (void) const;
-
- /// Set the continuation field.
- void cont (ACE_Message_Block *);
-
- // = Pointer to the <Message_Block> directly ahead in the <ACE_Message_Queue>.
- /// Get link to next message.
- ACE_Message_Block *next (void) const;
-
- /// Set link to next message.
- void next (ACE_Message_Block *);
-
- // = Pointer to the <Message_Block> directly behind in the <ACE_Message_Queue>.
- /// Get link to prev message.
- ACE_Message_Block *prev (void) const;
-
- /// Set link to prev message.
- void prev (ACE_Message_Block *);
-
- // = The locking strategy prevents race conditions.
- /// Get the locking strategy.
- ACE_Lock *locking_strategy (void);
-
- /// Set a new locking strategy and return the hold one.
- ACE_Lock *locking_strategy (ACE_Lock *);
-
- /// Get the current reference count.
- int reference_count (void) const;
-
- /// Dump the state of an object.
- void dump (void) const;
-
- /// Declare the dynamic allocation hooks.
- ACE_ALLOC_HOOK_DECLARE;
-
-protected:
- // = Internal initialization methods.
- /// Perform the actual initialization.
- 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,
- unsigned 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);
-
- /// Internal release implementation
- /// Returns 1 if the data block has to be destroyed.
- int release_i (ACE_Lock *lock);
-
- /// Perform the actual initialization.
- 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,
- unsigned 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);
-
- /// Pointer to beginning of next read.
- size_t rd_ptr_;
-
- /// Pointer to beginning of next write.
- size_t wr_ptr_;
-
- /// Priority of message.
- unsigned long priority_;
-
-#if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
- /// Execution time associated with the message.
- ACE_Time_Value execution_time_;
-
- /// Absolute deadline time for message.
- ACE_Time_Value deadline_time_;
-#endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
-
- // = Links to other ACE_Message_Block *s.
- /// Pointer to next message block in the chain.
- ACE_Message_Block *cont_;
-
- /// Pointer to next message in the list.
- ACE_Message_Block *next_;
-
- /// Pointer to previous message in the list.
- ACE_Message_Block *prev_;
-
- /// Misc flags (e.g., DONT_DELETE and USER_FLAGS).
- ACE_Message_Block::Message_Flags flags_;
-
- /// Pointer to the reference counted data structure that contains the
- /// actual memory buffer.
- ACE_Data_Block *data_block_;
-
- /// The allocator used to destroy ourselves when release is called
- /// and create new message blocks on duplicate.
- ACE_Allocator *message_block_allocator_;
-
-private:
- // = Disallow these operations for now (use <clone> instead).
- ACE_Message_Block &operator= (const ACE_Message_Block &);
- ACE_Message_Block (const ACE_Message_Block &);
-};
-
-/**
- * @class ACE_Data_Block
- *
- * @brief Stores the data payload that is accessed via one or more
- * <ACE_Message_Block>s.
- *
- * This data structure is reference counted to maximize
- * sharing. It also contains the <locking_strategy_> (which
- * protects the reference count from race conditions in
- * concurrent programs) and the <allocation_strategy_> (which
- * determines what memory pool is used to allocate the memory).
- */
-class ACE_Export ACE_Data_Block
-{
-public:
- // = Initialization and termination methods.
- /// Default "do-nothing" constructor.
- ACE_Data_Block (void);
-
- /// Initialize.
- ACE_Data_Block (size_t size,
- ACE_Message_Block::ACE_Message_Type msg_type,
- const char *msg_data,
- ACE_Allocator *allocator_strategy,
- ACE_Lock *locking_strategy,
- ACE_Message_Block::Message_Flags flags,
- ACE_Allocator *data_block_allocator);
-
- /// Delete all the resources held in the message.
- virtual ~ACE_Data_Block (void);
-
- /// Get type of the message.
- ACE_Message_Block::ACE_Message_Type msg_type (void) const;
-
- /// Set type of the message.
- void msg_type (ACE_Message_Block::ACE_Message_Type type);
-
- /// Get message data pointer
- char *base (void) const;
-
- /// Set message data pointer (doesn't reallocate).
- void base (char *data,
- size_t size,
- ACE_Message_Block::Message_Flags mflags = ACE_Message_Block::DONT_DELETE);
-
- /// Return a pointer to 1 past the end of the allocated data in a message.
- char *end (void) const;
-
- /**
- * Return a pointer to 1 past the end of the allotted data in a message.
- * The allotted data may be less than allocated data if <size()> is passed
- * an argument less than <capacity()>.
- */
- char *mark (void) const;
-
- // = Message size is the total amount of space alloted.
-
- /// Get the total amount of allotted space in the message. The amount of
- /// allotted space may be less than allocated space.
- size_t size (void) const;
-
- /// Set the total amount of space in the message. Returns 0 if
- /// successful, else -1.
- int size (size_t length);
-
- /// Get the total amount of allocated space.
- size_t capacity (void) const;
-
- /**
- * Return an exact "deep copy" of the message, i.e., create fresh
- * new copies of all the Data_Blocks and continuations.
- * Notice that Data_Blocks can act as "Prototypes", i.e. derived
- * classes can override this method and create instances of
- * themselves.
- */
- virtual ACE_Data_Block *clone (ACE_Message_Block::Message_Flags mask = 0) const;
-
- /**
- * As clone above, but it does not copy the contents of the buffer,
- * i.e., create a new Data_Block of the same dynamic type, with the
- * same allocator, locking_strategy, and with the same amount of
- * storage available but the buffer is unitialized.
- */
- virtual ACE_Data_Block *clone_nocopy (ACE_Message_Block::Message_Flags mask = 0) const;
-
- /// Return a "shallow" copy that increments our reference count by 1.
- ACE_Data_Block *duplicate (void);
-
- /**
- * Decrease the shared reference count by 1. If the reference count
- * is > 0 then return this; else if reference count == 0 then delete
- * <this> and <mb> and return 0. Behavior is undefined if reference
- * count < 0.
- */
- ACE_Data_Block *release (ACE_Lock *lock = 0);
-
- // = Message flag accessors and mutators.
- /// Bitwise-or the <more_flags> into the existing message flags and
- /// return the new value.
- ACE_Message_Block::Message_Flags set_flags (ACE_Message_Block::Message_Flags more_flags);
-
- /// Clear the message flag bits specified in <less_flags> and return
- /// the new value.
- ACE_Message_Block::Message_Flags clr_flags (ACE_Message_Block::Message_Flags less_flags);
-
- /// Get the current message flags.
- ACE_Message_Block::Message_Flags flags (void) const;
-
- /// Obtain the allocator strategy.
- ACE_Allocator *allocator_strategy (void) const;
-
- // = The locking strategy prevents race conditions.
- /// Get the locking strategy.
- ACE_Lock *locking_strategy (void);
-
- /// Set a new locking strategy and return the hold one.
- ACE_Lock *locking_strategy (ACE_Lock *);
-
- /// Dump the state of an object.
- void dump (void) const;
-
- /// Get the current reference count.
- int reference_count (void) const;
-
- /// Get the allocator used to create this object
- ACE_Allocator *data_block_allocator (void) const;
-
-protected:
- /// Internal release implementation
- ACE_Data_Block *release_i (void);
-
- /**
- * Decrease the reference count, but don't delete the object.
- * Returns 0 if the object should be removed.
- * If <lock> is equal to the locking strategy then we assume that
- * the lock is beign held by the current thread; this is used to
- * release all the data blocks in a chain while holding a single
- * lock.
- */
- friend class ACE_Message_Block;
- ACE_Data_Block *release_no_delete (ACE_Lock *lock);
-
- /// Type of message.
- ACE_Message_Block::ACE_Message_Type type_;
-
- /// Current size of message block.
- size_t cur_size_;
-
- /// Total size of buffer.
- size_t max_size_;
-
- /// Misc flags (e.g., DONT_DELETE and USER_FLAGS).
- ACE_Message_Block::Message_Flags flags_;
-
- /// Pointer To beginning of message payload.
- char *base_;
-
- // = Strategies.
- /**
- * Pointer to the allocator defined for this <ACE_Data_Block>. Note
- * that this pointer is shared by all owners of this
- * <ACE_Data_Block>.
- */
- ACE_Allocator *allocator_strategy_;
-
- /**
- * Pointer to the locking strategy defined for this
- * <ACE_Data_Block>. This is used to protect regions of code that
- * access shared <ACE_Data_Block> state. Note that this lock is
- * shared by all owners of the <ACE_Data_Block>'s data.
- */
- ACE_Lock *locking_strategy_;
-
- /**
- * Reference count for this <ACE_Data_Block>, which is used to avoid
- * deep copies (i.e., <clone>). Note that this pointer value is
- * shared by all owners of the <Data_Block>'s data, i.e., all the
- * <ACE_Message_Block>s.
- */
- int reference_count_;
-
- /// The allocator use to destroy ourselves.
- ACE_Allocator *data_block_allocator_;
-
-private:
- // = Disallow these operations.
- ACE_Data_Block &operator= (const ACE_Data_Block &);
- ACE_Data_Block (const ACE_Data_Block &);
-};
-
-/**
- * @class ACE_Dynamic_Message_Strategy
- *
- * @brief An abstract base class which provides dynamic priority
- * evaluation methods for use by the <ACE_Dynamic_Message_Queue>
- * class or any other class which needs to manage the priorities
- * of a collection of <ACE_Message_Block>s dynamically.
- *
- * Methods for deadline and laxity based priority evaluation are
- * provided. These methods assume a specific partitioning of
- * the message priority number into a higher order dynamic bit
- * field and a lower order static priority bit field. The
- * default partitioning assumes an unsigned dynamic message
- * priority field of 22 bits and an unsigned static message
- * priority field of 10 bits. This corresponds to the initial
- * values of the static class members. To provide a different
- * partitioning, assign a different set of values to the static
- * class memebers before using the static member functions.
- */
-class ACE_Export ACE_Dynamic_Message_Strategy
-{
-public:
-
- // = Message priority status
-
- // Values are defined as bit flags so that status combinations may
- // be specified easily.
-
- enum Priority_Status
- {
- /// Message can still make its deadline
- PENDING = 0x01,
- /// Message cannot make its deadline
- LATE = 0x02,
- /// Message is so late its priority is undefined
- BEYOND_LATE = 0x04,
- /// Mask to match any priority status
- ANY_STATUS = 0x07
- };
-
- /// Constructor.
- ACE_Dynamic_Message_Strategy (unsigned long static_bit_field_mask,
- unsigned long static_bit_field_shift,
- unsigned long dynamic_priority_max,
- unsigned long dynamic_priority_offset);
-
- /// Virtual destructor.
- virtual ~ACE_Dynamic_Message_Strategy (void);
-
- /// Updates the message's priority and returns its priority status.
- Priority_Status priority_status (ACE_Message_Block &mb,
- const ACE_Time_Value &tv);
-
- /// Get static bit field mask.
- unsigned long static_bit_field_mask (void) const;
-
- /// Set static bit field mask.
- void static_bit_field_mask (unsigned long);
-
- /// Get left shift value to make room for static bit field.
- unsigned long static_bit_field_shift (void) const;
-
- /// Set left shift value to make room for static bit field.
- void static_bit_field_shift (unsigned long);
-
- /// Get maximum supported priority value.
- unsigned long dynamic_priority_max (void) const;
-
- /// Set maximum supported priority value.
- void dynamic_priority_max (unsigned long);
-
- /// Get offset to boundary between signed range and unsigned range.
- unsigned long dynamic_priority_offset (void) const;
-
- /// Set offset to boundary between signed range and unsigned range.
- void dynamic_priority_offset (unsigned long);
-
- /// Dump the state of the strategy.
- virtual void dump (void) const;
-
-protected:
- /// Hook method for dynamic priority conversion.
- virtual void convert_priority (ACE_Time_Value &priority,
- const ACE_Message_Block &mb) = 0;
-
- /// This is a bit mask with all ones in the static bit field.
- unsigned long static_bit_field_mask_;
-
- /**
- * This is a left shift value to make room for static bit field:
- * this value should be the logarithm base 2 of
- * (static_bit_field_mask_ + 1).
- */
- unsigned long static_bit_field_shift_;
-
- /// Maximum supported priority value.
- unsigned long dynamic_priority_max_;
-
- /// Offset to boundary between signed range and unsigned range.
- unsigned long dynamic_priority_offset_;
-
- /// Maximum late time value that can be represented.
- ACE_Time_Value max_late_;
-
- /// Minimum pending time value that can be represented.
- ACE_Time_Value min_pending_;
-
- /// Time value by which to shift pending priority.
- ACE_Time_Value pending_shift_;
-};
-
-/**
- * @class ACE_Deadline_Message_Strategy
- *
- * @brief Deadline based message priority strategy.
- *
- * Assigns dynamic message priority according to time to deadline. The
- * message priority is divided into high and low order bit fields. The
- * high order bit field is used for dynamic message priority, which is
- * updated whenever the convert_priority() method is called. The
- * low order bit field is used for static message priority and is left
- * unchanged. The partitioning of the priority value into high and low
- * order bit fields is done according to the arguments passed to the
- * strategy object's constructor.
- */
-class ACE_Export ACE_Deadline_Message_Strategy : public ACE_Dynamic_Message_Strategy
-{
-public:
- /// Ctor, with all arguments defaulted.
- ACE_Deadline_Message_Strategy (unsigned long static_bit_field_mask = 0x3FFUL, // 2^(10) - 1
- unsigned long static_bit_field_shift = 10, // 10 low order bits
- unsigned long dynamic_priority_max = 0x3FFFFFUL, // 2^(22)-1
- unsigned long dynamic_priority_offset = 0x200000UL); // 2^(22-1)
-
- /// Virtual dtor.
- virtual ~ACE_Deadline_Message_Strategy (void);
-
- /// Dynamic priority conversion function based on time to deadline.
- virtual void convert_priority (ACE_Time_Value &priority,
- const ACE_Message_Block &mb);
-
- /// Dump the state of the strategy.
- virtual void dump (void) const;
-};
-
-/**
- * @class ACE_Laxity_Message_Strategy
- *
- * @brief Laxity based message priority strategy.
- *
- * Assigns dynamic message priority according to laxity (time to
- * deadline minus worst case execution time). The message priority is
- * divided into high and low order bit fields. The high order
- * bit field is used for dynamic message priority, which is
- * updated whenever the convert_priority() method is called. The
- * low order bit field is used for static message priority and is left
- * unchanged. The partitioning of the priority value into high and low
- * order bit fields is done according to the arguments passed to the
- * strategy object's constructor.
- */
-class ACE_Export ACE_Laxity_Message_Strategy : public ACE_Dynamic_Message_Strategy
-{
-public:
- /// Ctor, with all arguments defaulted.
- ACE_Laxity_Message_Strategy (unsigned long static_bit_field_mask = 0x3FFUL, // 2^(10) - 1
- unsigned long static_bit_field_shift = 10, // 10 low order bits
- unsigned long dynamic_priority_max = 0x3FFFFFUL, // 2^(22)-1
- unsigned long dynamic_priority_offset = 0x200000UL); // 2^(22-1)
-
- /// virtual dtor.
- virtual ~ACE_Laxity_Message_Strategy (void);
-
- /// Dynamic priority conversion function based on laxity.
- virtual void convert_priority (ACE_Time_Value &priority,
- const ACE_Message_Block &mb);
-
- /// Dump the state of the strategy.
- virtual void dump (void) const;
-};
-
-#if defined (__ACE_INLINE__)
-#include "ace/Message_Block.i"
-#endif /* __ACE_INLINE__ */
-
-#include "ace/Message_Block_T.h"
-
-#include /**/ "ace/post.h"
-
-#endif /* ACE_MESSAGE_BLOCK_H */