Removed ACE_HAS_BSTRING, not used
[ACE_TAO.git] / ACE / ace / Message_Block.h
blob1ad30dd03386e0b75888150fb98cb825f26e4605
1 // -*- C++ -*-
3 //==========================================================================
4 /**
5 * @file Message_Block.h
7 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
8 */
9 //==========================================================================
11 #ifndef ACE_MESSAGE_BLOCK_H
12 #define ACE_MESSAGE_BLOCK_H
14 #include /**/ "ace/pre.h"
16 #include /**/ "ace/config-lite.h"
17 #include /**/ "ace/ACE_export.h"
19 #if !defined (ACE_LACKS_PRAGMA_ONCE)
20 # pragma once
21 #endif /* ACE_LACKS_PRAGMA_ONCE */
23 #include "ace/Default_Constants.h"
24 #include "ace/Global_Macros.h"
25 #include "ace/Time_Value.h"
27 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
29 // Forward declaration.
30 class ACE_Allocator;
31 class ACE_Data_Block;
32 class ACE_Lock;
35 /**
36 * @class ACE_Message_Block
38 * @brief Stores messages for use throughout ACE (particularly
39 * in an ACE_Message_Queue).
41 * An ACE_Message_Block is modeled after the message data
42 * structures used in System V STREAMS. Its purpose is to
43 * enable efficient manipulation of arbitrarily large messages
44 * without incurring much memory copying overhead. Here are the
45 * main characteristics of an ACE_Message_Block:
46 * - Contains a pointer to a reference-counted
47 * ACE_Data_Block, which in turn points to the actual data
48 * buffer. This allows very flexible and efficient sharing of
49 * data by multiple ACE_Message_Block objects.
50 * - One or more ACE_Message_Blocks can be linked to form a
51 * ``fragment chain.''
52 * - ACE_Message_Blocks can be linked together in a doubly linked fashion
53 * to form a queue of messages (this is how ACE_Message_Queue works).
55 * @see C++NPv1, section 4.2; APG, section 12.3.2.
57 class ACE_Export ACE_Message_Block
59 public:
60 friend class ACE_Data_Block;
62 enum
64 // = Data and proto
65 /// Undifferentiated data message
66 MB_DATA = 0x01,
67 /// Undifferentiated protocol control
68 MB_PROTO = 0x02,
70 // = Control messages
71 /// Line break (regular and priority)
72 MB_BREAK = 0x03,
73 /// Pass file pointer
74 MB_PASSFP = 0x04,
75 /// Post an event to an event queue
76 MB_EVENT = 0x05,
77 /// Generate process signal
78 MB_SIG = 0x06,
79 /// ioctl; set/get params
80 MB_IOCTL = 0x07,
81 /// Set various stream head options
82 MB_SETOPTS = 0x08,
84 // = Control messages
85 /// Acknowledge ioctl (high priority; go to head of queue)
86 MB_IOCACK = 0x81,
87 /// Negative ioctl acknowledge
88 MB_IOCNAK = 0x82,
89 /// Priority proto message
90 MB_PCPROTO = 0x83,
91 /// Generate process signal
92 MB_PCSIG = 0x84,
93 /// Generate read notification
94 MB_READ = 0x85,
95 /// Flush your queues
96 MB_FLUSH = 0x86,
97 /// Stop transmission immediately
98 MB_STOP = 0x87,
99 /// Restart transmission after stop
100 MB_START = 0x88,
101 /// Line disconnect
102 MB_HANGUP = 0x89,
103 /// Fatal error used to set u.u_error
104 MB_ERROR = 0x8a,
105 /// Post an event to an event queue
106 MB_PCEVENT = 0x8b,
108 // = Message class masks
109 /// Normal priority message mask
110 MB_NORMAL = 0x00,
111 /// High priority control message mask
112 MB_PRIORITY = 0x80,
113 /// User-defined message mask
114 MB_USER = 0x200
117 typedef int ACE_Message_Type;
118 typedef unsigned long Message_Flags;
120 enum
122 /// Don't delete the data on exit since we don't own it.
123 DONT_DELETE = 01,
124 /// user defined flags start here
125 USER_FLAGS = 0x1000
128 /// Create an empty message.
129 ACE_Message_Block (ACE_Allocator *message_block_allocator = 0);
132 * Create an ACE_Message_Block that owns the specified ACE_Data_Block
133 * without copying it. If the @a flags is set to @c DONT_DELETE we
134 * don't delete the ACE_Data_Block. It is left to the client's
135 * responsibility to take care of the memory allocated for the
136 * data_block
138 ACE_Message_Block (ACE_Data_Block *data_block,
139 Message_Flags flags = 0,
140 ACE_Allocator *message_block_allocator = 0);
143 * Create an ACE_Message_Block that refers to @a data without
144 * copying it. The @a data memory will not be freed when this block is
145 * destroyed; memory management of @a data is left to the caller.
146 * Note that the @c size of the new ACE_Message_Block will be @a size, but
147 * the @c length will be 0 until the write pointer is changed.
149 ACE_Message_Block (const char *data,
150 size_t size = 0,
151 unsigned long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY);
154 * Create an initialized message of type @a type containing @a size
155 * bytes. The @a cont argument initializes the continuation field in
156 * the ACE_Message_Block. If @a data == 0 then this block allocates and
157 * owns the block's memory, using @a allocator to get the data if it's
158 * non-0. If @a data != 0 then this block refers to that memory until
159 * this this block ceases to exist; this object will not free @a data on
160 * destruction. If @a locking_strategy is non-0 then this is used
161 * to protect regions of code that access shared state (e.g.,
162 * reference counting) from race conditions. Note that the @c size
163 * of the ACE_Message_Block will be @a size, but the @c length will be 0
164 * until the write pointer is set. The @a data_block_allocator is used to
165 * allocate the data blocks while the @a allocator_strategy is used
166 * to allocate the buffers contained by those. The
167 * @a message_block_allocator is used to allocate new ACE_Message_Block
168 * objects when the duplicate() method is called. If a
169 * @a message_block_allocator is given, this ACE_Message_Block and
170 * future ACE_Message_Block objects created by duplicate() will be
171 * freed using this allocator when they are released.
172 * @note If you use this allocator, the ACE_Message_Block you created
173 * should have been created using this allocator because it will be
174 * released to the same allocator.
176 ACE_Message_Block (size_t size,
177 ACE_Message_Type type = MB_DATA,
178 ACE_Message_Block *cont = 0,
179 const char *data = 0,
180 ACE_Allocator *allocator_strategy = 0,
181 ACE_Lock *locking_strategy = 0,
182 unsigned long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY,
183 const ACE_Time_Value &execution_time = ACE_Time_Value::zero,
184 const ACE_Time_Value &deadline_time = ACE_Time_Value::max_time,
185 ACE_Allocator *data_block_allocator = 0,
186 ACE_Allocator *message_block_allocator = 0);
189 * A copy constructor. This constructor is a bit different. If the
190 * incoming Message Block has a data block from the stack this
191 * constructor does a deep copy ie. allocates a new data block on
192 * the heap and does a copy of the data from the incoming message
193 * block. As a final note, the alignment information is used to
194 * align the data block if it is created afresh. If the incoming
195 * @a mb has a data block has a data block allocated from the heap,
196 * then this constructor just duplicates (ie. a shallow copy) the
197 * data block of the incoming @a mb.
199 ACE_Message_Block (const ACE_Message_Block &mb,
200 size_t align);
203 * Create a Message Block that assumes it has ownership of @a data,
204 * but in reality it doesn't (i.e., cannot delete it since it didn't
205 * malloc it!). Note that the @c size of the Message_Block will
206 * be @a size, but the @a length will be 0 until <wr_ptr> is set.
208 int init (const char *data,
209 size_t size = 0);
212 * Create an initialized message of type @a type containing @a size
213 * bytes. The @a cont argument initializes the continuation field in
214 * the Message_Block. If @a data == 0 then we create and own the
215 * @a data, using @a allocator_strategy to get the data if it's non-0. If
216 * @a data != 0 we assume that we have ownership of the @a data till
217 * this object ceases to exist (and don't delete it during
218 * destruction). If @a locking_strategy is non-0 then this is used
219 * to protect regions of code that access shared state (e.g.,
220 * reference counting) from race conditions. Note that the @a size
221 * of the Message_Block will be @a size, but the @a length will be 0
222 * until <wr_ptr> is set. The @a data_block_allocator is use to
223 * allocate the data blocks while the @a allocator_strategy is used
224 * to allocate the buffers contained by those.
226 int init (size_t size,
227 ACE_Message_Type type = MB_DATA,
228 ACE_Message_Block *cont = 0,
229 const char *data = 0,
230 ACE_Allocator *allocator_strategy = 0,
231 ACE_Lock *locking_strategy = 0,
232 unsigned long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY,
233 const ACE_Time_Value &execution_time = ACE_Time_Value::zero,
234 const ACE_Time_Value &deadline_time = ACE_Time_Value::max_time,
235 ACE_Allocator *data_block_allocator = 0,
236 ACE_Allocator *message_block_allocator = 0);
239 * Delete all the resources held in the message.
241 * @note Note that release() is designed to release the continuation
242 * chain; the destructor is not. See release() for details.
244 virtual ~ACE_Message_Block (void);
246 // = Message Type accessors and mutators.
248 /// Get type of the message.
249 ACE_Message_Type msg_type (void) const;
251 /// Set type of the message.
252 void msg_type (ACE_Message_Type type);
254 /// Find out what type of message this is.
255 int is_data_msg (void) const;
257 /// Find out what class of message this is (there are two classes,
258 /// @c normal messages and @c high-priority messages).
259 ACE_Message_Type msg_class (void) const;
261 // = Message flag accessors and mutators.
262 /// Bitwise-or the @a more_flags into the existing message flags and
263 /// return the new value.
264 Message_Flags set_flags (Message_Flags more_flags);
266 /// Clear the message flag bits specified in @a less_flags and return
267 /// the new value.
268 Message_Flags clr_flags (Message_Flags less_flags);
270 /// Get the current message flags.
271 Message_Flags flags (void) const;
273 // = Data Block flag accessors and mutators.
274 /// Bitwise-or the @a more_flags into the existing message flags and
275 /// return the new value.
276 /** @todo I think the following set of methods could not be used at
277 * all. May be they are useless. Let us have it so that we don't
278 * mess up memory management of the Message_Block. Somebody correct
279 * me if I am totally totally wrong..
281 Message_Flags set_self_flags (ACE_Message_Block::Message_Flags more_flags);
283 /// Clear the message flag bits specified in @a less_flags and return
284 /// the new value.
285 Message_Flags clr_self_flags (ACE_Message_Block::Message_Flags less_flags);
287 /// Get the current message flags.
288 Message_Flags self_flags (void) const;
290 /// Get priority of the message.
291 unsigned long msg_priority (void) const;
293 /// Set priority of the message.
294 void msg_priority (unsigned long priority);
296 /// Get execution time associated with the message.
297 const ACE_Time_Value &msg_execution_time (void) const;
299 /// Set execution time associated with the message.
300 void msg_execution_time (const ACE_Time_Value &et);
302 /// Get absolute time of deadline associated with the message.
303 const ACE_Time_Value &msg_deadline_time (void) const;
305 /// Set absolute time of deadline associated with the message.
306 void msg_deadline_time (const ACE_Time_Value &dt);
308 // = Deep copy and shallow copy methods.
310 /// Return an exact "deep copy" of the message, i.e., create fresh
311 /// new copies of all the Data_Blocks and continuations.
312 virtual ACE_Message_Block *clone (Message_Flags mask = 0) const;
314 /// Return a "shallow" copy that increments our reference count by 1.
315 virtual ACE_Message_Block *duplicate (void) const;
318 * Return a "shallow" copy that increments our reference count by 1.
319 * This is similar to CORBA's _duplicate() method, which is useful
320 * if you want to eliminate lots of checks for NULL @a mb pointers
321 * before calling _duplicate() on them.
323 static ACE_Message_Block *duplicate (const ACE_Message_Block *mb);
326 * Decrease the shared ACE_Data_Block's reference count by 1. If the
327 * ACE_Data_Block's reference count goes to 0, it is deleted.
328 * In all cases, this ACE_Message_Block is deleted - it must have come
329 * from the heap, or there will be trouble.
331 * release() is designed to release the continuation chain; the
332 * destructor is not. If we make the destructor release the
333 * continuation chain by calling release() or delete on the message
334 * blocks in the continuation chain, the following code will not
335 * work since the message block in the continuation chain is not off
336 * the heap:
338 * ACE_Message_Block mb1 (1024);
339 * ACE_Message_Block mb2 (1024);
341 * mb1.cont (&mb2);
343 * And hence, call release() on a dynamically allocated message
344 * block. This will release all the message blocks in the
345 * continuation chain. If you call delete or let the message block
346 * fall off the stack, cleanup of the message blocks in the
347 * continuation chain becomes the responsibility of the user.
349 * @retval 0, always, and the object this method was invoked on is no
350 * longer valid.
352 virtual ACE_Message_Block *release (void);
355 * This behaves like the non-static method release(), except that it
356 * checks if @a mb is 0. This is similar to CORBA::release(), which
357 * is useful if you want to eliminate lots of checks for NULL
358 * pointers before calling release() on them. Returns @a mb.
360 static ACE_Message_Block *release (ACE_Message_Block *mb);
362 // = Operations on Message data
365 * Copies data into this ACE_Message_Block. Data is copied into the
366 * block starting at the current write pointer.
368 * @param buf Pointer to the buffer to copy from.
369 * @param n The number of bytes to copy.
371 * @retval 0 on success; the write pointer is advanced by @arg n.
372 * @retval -1 if the amount of free space following the write pointer
373 * in the block is less than @arg n. Free space can be checked
374 * by calling space().
376 int copy (const char *buf, size_t n);
379 * Copies a 0-terminated character string into this ACE_Message_Block.
380 * The string is copied into the block starting at the current write
381 * pointer. The 0-terminator is included in the copied data.
383 * @param buf Pointer to the character string to copy from.
385 * @retval 0 on success; the write pointer is advanced by the string's
386 * length, including the 0 terminator.
387 * @retval -1 if the amount of free space following the write pointer
388 * in the block is less than required to hold the entire string.
389 * Free space can be checked by calling space().
391 int copy (const char *buf);
393 /// Normalizes data in the top-level Message_Block to align with the base,
394 /// i.e., it "shifts" the data pointed to by <rd_ptr> down to the <base> and
395 /// then readjusts <rd_ptr> to point to <base> and <wr_ptr> to point
396 /// to <base> + the length of the moved data. Returns -1 and does
397 /// nothing if the <rd_ptr> is > <wr_ptr>, else 0 on success.
398 int crunch (void);
400 /// Resets the Message Block data to contain nothing, i.e., sets the
401 /// read and write pointers to align with the base.
402 void reset (void);
404 /// Access all the allocators in the message block.
405 /// @todo Not sure whether we would need finer control while
406 /// trying to access allocators ie. a method for every allocator.
408 * This method returns the allocators only from the first message
409 * block in the chain.
411 * @param allocator_strategy Strategy used to allocate the
412 * underlying buffer
414 * @param data_block_allocator Strategy used to allocate the
415 * underlying data block
417 * @param message_block_allocator Strategy used to allocate the
418 * message block
420 void access_allocators (ACE_Allocator *&allocator_strategy,
421 ACE_Allocator *&data_block_allocator,
422 ACE_Allocator *&message_block_allocator);
424 /// Reset all the allocators in the message block.
425 /// @todo Not sure whether we would need finer control while
426 /// trying to reset allocators ie. a method for every allocator.
428 * This method resets the allocators in all the message blocks in
429 * the chain.
431 void reset_allocators (ACE_Allocator *allocator_strategy = 0,
432 ACE_Allocator *data_block_allocator = 0,
433 ACE_Allocator *message_block_allocator = 0);
435 /// Get message data.
436 char *base (void) const;
438 /// Set message data (doesn't reallocate).
439 void base (char *data,
440 size_t size,
441 Message_Flags = DONT_DELETE);
443 /// Return a pointer to 1 past the end of the allocated data in a message.
444 char *end (void) const;
447 * Return a pointer to 1 past the end of the allotted data in a message.
448 * Allotted data may be less than allocated data if a value smaller than
449 * capacity() to is passed to size().
451 char *mark (void) const;
453 /// Get the read pointer.
454 char *rd_ptr (void) const;
456 /// Set the read pointer to @a ptr.
457 void rd_ptr (char *ptr);
459 /// Set the read pointer ahead @a n bytes.
460 void rd_ptr (size_t n);
462 /// Get the write pointer.
463 char *wr_ptr (void) const;
465 /// Set the write pointer to @a ptr.
466 void wr_ptr (char *ptr);
468 /// Set the write pointer ahead @a n bytes. This is used to compute
469 /// the <length> of a message.
470 void wr_ptr (size_t n);
472 /** @name Message length and size operations
474 * Message length is (wr_ptr - rd_ptr).
476 * Message size is capacity of the message, including data outside
477 * the [rd_ptr,wr_ptr] range.
479 //@{
480 /// Get the length of the message
481 size_t length (void) const;
483 /// Set the length of the message
484 void length (size_t n);
486 /// Get the length of the Message_Blocks, including chained
487 /// Message_Blocks.
488 size_t total_length (void) const;
490 /// Get the total number of bytes in all Message_Blocks, including
491 /// chained Message_Blocks.
492 size_t total_size (void) const;
494 /// Get the total number of bytes and total length in all
495 /// Message_Blocks, including chained Message_Blocks.
496 void total_size_and_length (size_t &mb_size,
497 size_t &mb_length) const;
499 /// Get the number of bytes in the top-level Message_Block (i.e.,
500 /// does not consider the bytes in chained Message_Blocks).
501 size_t size (void) const;
504 * Set the number of bytes in the top-level Message_Block,
505 * reallocating space if necessary. However, the @c rd_ptr_ and
506 * @c wr_ptr_ remain at the original offsets into the buffer, even if
507 * it is reallocated. Returns 0 if successful, else -1.
509 int size (size_t length);
511 /// Get the number of allocated bytes in all Message_Block, including
512 /// chained Message_Blocks.
513 size_t total_capacity (void) const;
515 /// Get the number of allocated bytes in the top-level Message_Block.
516 size_t capacity (void) const;
518 /// Get the number of bytes available after the <wr_ptr_> in the
519 /// top-level Message_Block.
520 size_t space (void) const;
521 //@}
523 // = ACE_Data_Block methods.
526 * Get a pointer to the data block. Note that the ACE_Message_Block
527 * still references the block; this call does not change the reference
528 * count.
530 ACE_Data_Block *data_block (void) const;
533 * Set a new data block pointer. The original ACE_Data_Block is released
534 * as a result of this call. If you need to keep the original block, call
535 * <replace_data_block> instead. Upon return, this ACE_Message_Block
536 * holds a pointer to the new ACE_Data_Block, taking over the reference
537 * you held on it prior to the call.
539 void data_block (ACE_Data_Block *);
541 /// Set a new data block pointer. A pointer to the original ACE_Data_Block
542 /// is returned, and not released (as it is with <data_block>).
543 ACE_Data_Block *replace_data_block (ACE_Data_Block*);
545 // = The continuation field chains together composite messages.
546 /// Get the continuation field.
547 ACE_Message_Block *cont (void) const;
549 /// Set the continuation field.
550 void cont (ACE_Message_Block *);
552 // = Pointer to the Message_Block directly ahead in the ACE_Message_Queue.
553 /// Get link to next message.
554 ACE_Message_Block *next (void) const;
556 /// Set link to next message.
557 void next (ACE_Message_Block *);
559 // = Pointer to the Message_Block directly behind in the ACE_Message_Queue.
560 /// Get link to prev message.
561 ACE_Message_Block *prev (void) const;
563 /// Set link to prev message.
564 void prev (ACE_Message_Block *);
566 // = The locking strategy prevents race conditions.
567 /// Get the locking strategy.
568 ACE_Lock *locking_strategy (void);
570 /// Set a new locking strategy and return the hold one.
571 ACE_Lock *locking_strategy (ACE_Lock *);
573 /// Get the current reference count.
574 int reference_count (void) const;
576 /// Dump the state of an object.
577 void dump (void) const;
579 /// Declare the dynamic allocation hooks.
580 ACE_ALLOC_HOOK_DECLARE;
582 protected:
583 // = Internal initialization methods.
584 /// Perform the actual initialization.
585 ACE_Message_Block (size_t size,
586 ACE_Message_Type type,
587 ACE_Message_Block *cont,
588 const char *data,
589 ACE_Allocator *allocator_strategy,
590 ACE_Lock *locking_strategy,
591 Message_Flags flags,
592 unsigned long priority,
593 const ACE_Time_Value &execution_time,
594 const ACE_Time_Value &deadline_time,
595 ACE_Data_Block *db,
596 ACE_Allocator *data_block_allocator,
597 ACE_Allocator *message_block_allocator);
599 /// Internal release implementation
600 /// Returns 1 if the data block has to be destroyed.
601 int release_i (ACE_Lock *lock);
603 /// Perform the actual initialization.
604 int init_i (size_t size,
605 ACE_Message_Type type,
606 ACE_Message_Block *cont,
607 const char *data,
608 ACE_Allocator *allocator_strategy,
609 ACE_Lock *locking_strategy,
610 Message_Flags flags,
611 unsigned long priority,
612 const ACE_Time_Value &execution_time,
613 const ACE_Time_Value &deadline_time,
614 ACE_Data_Block *db,
615 ACE_Allocator *data_block_allocator,
616 ACE_Allocator *message_block_allocator);
618 /// Pointer to beginning of next read.
619 size_t rd_ptr_;
621 /// Pointer to beginning of next write.
622 size_t wr_ptr_;
624 /// Priority of message.
625 unsigned long priority_;
627 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
628 /// Execution time associated with the message.
629 ACE_Time_Value execution_time_;
631 /// Absolute deadline time for message.
632 ACE_Time_Value deadline_time_;
633 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
635 // = Links to other ACE_Message_Block *s.
636 /// Pointer to next message block in the chain.
637 ACE_Message_Block *cont_;
639 /// Pointer to next message in the list.
640 ACE_Message_Block *next_;
642 /// Pointer to previous message in the list.
643 ACE_Message_Block *prev_;
645 /// Misc flags (e.g., DONT_DELETE and USER_FLAGS).
646 ACE_Message_Block::Message_Flags flags_;
648 /// Pointer to the reference counted data structure that contains the
649 /// actual memory buffer.
650 ACE_Data_Block *data_block_;
652 /// The allocator used to destroy ourselves when release is called
653 /// and create new message blocks on duplicate.
654 ACE_Allocator *message_block_allocator_;
656 private:
657 // = Disallow these operations for now (use <clone> instead).
658 ACE_Message_Block &operator= (const ACE_Message_Block &);
659 ACE_Message_Block (const ACE_Message_Block &);
663 * @class ACE_Data_Block
665 * @brief Stores the data payload that is accessed via one or more
666 * ACE_Message_Block's.
668 * This data structure is reference counted to maximize
669 * sharing. It also contains the <locking_strategy_> (which
670 * protects the reference count from race conditions in
671 * concurrent programs) and the <allocation_strategy_> (which
672 * determines what memory pool is used to allocate the memory).
674 class ACE_Export ACE_Data_Block
676 public:
677 /// Default "do-nothing" constructor.
678 ACE_Data_Block (void);
680 /// Initialize.
681 ACE_Data_Block (size_t size,
682 ACE_Message_Block::ACE_Message_Type msg_type,
683 const char *msg_data,
684 ACE_Allocator *allocator_strategy,
685 ACE_Lock *locking_strategy,
686 ACE_Message_Block::Message_Flags flags,
687 ACE_Allocator *data_block_allocator);
689 /// Delete all the resources held in the message.
690 virtual ~ACE_Data_Block (void);
692 /// Get type of the message.
693 ACE_Message_Block::ACE_Message_Type msg_type (void) const;
695 /// Set type of the message.
696 void msg_type (ACE_Message_Block::ACE_Message_Type type);
698 /// Get message data pointer
699 char *base (void) const;
701 /// Set message data pointer (doesn't reallocate).
702 void base (char *data,
703 size_t size,
704 ACE_Message_Block::Message_Flags mflags = ACE_Message_Block::DONT_DELETE);
706 /// Return a pointer to 1 past the end of the allocated data in a message.
707 char *end (void) const;
710 * Return a pointer to 1 past the end of the allotted data in a message.
711 * The allotted data may be less than allocated data if <size()> is passed
712 * an argument less than <capacity()>.
714 char *mark (void) const;
716 // = Message size is the total amount of space allocated.
718 /// Get the total amount of allotted space in the message. The amount of
719 /// allotted space may be less than allocated space.
720 size_t size (void) const;
722 /// Set the total amount of space in the message. Returns 0 if
723 /// successful, else -1.
724 int size (size_t length);
726 /// Get the total amount of allocated space.
727 size_t capacity (void) const;
730 * Return an exact "deep copy" of the message, i.e., create fresh
731 * new copies of all the Data_Blocks and continuations.
732 * Notice that Data_Blocks can act as "Prototypes", i.e. derived
733 * classes can override this method and create instances of
734 * themselves.
736 virtual ACE_Data_Block *clone (ACE_Message_Block::Message_Flags mask = 0) const;
739 * As clone above, but it does not copy the contents of the buffer,
740 * i.e., create a new Data_Block of the same dynamic type, with the
741 * same allocator, locking_strategy, and with the same amount of
742 * storage available (if @a max_size is zero) but the buffer is unitialized.
743 * If @a max_size is specified other than zero, it will be used when
744 * creating the new data block.
746 virtual ACE_Data_Block *clone_nocopy (ACE_Message_Block::Message_Flags mask = 0,
747 size_t max_size = 0) const;
749 /// Return a "shallow" copy that increments our reference count by 1.
750 ACE_Data_Block *duplicate (void);
753 * Decrease the shared reference count by 1. If the reference count
754 * is > 0 then return this; else if reference count == 0 then delete
755 * @c this and @a mb and return 0. Behavior is undefined if reference
756 * count < 0.
758 ACE_Data_Block *release (ACE_Lock *lock = 0);
760 // = Message flag accessors and mutators.
761 /// Bitwise-or the @a more_flags into the existing message flags and
762 /// return the new value.
763 ACE_Message_Block::Message_Flags set_flags (ACE_Message_Block::Message_Flags more_flags);
765 /// Clear the message flag bits specified in @a less_flags and return
766 /// the new value.
767 ACE_Message_Block::Message_Flags clr_flags (ACE_Message_Block::Message_Flags less_flags);
769 /// Get the current message flags.
770 ACE_Message_Block::Message_Flags flags (void) const;
772 /// Obtain the allocator strategy.
773 ACE_Allocator *allocator_strategy (void) const;
775 // = The locking strategy prevents race conditions.
776 /// Get the locking strategy.
777 ACE_Lock *locking_strategy (void);
779 /// Set a new locking strategy and return the hold one.
780 ACE_Lock *locking_strategy (ACE_Lock *);
782 /// Dump the state of an object.
783 void dump (void) const;
785 /// Get the current reference count.
786 int reference_count (void) const;
788 /// Get the allocator used to create this object
789 ACE_Allocator *data_block_allocator (void) const;
791 protected:
792 /// Internal release implementation
793 virtual ACE_Data_Block *release_i (void);
795 /// Internal get the current reference count.
796 int reference_count_i (void) const;
799 * Decrease the reference count, but don't delete the object.
800 * Returns 0 if the object should be removed.
801 * If @a lock is equal to the locking strategy then we assume that
802 * the lock is being held by the current thread; this is used to
803 * release all the data blocks in a chain while holding a single
804 * lock.
806 friend class ACE_Message_Block;
807 ACE_Data_Block *release_no_delete (ACE_Lock *lock);
809 /// Type of message.
810 ACE_Message_Block::ACE_Message_Type type_;
812 /// Current size of message block.
813 size_t cur_size_;
815 /// Total size of buffer.
816 size_t max_size_;
818 /// Misc flags (e.g., DONT_DELETE and USER_FLAGS).
819 ACE_Message_Block::Message_Flags flags_;
821 /// Pointer To beginning of message payload.
822 char *base_;
824 // = Strategies.
826 * Pointer to the allocator defined for this ACE_Data_Block. Note
827 * that this pointer is shared by all owners of this
828 * ACE_Data_Block.
830 ACE_Allocator *allocator_strategy_;
833 * Pointer to the locking strategy defined for this
834 * ACE_Data_Block. This is used to protect regions of code that
835 * access shared ACE_Data_Block state. Note that this lock is
836 * shared by all owners of the ACE_Data_Block's data.
838 ACE_Lock *locking_strategy_;
841 * Reference count for this ACE_Data_Block, which is used to avoid
842 * deep copies (i.e., clone()). Note that this pointer value is
843 * shared by all owners of the <Data_Block>'s data, i.e., all the
844 * ACE_Message_Blocks.
846 int reference_count_;
848 /// The allocator use to destroy ourselves.
849 ACE_Allocator *data_block_allocator_;
851 private:
852 // = Disallow these operations.
853 ACE_Data_Block &operator= (const ACE_Data_Block &);
854 ACE_Data_Block (const ACE_Data_Block &);
857 ACE_END_VERSIONED_NAMESPACE_DECL
859 #if defined (__ACE_INLINE__)
860 #include "ace/Message_Block.inl"
861 #endif /* __ACE_INLINE__ */
863 #include "ace/Message_Block_T.h"
865 #include /**/ "ace/post.h"
867 #endif /* ACE_MESSAGE_BLOCK_H */