3 //==========================================================================
5 * @file Message_Block.h
7 * $Id: Message_Block.h 80826 2008-03-04 14:51:23Z wotte $
9 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
11 //==========================================================================
13 #ifndef ACE_MESSAGE_BLOCK_H
14 #define ACE_MESSAGE_BLOCK_H
16 #include /**/ "ace/pre.h"
18 #include "ace/config-lite.h"
19 #include /**/ "ace/ACE_export.h"
21 #if !defined (ACE_LACKS_PRAGMA_ONCE)
23 #endif /* ACE_LACKS_PRAGMA_ONCE */
25 #include "ace/Default_Constants.h"
26 #include "ace/Global_Macros.h"
27 #include "ace/Time_Value.h"
29 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
31 // Forward declaration.
38 * @class ACE_Message_Block
40 * @brief Stores messages for use throughout ACE (particularly
41 * in an ACE_Message_Queue).
43 * An ACE_Message_Block is modeled after the message data
44 * structures used in System V STREAMS. Its purpose is to
45 * enable efficient manipulation of arbitrarily large messages
46 * without incurring much memory copying overhead. Here are the
47 * main characteristics of an ACE_Message_Block:
48 * - Contains a pointer to a reference-counted
49 * ACE_Data_Block, which in turn points to the actual data
50 * buffer. This allows very flexible and efficient sharing of
51 * data by multiple ACE_Message_Block objects.
52 * - One or more ACE_Message_Blocks can be linked to form a
54 * - ACE_Message_Blocks can be linked together in a doubly linked fashion
55 * to form a queue of messages (this is how ACE_Message_Queue works).
57 * @see C++NPv1, section 4.2; APG, section 12.3.2.
59 class ACE_Export ACE_Message_Block
62 friend class ACE_Data_Block
;
67 /// Undifferentiated data message
69 /// Undifferentiated protocol control
73 /// Line break (regular and priority)
77 /// Post an event to an event queue
79 /// Generate process signal
81 /// ioctl; set/get params
83 /// Set various stream head options
87 /// Acknowledge ioctl (high priority; go to head of queue)
89 /// Negative ioctl acknowledge
91 /// Priority proto message
93 /// Generate process signal
95 /// Generate read notification
99 /// Stop transmission immediately
101 /// Restart transmission after stop
105 /// Fatal error used to set u.u_error
107 /// Post an event to an event queue
110 // = Message class masks
111 /// Normal priority message mask
113 /// High priority control message mask
115 /// User-defined message mask
119 typedef int ACE_Message_Type
;
120 typedef unsigned long Message_Flags
;
124 /// Don't delete the data on exit since we don't own it.
126 /// user defined flags start here
130 // = Initialization and termination.
131 /// Create an empty message.
132 ACE_Message_Block (ACE_Allocator
*message_block_allocator
= 0);
135 * Create an ACE_Message_Block that owns the specified ACE_Data_Block
136 * without copying it. If the @a flags is set to @c DONT_DELETE we
137 * don't delete the ACE_Data_Block. It is left to the client's
138 * responsibility to take care of the memory allocated for the
141 ACE_Message_Block (ACE_Data_Block
*,
142 Message_Flags flags
= 0,
143 ACE_Allocator
*message_block_allocator
= 0);
146 * Create an ACE_Message_Block that refers to @a data without
147 * copying it. The @a data memory will not be freed when this block is
148 * destroyed; memory management of @a data is left to the caller.
149 * Note that the @c size of the new ACE_Message_Block will be @a size, but
150 * the @c length will be 0 until the write pointer is changed.
152 ACE_Message_Block (const char *data
,
154 unsigned long priority
= ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY
);
157 * Create an initialized message of type @a type containing @a size
158 * bytes. The @a cont argument initializes the continuation field in
159 * the ACE_Message_Block. If @a data == 0 then this block allocates and
160 * owns the block's memory, using @a allocator to get the data if it's
161 * non-0. If @a data != 0 then this block refers to that memory until
162 * this this block ceases to exist; this object will not free @a data on
163 * destruction. If @a locking_strategy is non-0 then this is used
164 * to protect regions of code that access shared state (e.g.,
165 * reference counting) from race conditions. Note that the @c size
166 * of the ACE_Message_Block will be @a size, but the @c length will be 0
167 * until the write pointer is set. The @a data_block_allocator is used to
168 * allocate the data blocks while the @a allocator_strategy is used
169 * to allocate the buffers contained by those. The
170 * @a message_block_allocator is used to allocate new ACE_Message_Block
171 * objects when the duplicate() method is called. If a
172 * @a message_block_allocator is given, this ACE_Message_Block and
173 * future ACE_Message_Block objects created by duplicate() will be
174 * freed using this allocator when they are released.
175 * @note If you use this allocator, the ACE_Message_Block you created
176 * should have been created using this allocator because it will be
177 * released to the same allocator.
179 ACE_Message_Block (size_t size
,
180 ACE_Message_Type type
= MB_DATA
,
181 ACE_Message_Block
*cont
= 0,
182 const char *data
= 0,
183 ACE_Allocator
*allocator_strategy
= 0,
184 ACE_Lock
*locking_strategy
= 0,
185 unsigned long priority
= ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY
,
186 const ACE_Time_Value
&execution_time
= ACE_Time_Value::zero
,
187 const ACE_Time_Value
&deadline_time
= ACE_Time_Value::max_time
,
188 ACE_Allocator
*data_block_allocator
= 0,
189 ACE_Allocator
*message_block_allocator
= 0);
192 * A copy constructor. This constructor is a bit different. If the
193 * incoming Message Block has a data block from the stack this
194 * constructor does a deep copy ie. allocates a new data block on
195 * the heap and does a copy of the data from the incoming message
196 * block. As a final note, the alignment information is used to
197 * align the data block if it is created afresh. If the incoming
198 * @a mb has a data block has a data block allocated from the heap,
199 * then this constructor just duplicates (ie. a shallow copy) the
200 * data block of the incoming @a mb.
202 ACE_Message_Block (const ACE_Message_Block
&mb
,
206 * Create a Message Block that assumes it has ownership of @a data,
207 * but in reality it doesnt (i.e., cannot delete it since it didn't
208 * malloc it!). Note that the @c size of the Message_Block will
209 * be @a size, but the @a length will be 0 until <wr_ptr> is set.
211 int init (const char *data
,
215 * Create an initialized message of type @a type containing @a size
216 * bytes. The @a cont argument initializes the continuation field in
217 * the <Message_Block>. If @a data == 0 then we create and own the
218 * @a data, using @a allocator_strategy to get the data if it's non-0. If
219 * @a data != 0 we assume that we have ownership of the @a data till
220 * this object ceases to exist (and don't delete it during
221 * destruction). If @a locking_strategy is non-0 then this is used
222 * to protect regions of code that access shared state (e.g.,
223 * reference counting) from race conditions. Note that the @a size
224 * of the <Message_Block> will be @a size, but the @a length will be 0
225 * until <wr_ptr> is set. The @a data_block_allocator is use to
226 * allocate the data blocks while the @a allocator_strategy is used
227 * to allocate the buffers contained by those.
229 int init (size_t size
,
230 ACE_Message_Type type
= MB_DATA
,
231 ACE_Message_Block
*cont
= 0,
232 const char *data
= 0,
233 ACE_Allocator
*allocator_strategy
= 0,
234 ACE_Lock
*locking_strategy
= 0,
235 unsigned long priority
= ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY
,
236 const ACE_Time_Value
&execution_time
= ACE_Time_Value::zero
,
237 const ACE_Time_Value
&deadline_time
= ACE_Time_Value::max_time
,
238 ACE_Allocator
*data_block_allocator
= 0,
239 ACE_Allocator
*message_block_allocator
= 0);
242 * Delete all the resources held in the message.
244 * Note that <release()> is designed to release the continuation
245 * chain; the destructor is not. See <release()> for details.
247 virtual ~ACE_Message_Block (void);
249 // = Message Type accessors and mutators.
251 /// Get type of the message.
252 ACE_Message_Type
msg_type (void) const;
254 /// Set type of the message.
255 void msg_type (ACE_Message_Type type
);
257 /// Find out what type of message this is.
258 int is_data_msg (void) const;
260 /// Find out what class of message this is (there are two classes,
261 /// @c normal messages and @c high-priority messages).
262 ACE_Message_Type
msg_class (void) const;
264 // = Message flag accessors and mutators.
265 /// Bitwise-or the @a more_flags into the existing message flags and
266 /// return the new value.
267 Message_Flags
set_flags (Message_Flags more_flags
);
269 /// Clear the message flag bits specified in @a less_flags and return
271 Message_Flags
clr_flags (Message_Flags less_flags
);
273 /// Get the current message flags.
274 Message_Flags
flags (void) const;
276 // = Data Block flag accessors and mutators.
277 /// Bitwise-or the @a more_flags into the existing message flags and
278 /// return the new value.
279 /* @todo: I think the following set of methods could not be used at
280 * all. May be they are useless. Let us have it so that we dont
281 * mess up memory management of the Message_Block. Somebody correct
282 * me if I am totally totally wrong..
284 Message_Flags
set_self_flags (ACE_Message_Block::Message_Flags more_flags
);
286 /// Clear the message flag bits specified in @a less_flags and return
288 Message_Flags
clr_self_flags (ACE_Message_Block::Message_Flags less_flags
);
290 /// Get the current message flags.
291 Message_Flags
self_flags (void) const;
293 /// Get priority of the message.
294 unsigned long msg_priority (void) const;
296 /// Set priority of the message.
297 void msg_priority (unsigned long priority
);
299 /// Get execution time associated with the message.
300 const ACE_Time_Value
&msg_execution_time (void) const;
302 /// Set execution time associated with the message.
303 void msg_execution_time (const ACE_Time_Value
&et
);
305 /// Get absolute time of deadline associated with the message.
306 const ACE_Time_Value
&msg_deadline_time (void) const;
308 /// Set absolute time of deadline associated with the message.
309 void msg_deadline_time (const ACE_Time_Value
&dt
);
311 // = Deep copy and shallow copy methods.
313 /// Return an exact "deep copy" of the message, i.e., create fresh
314 /// new copies of all the Data_Blocks and continuations.
315 virtual ACE_Message_Block
*clone (Message_Flags mask
= 0) const;
317 /// Return a "shallow" copy that increments our reference count by 1.
318 virtual ACE_Message_Block
*duplicate (void) const;
321 * Return a "shallow" copy that increments our reference count by 1.
322 * This is similar to CORBA's <_duplicate> method, which is useful
323 * if you want to eliminate lots of checks for NULL @a mb pointers
324 * before calling <_duplicate> on them.
326 static ACE_Message_Block
*duplicate (const ACE_Message_Block
*mb
);
329 * Decrease the shared ACE_Data_Block's reference count by 1. If the
330 * ACE_Data_Block's reference count goes to 0, it is deleted.
331 * In all cases, this ACE_Message_Block is deleted - it must have come
332 * from the heap, or there will be trouble.
334 * release() is designed to release the continuation chain; the
335 * destructor is not. If we make the destructor release the
336 * continuation chain by calling release() or delete on the message
337 * blocks in the continuation chain, the following code will not
338 * work since the message block in the continuation chain is not off
341 * ACE_Message_Block mb1 (1024);
342 * ACE_Message_Block mb2 (1024);
346 * And hence, call release() on a dynamically allocated message
347 * block. This will release all the message blocks in the
348 * continuation chain. If you call delete or let the message block
349 * fall off the stack, cleanup of the message blocks in the
350 * continuation chain becomes the responsibility of the user.
352 * @retval 0, always, and the object this method was invoked on is no
355 virtual ACE_Message_Block
*release (void);
358 * This behaves like the non-static method <release>, except that it
359 * checks if @a mb is 0. This is similar to <CORBA::release>, which
360 * is useful if you want to eliminate lots of checks for NULL
361 * pointers before calling <release> on them. Returns @a mb.
363 static ACE_Message_Block
*release (ACE_Message_Block
*mb
);
365 // = Operations on Message data
368 * Copies data into this ACE_Message_Block. Data is copied into the
369 * block starting at the current write pointer.
371 * @param buf Pointer to the buffer to copy from.
372 * @param n The number of bytes to copy.
374 * @retval 0 on success; the write pointer is advanced by @arg n.
375 * @retval -1 if the amount of free space following the write pointer
376 * in the block is less than @arg n. Free space can be checked
377 * by calling space().
379 int copy (const char *buf
, size_t n
);
382 * Copies a 0-terminated character string into this ACE_Message_Block.
383 * The string is copied into the block starting at the current write
384 * pointer. The 0-terminator is included in the copied data.
386 * @param buf Pointer to the character string to copy from.
388 * @retval 0 on success; the write pointer is advanced by the string's
389 * length, including the 0 terminator.
390 * @retval -1 if the amount of free space following the write pointer
391 * in the block is less than required to hold the entire string.
392 * Free space can be checked by calling space().
394 int copy (const char *buf
);
396 /// Normalizes data in the top-level <Message_Block> to align with the base,
397 /// i.e., it "shifts" the data pointed to by <rd_ptr> down to the <base> and
398 /// then readjusts <rd_ptr> to point to <base> and <wr_ptr> to point
399 /// to <base> + the length of the moved data. Returns -1 and does
400 /// nothing if the <rd_ptr> is > <wr_ptr>, else 0 on success.
403 /// Resets the Message Block data to contain nothing, i.e., sets the
404 /// read and write pointers to align with the base.
407 /// Access all the allocators in the message block.
408 /// @@todo: Not sure whether we would need finer control while
409 /// trying to access allocators ie. a method for every allocator.
411 * This method returns the allocators only from the first message
412 * block in the chain.
414 * @param allocator_strategy Strategy used to allocate the
417 * @param data_block_allocator Strategy used to allocate the
418 * underlying data block
420 * @param message_block_allocator Strategy used to allocate the
423 void access_allocators (ACE_Allocator
*&allocator_strategy
,
424 ACE_Allocator
*&data_block_allocator
,
425 ACE_Allocator
*&message_block_allocator
);
427 /// Reset all the allocators in the message block.
428 /// @todo Not sure whether we would need finer control while
429 /// trying to reset allocators ie. a method for every allocator.
431 * This method resets the allocators in all the message blocks in
434 void reset_allocators (ACE_Allocator
*allocator_strategy
= 0,
435 ACE_Allocator
*data_block_allocator
= 0,
436 ACE_Allocator
*message_block_allocator
= 0);
438 /// Get message data.
439 char *base (void) const;
441 /// Set message data (doesn't reallocate).
442 void base (char *data
,
444 Message_Flags
= DONT_DELETE
);
446 /// Return a pointer to 1 past the end of the allocated data in a message.
447 char *end (void) const;
450 * Return a pointer to 1 past the end of the allotted data in a message.
451 * Allotted data may be less than allocated data if a value smaller than
452 * capacity() to is passed to size().
454 char *mark (void) const;
456 /// Get the read pointer.
457 char *rd_ptr (void) const;
459 /// Set the read pointer to @a ptr.
460 void rd_ptr (char *ptr
);
462 /// Set the read pointer ahead @a n bytes.
463 void rd_ptr (size_t n
);
465 /// Get the write pointer.
466 char *wr_ptr (void) const;
468 /// Set the write pointer to @a ptr.
469 void wr_ptr (char *ptr
);
471 /// Set the write pointer ahead @a n bytes. This is used to compute
472 /// the <length> of a message.
473 void wr_ptr (size_t n
);
475 /** @name Message length and size operations
477 * Message length is (wr_ptr - rd_ptr).
479 * Message size is capacity of the message, including data outside
480 * the [rd_ptr,wr_ptr] range.
483 /// Get the length of the message
484 size_t length (void) const;
486 /// Set the length of the message
487 void length (size_t n
);
489 /// Get the length of the <Message_Block>s, including chained
490 /// <Message_Block>s.
491 size_t total_length (void) const;
493 /// Get the total number of bytes in all <Message_Block>s, including
494 /// chained <Message_Block>s.
495 size_t total_size (void) const;
497 /// Get the total number of bytes and total length in all
498 /// <Message_Block>s, including chained <Message_Block>s.
499 void total_size_and_length (size_t &mb_size
,
500 size_t &mb_length
) const;
502 /// Get the number of bytes in the top-level <Message_Block> (i.e.,
503 /// does not consider the bytes in chained <Message_Block>s).
504 size_t size (void) const;
507 * Set the number of bytes in the top-level <Message_Block>,
508 * reallocating space if necessary. However, the <rd_ptr_> and
509 * <wr_ptr_> remain at the original offsets into the buffer, even if
510 * it is reallocated. Returns 0 if successful, else -1.
512 int size (size_t length
);
514 /// Get the number of allocated bytes in all <Message_Block>, including
515 /// chained <Message_Block>s.
516 size_t total_capacity (void) const;
518 /// Get the number of allocated bytes in the top-level <Message_Block>.
519 size_t capacity (void) const;
521 /// Get the number of bytes available after the <wr_ptr_> in the
522 /// top-level <Message_Block>.
523 size_t space (void) const;
526 // = ACE_Data_Block methods.
529 * Get a pointer to the data block. Note that the ACE_Message_Block
530 * still references the block; this call does not change the reference
533 ACE_Data_Block
*data_block (void) const;
536 * Set a new data block pointer. The original ACE_Data_Block is released
537 * as a result of this call. If you need to keep the original block, call
538 * <replace_data_block> instead. Upon return, this ACE_Message_Block
539 * holds a pointer to the new ACE_Data_Block, taking over the reference
540 * you held on it prior to the call.
542 void data_block (ACE_Data_Block
*);
544 /// Set a new data block pointer. A pointer to the original ACE_Data_Block
545 /// is returned, and not released (as it is with <data_block>).
546 ACE_Data_Block
*replace_data_block (ACE_Data_Block
*);
548 // = The continuation field chains together composite messages.
549 /// Get the continuation field.
550 ACE_Message_Block
*cont (void) const;
552 /// Set the continuation field.
553 void cont (ACE_Message_Block
*);
555 // = Pointer to the <Message_Block> directly ahead in the ACE_Message_Queue.
556 /// Get link to next message.
557 ACE_Message_Block
*next (void) const;
559 /// Set link to next message.
560 void next (ACE_Message_Block
*);
562 // = Pointer to the <Message_Block> directly behind in the ACE_Message_Queue.
563 /// Get link to prev message.
564 ACE_Message_Block
*prev (void) const;
566 /// Set link to prev message.
567 void prev (ACE_Message_Block
*);
569 // = The locking strategy prevents race conditions.
570 /// Get the locking strategy.
571 ACE_Lock
*locking_strategy (void);
573 /// Set a new locking strategy and return the hold one.
574 ACE_Lock
*locking_strategy (ACE_Lock
*);
576 /// Get the current reference count.
577 int reference_count (void) const;
579 /// Dump the state of an object.
580 void dump (void) const;
582 /// Declare the dynamic allocation hooks.
583 ACE_ALLOC_HOOK_DECLARE
;
586 // = Internal initialization methods.
587 /// Perform the actual initialization.
588 ACE_Message_Block (size_t size
,
589 ACE_Message_Type type
,
590 ACE_Message_Block
*cont
,
592 ACE_Allocator
*allocator_strategy
,
593 ACE_Lock
*locking_strategy
,
595 unsigned long priority
,
596 const ACE_Time_Value
&execution_time
,
597 const ACE_Time_Value
&deadline_time
,
599 ACE_Allocator
*data_block_allocator
,
600 ACE_Allocator
*message_block_allocator
);
602 /// Internal release implementation
603 /// Returns 1 if the data block has to be destroyed.
604 int release_i (ACE_Lock
*lock
);
606 /// Perform the actual initialization.
607 int init_i (size_t size
,
608 ACE_Message_Type type
,
609 ACE_Message_Block
*cont
,
611 ACE_Allocator
*allocator_strategy
,
612 ACE_Lock
*locking_strategy
,
614 unsigned long priority
,
615 const ACE_Time_Value
&execution_time
,
616 const ACE_Time_Value
&deadline_time
,
618 ACE_Allocator
*data_block_allocator
,
619 ACE_Allocator
*message_block_allocator
);
621 /// Pointer to beginning of next read.
624 /// Pointer to beginning of next write.
627 /// Priority of message.
628 unsigned long priority_
;
630 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
631 /// Execution time associated with the message.
632 ACE_Time_Value execution_time_
;
634 /// Absolute deadline time for message.
635 ACE_Time_Value deadline_time_
;
636 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
638 // = Links to other ACE_Message_Block *s.
639 /// Pointer to next message block in the chain.
640 ACE_Message_Block
*cont_
;
642 /// Pointer to next message in the list.
643 ACE_Message_Block
*next_
;
645 /// Pointer to previous message in the list.
646 ACE_Message_Block
*prev_
;
648 /// Misc flags (e.g., DONT_DELETE and USER_FLAGS).
649 ACE_Message_Block::Message_Flags flags_
;
651 /// Pointer to the reference counted data structure that contains the
652 /// actual memory buffer.
653 ACE_Data_Block
*data_block_
;
655 /// The allocator used to destroy ourselves when release is called
656 /// and create new message blocks on duplicate.
657 ACE_Allocator
*message_block_allocator_
;
660 // = Disallow these operations for now (use <clone> instead).
661 ACE_Message_Block
&operator= (const ACE_Message_Block
&);
662 ACE_Message_Block (const ACE_Message_Block
&);
666 * @class ACE_Data_Block
668 * @brief Stores the data payload that is accessed via one or more
669 * ACE_Message_Block's.
671 * This data structure is reference counted to maximize
672 * sharing. It also contains the <locking_strategy_> (which
673 * protects the reference count from race conditions in
674 * concurrent programs) and the <allocation_strategy_> (which
675 * determines what memory pool is used to allocate the memory).
677 class ACE_Export ACE_Data_Block
680 // = Initialization and termination methods.
681 /// Default "do-nothing" constructor.
682 ACE_Data_Block (void);
685 ACE_Data_Block (size_t size
,
686 ACE_Message_Block::ACE_Message_Type msg_type
,
687 const char *msg_data
,
688 ACE_Allocator
*allocator_strategy
,
689 ACE_Lock
*locking_strategy
,
690 ACE_Message_Block::Message_Flags flags
,
691 ACE_Allocator
*data_block_allocator
);
693 /// Delete all the resources held in the message.
694 virtual ~ACE_Data_Block (void);
696 /// Get type of the message.
697 ACE_Message_Block::ACE_Message_Type
msg_type (void) const;
699 /// Set type of the message.
700 void msg_type (ACE_Message_Block::ACE_Message_Type type
);
702 /// Get message data pointer
703 char *base (void) const;
705 /// Set message data pointer (doesn't reallocate).
706 void base (char *data
,
708 ACE_Message_Block::Message_Flags mflags
= ACE_Message_Block::DONT_DELETE
);
710 /// Return a pointer to 1 past the end of the allocated data in a message.
711 char *end (void) const;
714 * Return a pointer to 1 past the end of the allotted data in a message.
715 * The allotted data may be less than allocated data if <size()> is passed
716 * an argument less than <capacity()>.
718 char *mark (void) const;
720 // = Message size is the total amount of space alloted.
722 /// Get the total amount of allotted space in the message. The amount of
723 /// allotted space may be less than allocated space.
724 size_t size (void) const;
726 /// Set the total amount of space in the message. Returns 0 if
727 /// successful, else -1.
728 int size (size_t length
);
730 /// Get the total amount of allocated space.
731 size_t capacity (void) const;
734 * Return an exact "deep copy" of the message, i.e., create fresh
735 * new copies of all the Data_Blocks and continuations.
736 * Notice that Data_Blocks can act as "Prototypes", i.e. derived
737 * classes can override this method and create instances of
740 virtual ACE_Data_Block
*clone (ACE_Message_Block::Message_Flags mask
= 0) const;
743 * As clone above, but it does not copy the contents of the buffer,
744 * i.e., create a new Data_Block of the same dynamic type, with the
745 * same allocator, locking_strategy, and with the same amount of
746 * storage available (if @a max_size is zero) but the buffer is unitialized.
747 * If @a max_size is specified other than zero, it will be used when
748 * creating the new data block.
750 virtual ACE_Data_Block
*clone_nocopy (ACE_Message_Block::Message_Flags mask
= 0,
751 size_t max_size
= 0) const;
753 /// Return a "shallow" copy that increments our reference count by 1.
754 ACE_Data_Block
*duplicate (void);
757 * Decrease the shared reference count by 1. If the reference count
758 * is > 0 then return this; else if reference count == 0 then delete
759 * @c this and @a mb and return 0. Behavior is undefined if reference
762 ACE_Data_Block
*release (ACE_Lock
*lock
= 0);
764 // = Message flag accessors and mutators.
765 /// Bitwise-or the <more_flags> into the existing message flags and
766 /// return the new value.
767 ACE_Message_Block::Message_Flags
set_flags (ACE_Message_Block::Message_Flags more_flags
);
769 /// Clear the message flag bits specified in <less_flags> and return
771 ACE_Message_Block::Message_Flags
clr_flags (ACE_Message_Block::Message_Flags less_flags
);
773 /// Get the current message flags.
774 ACE_Message_Block::Message_Flags
flags (void) const;
776 /// Obtain the allocator strategy.
777 ACE_Allocator
*allocator_strategy (void) const;
779 // = The locking strategy prevents race conditions.
780 /// Get the locking strategy.
781 ACE_Lock
*locking_strategy (void);
783 /// Set a new locking strategy and return the hold one.
784 ACE_Lock
*locking_strategy (ACE_Lock
*);
786 /// Dump the state of an object.
787 void dump (void) const;
789 /// Get the current reference count.
790 int reference_count (void) const;
792 /// Get the allocator used to create this object
793 ACE_Allocator
*data_block_allocator (void) const;
796 /// Internal release implementation
797 virtual ACE_Data_Block
*release_i (void);
799 /// Internal get the current reference count.
800 int reference_count_i (void) const;
803 * Decrease the reference count, but don't delete the object.
804 * Returns 0 if the object should be removed.
805 * If <lock> is equal to the locking strategy then we assume that
806 * the lock is beign held by the current thread; this is used to
807 * release all the data blocks in a chain while holding a single
810 friend class ACE_Message_Block
;
811 ACE_Data_Block
*release_no_delete (ACE_Lock
*lock
);
814 ACE_Message_Block::ACE_Message_Type type_
;
816 /// Current size of message block.
819 /// Total size of buffer.
822 /// Misc flags (e.g., DONT_DELETE and USER_FLAGS).
823 ACE_Message_Block::Message_Flags flags_
;
825 /// Pointer To beginning of message payload.
830 * Pointer to the allocator defined for this ACE_Data_Block. Note
831 * that this pointer is shared by all owners of this
834 ACE_Allocator
*allocator_strategy_
;
837 * Pointer to the locking strategy defined for this
838 * ACE_Data_Block. This is used to protect regions of code that
839 * access shared ACE_Data_Block state. Note that this lock is
840 * shared by all owners of the ACE_Data_Block's data.
842 ACE_Lock
*locking_strategy_
;
845 * Reference count for this ACE_Data_Block, which is used to avoid
846 * deep copies (i.e., <clone>). Note that this pointer value is
847 * shared by all owners of the <Data_Block>'s data, i.e., all the
848 * ACE_Message_Blocks.
850 int reference_count_
;
852 /// The allocator use to destroy ourselves.
853 ACE_Allocator
*data_block_allocator_
;
856 // = Disallow these operations.
857 ACE_Data_Block
&operator= (const ACE_Data_Block
&);
858 ACE_Data_Block (const ACE_Data_Block
&);
861 ACE_END_VERSIONED_NAMESPACE_DECL
863 #if defined (__ACE_INLINE__)
864 #include "ace/Message_Block.inl"
865 #endif /* __ACE_INLINE__ */
867 #include "ace/Message_Block_T.h"
869 #include /**/ "ace/post.h"
871 #endif /* ACE_MESSAGE_BLOCK_H */