1 #include "ace/Message_Block.h"
3 #if !defined (__ACE_INLINE__)
4 #include "ace/Message_Block.inl"
5 #endif /* __ACE_INLINE__ */
7 #include "ace/Guard_T.h"
8 #include "ace/Log_Category.h"
9 #include "ace/Malloc_Base.h"
10 #include "ace/OS_NS_string.h"
12 //#define ACE_ENABLE_TIMEPROBES
13 #include "ace/Timeprobe.h"
15 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
17 ACE_ALLOC_HOOK_DEFINE (ACE_Message_Block
)
19 #if defined (ACE_ENABLE_TIMEPROBES)
21 static const char *ACE_MB_Timeprobe_Description
[] =
23 "Message_Block::init_i - enter",
24 "Message_Block::init_i - leave",
25 "Message_Block::init_i - db alloc",
26 "Message_Block::init_i - db ctor",
27 "Data_Block::ctor[1] - enter",
28 "Data_Block::ctor[1] - leave",
29 "Data_Block::ctor[2] - enter",
30 "Data_Block::ctor[2] - leave",
31 "Data_Block::clone - enter",
32 "Data_Block::clone - leave"
37 ACE_MESSAGE_BLOCK_INIT_I_ENTER
= 3000,
38 ACE_MESSAGE_BLOCK_INIT_I_LEAVE
,
39 ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC
,
40 ACE_MESSAGE_BLOCK_INIT_I_DB_CTOR
,
41 ACE_DATA_BLOCK_CTOR1_ENTER
,
42 ACE_DATA_BLOCK_CTOR1_LEAVE
,
43 ACE_DATA_BLOCK_CTOR2_ENTER
,
44 ACE_DATA_BLOCK_CTOR2_LEAVE
,
45 ACE_DATA_BLOCK_CLONE_ENTER
,
46 ACE_DATA_BLOCK_CLONE_LEAVE
51 ACE_TIMEPROBE_EVENT_DESCRIPTIONS (ACE_MB_Timeprobe_Description
,
52 ACE_MESSAGE_BLOCK_INIT_I_ENTER
);
54 #endif /* ACE_ENABLE_TIMEPROBES */
57 ACE_Message_Block::data_block (ACE_Data_Block
*db
)
59 ACE_TRACE ("ACE_Message_Block::data_block");
60 if (ACE_BIT_DISABLED (this->flags_
,
61 ACE_Message_Block::DONT_DELETE
)
62 && this->data_block_
!= 0)
63 this->data_block_
->release ();
65 this->data_block_
= db
;
67 // Set the read and write pointers in the <Message_Block> to point
68 // to the buffer in the <ACE_Data_Block>.
69 this->rd_ptr (this->data_block ()->base ());
70 this->wr_ptr (this->data_block ()->base ());
74 ACE_Message_Block::copy (const char *buf
, size_t n
)
76 ACE_TRACE ("ACE_Message_Block::copy");
78 /*size_t len = static_cast<size_t> (this->end () - this->wr_ptr ());*/
79 // Note that for this to work correct, end () *must* be >= mark ().
80 size_t len
= this->space ();
89 (void) ACE_OS::memcpy (this->wr_ptr (),
98 ACE_Message_Block::copy (const char *buf
)
100 ACE_TRACE ("ACE_Message_Block::copy");
102 /* size_t len = static_cast<size_t> (this->end () - this->wr_ptr ()); */
103 // Note that for this to work correct, end() *must* be >= wr_ptr().
104 size_t len
= this->space ();
106 size_t buflen
= ACE_OS::strlen (buf
) + 1;
115 (void) ACE_OS::memcpy (this->wr_ptr (),
118 this->wr_ptr (buflen
);
124 ACE_Message_Block::crunch (void)
126 if (this->rd_ptr_
!= 0)
128 if (this->rd_ptr_
> this->wr_ptr_
)
131 size_t const len
= this->length ();
132 (void) ACE_OS::memmove (this->base (),
135 this->rd_ptr (this->base ());
136 this->wr_ptr (this->base () + len
);
142 ACE_Data_Block::dump (void) const
144 #if defined (ACE_HAS_DUMP)
145 ACE_TRACE ("ACE_Data_Block::dump");
146 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
147 ACELIB_DEBUG ((LM_DEBUG
,
148 ACE_TEXT ("-----( Data Block )-----\n")
149 ACE_TEXT ("type_ = %d\n")
150 ACE_TEXT ("cur_size_ = %u\n")
151 ACE_TEXT ("max_size_ = %u\n")
152 ACE_TEXT ("flags_ = %u\n")
153 ACE_TEXT ("base_ = %@\n")
154 ACE_TEXT ("locking_strategy_ = %u\n")
155 ACE_TEXT ("reference_count_ = %u\n")
156 ACE_TEXT ("---------------------------\n"),
162 this->locking_strategy_
,
163 this->reference_count_
));
164 this->allocator_strategy_
->dump ();
165 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
166 #endif /* ACE_HAS_DUMP */
170 ACE_Message_Block::dump (void) const
172 #if defined (ACE_HAS_DUMP)
173 ACE_TRACE ("ACE_Message_Block::dump");
174 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
175 ACELIB_DEBUG ((LM_DEBUG
,
176 ACE_TEXT ("-----( Message Block )-----\n")
177 ACE_TEXT ("priority_ = %d\n")
178 ACE_TEXT ("next_ = %@\n")
179 ACE_TEXT ("prev_ = %@\n")
180 ACE_TEXT ("cont_ = %@\n")
181 ACE_TEXT ("rd_ptr_ = %@\n")
182 ACE_TEXT ("wr_ptr_ = %@\n")
183 ACE_TEXT ("---------------------------\n"),
190 this->data_block ()->dump ();
191 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
192 #endif /* ACE_HAS_DUMP */
196 ACE_Data_Block::reference_count (void) const
198 if (this->locking_strategy_
)
200 // We need to acquire the lock before retrieving the count
201 ACE_GUARD_RETURN (ACE_Lock
, ace_mon
, *this->locking_strategy_
, 0);
203 return this->reference_count_i ();
206 return this->reference_count_i ();
210 ACE_Data_Block::size (size_t length
)
212 ACE_TRACE ("ACE_Data_Block::size");
214 if (length
<= this->max_size_
)
215 this->cur_size_
= length
;
218 // We need to resize!
220 ACE_ALLOCATOR_RETURN (buf
,
221 (char *) this->allocator_strategy_
->malloc (length
),
227 if (ACE_BIT_DISABLED (this->flags_
,
228 ACE_Message_Block::DONT_DELETE
))
229 this->allocator_strategy_
->free ((void *) this->base_
);
231 // We now assume ownership.
232 ACE_CLR_BITS (this->flags_
,
233 ACE_Message_Block::DONT_DELETE
);
234 this->max_size_
= length
;
235 this->cur_size_
= length
;
242 ACE_Message_Block::size (size_t length
)
244 ACE_TRACE ("ACE_Message_Block::size");
246 // Resize the underlying <ACE_Data_Block>.
247 if (this->data_block ()->size (length
) == -1)
254 ACE_Message_Block::total_size_and_length (size_t &mb_size
,
255 size_t &mb_length
) const
257 ACE_TRACE ("ACE_Message_Block::total_size_and_length");
259 for (const ACE_Message_Block
*i
= this;
263 mb_size
+= i
->size ();
264 mb_length
+= i
->length ();
269 ACE_Message_Block::total_size (void) const
271 ACE_TRACE ("ACE_Message_Block::total_size");
274 for (const ACE_Message_Block
*i
= this;
283 ACE_Message_Block::total_length (void) const
285 ACE_TRACE ("ACE_Message_Block::total_length");
288 for (const ACE_Message_Block
*i
= this;
291 length
+= i
->length ();
297 ACE_Message_Block::total_capacity (void) const
299 ACE_TRACE ("ACE_Message_Block::total_capacity");
303 for (const ACE_Message_Block
*i
= this;
306 size
+= i
->capacity ();
311 ACE_Data_Block::ACE_Data_Block (void)
312 : type_ (ACE_Message_Block::MB_DATA
),
315 flags_ (ACE_Message_Block::DONT_DELETE
),
317 allocator_strategy_ (0),
318 locking_strategy_ (0),
319 reference_count_ (1),
320 data_block_allocator_ (0)
322 ACE_TRACE ("ACE_Data_Block::ACE_Data_Block");
323 ACE_FUNCTION_TIMEPROBE (ACE_DATA_BLOCK_CTOR1_ENTER
);
325 ACE_ALLOCATOR (this->allocator_strategy_
,
326 ACE_Allocator::instance ());
328 ACE_ALLOCATOR (this->data_block_allocator_
,
329 ACE_Allocator::instance ());
332 ACE_Data_Block::ACE_Data_Block (size_t size
,
333 ACE_Message_Block::ACE_Message_Type msg_type
,
334 const char *msg_data
,
335 ACE_Allocator
*allocator_strategy
,
336 ACE_Lock
*locking_strategy
,
337 ACE_Message_Block::Message_Flags flags
,
338 ACE_Allocator
*data_block_allocator
)
340 cur_size_ (0), // Reset later if memory alloc'd ok
343 base_ (const_cast <char *> (msg_data
)),
344 allocator_strategy_ (allocator_strategy
),
345 locking_strategy_ (locking_strategy
),
346 reference_count_ (1),
347 data_block_allocator_ (data_block_allocator
)
349 ACE_TRACE ("ACE_Data_Block::ACE_Data_Block");
350 ACE_FUNCTION_TIMEPROBE (ACE_DATA_BLOCK_CTOR2_ENTER
);
352 // If the user didn't pass one in, let's use the
353 // <ACE_Allocator::instance>.
354 if (this->allocator_strategy_
== 0)
355 ACE_ALLOCATOR (this->allocator_strategy_
,
356 ACE_Allocator::instance ());
358 if (this->data_block_allocator_
== 0)
359 ACE_ALLOCATOR (this->data_block_allocator_
,
360 ACE_Allocator::instance ());
364 ACE_ALLOCATOR (this->base_
,
365 (char *) this->allocator_strategy_
->malloc (size
));
366 #if defined (ACE_INITIALIZE_MEMORY_BEFORE_USE)
367 (void) ACE_OS::memset (this->base_
,
370 #endif /* ACE_INITIALIZE_MEMORY_BEFORE_USE */
373 // ACE_ALLOCATOR returns on alloc failure but we cant throw, so setting
374 // the size to 0 (i.e. "bad bit") ...
375 if (this->base_
== 0)
380 // The memory is legit, whether passed in or allocated, so set
382 this->cur_size_
= this->max_size_
= size
;
385 ACE_Message_Block::ACE_Message_Block (const char *data
,
387 unsigned long priority
)
391 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
393 if (this->init_i (size
, // size
398 0, // locking strategy
399 ACE_Message_Block::DONT_DELETE
, // flags
400 priority
, // priority
401 ACE_Time_Value::zero
, // execution time
402 ACE_Time_Value::max_time
, // absolute time of deadline
404 0, // data_block allocator
405 0) == -1) // message_block allocator
406 ACELIB_ERROR ((LM_ERROR
,
407 ACE_TEXT ("ACE_Message_Block")));
410 ACE_Message_Block::ACE_Message_Block (ACE_Allocator
*message_block_allocator
)
414 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
416 if (this->init_i (0, // size
421 0, // locking strategy
422 ACE_Message_Block::DONT_DELETE
, // flags
424 ACE_Time_Value::zero
, // execution time
425 ACE_Time_Value::max_time
, // absolute time of deadline
427 0, // data_block allocator
428 message_block_allocator
) == -1) // message_block allocator
429 ACELIB_ERROR ((LM_ERROR
,
430 ACE_TEXT ("ACE_Message_Block")));
433 ACE_Message_Block::ACE_Message_Block (size_t size
,
434 ACE_Message_Type msg_type
,
435 ACE_Message_Block
*msg_cont
,
436 const char *msg_data
,
437 ACE_Allocator
*allocator_strategy
,
438 ACE_Lock
*locking_strategy
,
439 unsigned long priority
,
440 const ACE_Time_Value
&execution_time
,
441 const ACE_Time_Value
&deadline_time
,
442 ACE_Allocator
*data_block_allocator
,
443 ACE_Allocator
*message_block_allocator
)
447 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
449 if (this->init_i (size
,
455 msg_data
? ACE_Message_Block::DONT_DELETE
: 0,
460 data_block_allocator
,
461 message_block_allocator
) == -1)
462 ACELIB_ERROR ((LM_ERROR
,
463 ACE_TEXT ("ACE_Message_Block")));
467 ACE_Message_Block::init (size_t size
,
468 ACE_Message_Type msg_type
,
469 ACE_Message_Block
*msg_cont
,
470 const char *msg_data
,
471 ACE_Allocator
*allocator_strategy
,
472 ACE_Lock
*locking_strategy
,
473 unsigned long priority
,
474 const ACE_Time_Value
&execution_time
,
475 const ACE_Time_Value
&deadline_time
,
476 ACE_Allocator
*data_block_allocator
,
477 ACE_Allocator
*message_block_allocator
)
479 ACE_TRACE ("ACE_Message_Block::init");
481 return this->init_i (size
,
487 msg_data
? ACE_Message_Block::DONT_DELETE
: 0,
492 data_block_allocator
,
493 message_block_allocator
);
497 ACE_Message_Block::init (const char *data
,
500 ACE_TRACE ("ACE_Message_Block::init");
501 // Should we also initialize all the other fields, as well?
503 return this->init_i (size
, // size
508 0, // locking strategy
509 ACE_Message_Block::DONT_DELETE
, // flags
511 ACE_Time_Value::zero
, // execution time
512 ACE_Time_Value::max_time
, // absolute time of deadline
514 0, // data_block allocator
515 0); // message_block allocator
518 ACE_Message_Block::ACE_Message_Block (size_t size
,
519 ACE_Message_Type msg_type
,
520 ACE_Message_Block
*msg_cont
,
521 const char *msg_data
,
522 ACE_Allocator
*allocator_strategy
,
523 ACE_Lock
*locking_strategy
,
525 unsigned long priority
,
526 const ACE_Time_Value
&execution_time
,
527 const ACE_Time_Value
&deadline_time
,
529 ACE_Allocator
*data_block_allocator
,
530 ACE_Allocator
*message_block_allocator
)
534 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
536 if (this->init_i (size
,
547 data_block_allocator
,
548 message_block_allocator
) == -1)
549 ACELIB_ERROR ((LM_ERROR
,
550 ACE_TEXT ("ACE_Message_Block")));
553 ACE_Message_Block::ACE_Message_Block (ACE_Data_Block
*data_block
,
554 ACE_Message_Block::Message_Flags flags
,
555 ACE_Allocator
*message_block_allocator
)
559 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
561 if (this->init_i (0, // size
566 0, // locking strategy
569 ACE_Time_Value::zero
, // execution time
570 ACE_Time_Value::max_time
, // absolute time of deadline
571 data_block
, // data block
572 data_block
->data_block_allocator (),
573 message_block_allocator
) == -1)
574 ACELIB_ERROR ((LM_ERROR
,
575 ACE_TEXT ("ACE_Message_Block")));
578 ACE_Message_Block::ACE_Message_Block (const ACE_Message_Block
&mb
,
583 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
585 if (ACE_BIT_DISABLED (mb
.flags_
,
586 ACE_Message_Block::DONT_DELETE
))
588 if (this->init_i (0, // size
593 0, // locking strategy
596 ACE_Time_Value::zero
, // execution time
597 ACE_Time_Value::max_time
, // absolute time of deadline
598 mb
.data_block ()->duplicate (), // data block
599 mb
.data_block ()->data_block_allocator (),
600 mb
.message_block_allocator_
) == -1)
601 ACELIB_ERROR ((LM_ERROR
,
602 ACE_TEXT ("ACE_Message_Block")));
603 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
605 char *start
= ACE_ptr_align_binary (this->base (),
608 char *start
= this->base ();
609 #endif /* ACE_LACKS_CDR_ALIGNMENT */
611 // Set our rd & wr pointers
612 this->rd_ptr (start
);
613 this->wr_ptr (start
);
618 if (this->init_i (0, // size
623 0, // locking strategy
626 ACE_Time_Value::zero
, // execution time
627 ACE_Time_Value::max_time
, // absolute time of deadline
628 mb
.data_block ()->clone_nocopy (),// data block
629 mb
.data_block ()->data_block_allocator (),
630 mb
.message_block_allocator_
) == -1)
631 ACELIB_ERROR ((LM_ERROR
,
632 ACE_TEXT ("ACE_Message_Block")));
634 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
636 char *start
= ACE_ptr_align_binary (this->base (),
639 char *start
= this->base ();
640 #endif /* ACE_LACKS_CDR_ALIGNMENT */
642 // Set our rd & wr pointers
643 this->rd_ptr (start
);
644 this->wr_ptr (start
);
646 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
647 // Get the alignment offset of the incoming ACE_Message_Block
648 start
= ACE_ptr_align_binary (mb
.base (),
652 #endif /* ACE_LACKS_CDR_ALIGNMENT */
654 // Actual offset for the incoming message block assuming that it
655 // is also aligned to the same "align" byte
656 size_t const wr_offset
= mb
.wr_ptr_
- (start
- mb
.base ());
658 // Copy wr_offset amount of data in to <this->data_block>
659 (void) ACE_OS::memcpy (this->wr_ptr (),
663 // Dont move the write pointer, just leave it to the application
664 // to do what it wants
667 #if defined (ACE_LACKS_CDR_ALIGNMENT)
668 ACE_UNUSED_ARG (align
);
669 #endif /* ACE_LACKS_CDR_ALIGNMENT */
673 ACE_Message_Block::init_i (size_t size
,
674 ACE_Message_Type msg_type
,
675 ACE_Message_Block
*msg_cont
,
676 const char *msg_data
,
677 ACE_Allocator
*allocator_strategy
,
678 ACE_Lock
*locking_strategy
,
680 unsigned long priority
,
681 const ACE_Time_Value
&execution_time
,
682 const ACE_Time_Value
&deadline_time
,
684 ACE_Allocator
*data_block_allocator
,
685 ACE_Allocator
*message_block_allocator
)
687 ACE_TRACE ("ACE_Message_Block::init_i");
688 ACE_FUNCTION_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_ENTER
);
692 this->priority_
= priority
;
693 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
694 this->execution_time_
= execution_time
;
695 this->deadline_time_
= deadline_time
;
697 ACE_UNUSED_ARG (execution_time
);
698 ACE_UNUSED_ARG (deadline_time
);
699 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
700 this->cont_
= msg_cont
;
704 this->message_block_allocator_
= message_block_allocator
;
706 if (this->data_block_
!= 0)
708 this->data_block_
->release ();
709 this->data_block_
= 0;
714 if (data_block_allocator
== 0)
715 ACE_ALLOCATOR_RETURN (data_block_allocator
,
716 ACE_Allocator::instance (),
719 ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC
);
721 // Allocate the <ACE_Data_Block> portion, which is reference
723 ACE_NEW_MALLOC_RETURN (db
,
724 static_cast<ACE_Data_Block
*> (
725 data_block_allocator
->malloc (sizeof (ACE_Data_Block
))),
726 ACE_Data_Block (size
,
732 data_block_allocator
),
734 ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_CTOR
);
736 // Message block initialization may fail, while the construction
737 // succeds. Since ACE may throw no exceptions, we have to do a
738 // separate check and clean up, like this:
739 if (db
!= 0 && db
->size () < size
)
741 db
->ACE_Data_Block::~ACE_Data_Block(); // placement destructor ...
742 data_block_allocator
->free (db
); // free ...
748 // Reset the data_block_ pointer.
749 this->data_block (db
);
754 ACE_Data_Block::~ACE_Data_Block (void)
757 ACE_ASSERT (this->reference_count_
<= 1);
759 // Just to be safe...
760 this->reference_count_
= 0;
762 if (ACE_BIT_DISABLED (this->flags_
,
763 ACE_Message_Block::DONT_DELETE
))
765 this->allocator_strategy_
->free ((void *) this->base_
);
771 ACE_Data_Block::release_i (void)
773 ACE_TRACE ("ACE_Data_Block::release_i");
775 ACE_ASSERT (this->reference_count_
> 0);
777 ACE_Data_Block
*result
= 0;
779 // decrement reference count
780 --this->reference_count_
;
782 if (this->reference_count_
== 0)
783 // this will cause deletion of this
792 ACE_Data_Block::release_no_delete (ACE_Lock
*lock
)
794 ACE_TRACE ("ACE_Data_Block::release_no_delete");
796 ACE_Data_Block
*result
= 0;
797 ACE_Lock
*lock_to_be_used
= 0;
799 // Check if we were passed in a lock
802 // Make sure that the lock passed in and our lock are the same
803 if (lock
== this->locking_strategy_
)
804 // In this case no locking is required.
807 // The lock passed in does not match our lock
809 // Lock to be used is our lock
810 lock_to_be_used
= this->locking_strategy_
;
812 // This is the case when no lock was passed in
815 // Lock to be used is our lock
816 lock_to_be_used
= this->locking_strategy_
;
819 // If there's a locking strategy then we need to acquire the lock
820 // before decrementing the count.
821 if (lock_to_be_used
!= 0)
823 ACE_GUARD_RETURN (ACE_Lock
, ace_mon
, *lock_to_be_used
, 0);
825 result
= this->release_i ();
829 result
= this->release_i ();
836 ACE_Data_Block::release (ACE_Lock
*lock
)
838 ACE_TRACE ("ACE_Data_Block::release");
840 ACE_Allocator
*allocator
= this->data_block_allocator_
;
842 ACE_Data_Block
*result
= this->release_no_delete (lock
);
844 // We must delete this outside the scope of the locking_strategy_
845 // since otherwise we'd be trying to "release" through a deleted
848 ACE_DES_FREE_THIS (allocator
->free
,
854 ACE_Message_Block::release (void)
856 ACE_TRACE ("ACE_Message_Block::release");
858 // We want to hold the data block in a temporary variable because we
859 // invoked "delete this;" at some point, so using this->data_block_
860 // could be a bad idea.
861 ACE_Data_Block
*tmp
= this->data_block ();
863 // This flag is set to 1 when we have to destroy the data_block
864 int destroy_dblock
= 0;
868 // Do we have a valid data block
869 if (this->data_block ())
871 // Grab the lock that belongs to my data block
872 lock
= this->data_block ()->locking_strategy ();
878 ACE_GUARD_RETURN (ACE_Lock
, ace_mon
, *lock
, 0);
880 // Call non-guarded release with @a lock
881 destroy_dblock
= this->release_i (lock
);
883 // This is the case when we have a valid data block but no lock
885 // Call non-guarded release with no lock
886 destroy_dblock
= this->release_i (0);
889 // This is the case when we don't even have a valid data block
890 destroy_dblock
= this->release_i (0);
892 if (destroy_dblock
!= 0)
894 ACE_Allocator
*allocator
= tmp
->data_block_allocator ();
904 ACE_Message_Block::release_i (ACE_Lock
*lock
)
906 ACE_TRACE ("ACE_Message_Block::release_i");
908 // Free up all the continuation messages.
911 ACE_Message_Block
*mb
= this->cont_
;
912 ACE_Message_Block
*tmp
= 0;
920 ACE_Data_Block
*db
= tmp
->data_block ();
921 if (tmp
->release_i (lock
) != 0)
923 ACE_Allocator
*allocator
= db
->data_block_allocator ();
936 if (ACE_BIT_DISABLED (this->flags_
,
937 ACE_Message_Block::DONT_DELETE
) &&
940 if (this->data_block ()->release_no_delete (lock
) == 0)
942 this->data_block_
= 0;
945 // We will now commit suicide: this object *must* have come from the
947 if (this->message_block_allocator_
== 0)
951 ACE_Allocator
*allocator
= this->message_block_allocator_
;
952 ACE_DES_FREE_THIS (allocator
->free
,
959 /* static */ ACE_Message_Block
*
960 ACE_Message_Block::release (ACE_Message_Block
*mb
)
962 ACE_TRACE ("ACE_Message_Block::release");
965 return mb
->release ();
970 ACE_Message_Block::~ACE_Message_Block (void)
972 ACE_TRACE ("ACE_Message_Block::~ACE_Message_Block");
974 if (ACE_BIT_DISABLED (this->flags_
,
975 ACE_Message_Block::DONT_DELETE
)&&
977 this->data_block ()->release ();
985 ACE_Data_Block::duplicate (void)
987 ACE_TRACE ("ACE_Data_Block::duplicate");
989 // Create a new <ACE_Message_Block>, but share the <base_> pointer
990 // data (i.e., don't copy that).
991 if (this->locking_strategy_
)
993 // We need to acquire the lock before incrementing the count.
994 ACE_GUARD_RETURN (ACE_Lock
, ace_mon
, *this->locking_strategy_
, 0);
995 ++this->reference_count_
;
998 ++this->reference_count_
;
1003 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
1004 #define ACE_EXECUTION_TIME this->execution_time_
1005 #define ACE_DEADLINE_TIME this->deadline_time_
1007 #define ACE_EXECUTION_TIME ACE_Time_Value::zero
1008 #define ACE_DEADLINE_TIME ACE_Time_Value::max_time
1009 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
1012 ACE_Message_Block::duplicate (void) const
1014 ACE_TRACE ("ACE_Message_Block::duplicate");
1016 ACE_Message_Block
*nb_top
= 0;
1017 ACE_Message_Block
*nb
= 0;
1019 const ACE_Message_Block
*current
= this;
1021 // Increment the reference counts of all the continuation messages.
1024 ACE_Message_Block
* cur_dup
= 0;
1026 // Create a new <ACE_Message_Block> that contains unique copies of
1027 // the message block fields, but a reference counted duplicate of
1028 // the <ACE_Data_Block>.
1030 // If there is no allocator, use the standard new and delete calls.
1031 if (current
->message_block_allocator_
== 0)
1032 ACE_NEW_NORETURN (cur_dup
,
1033 ACE_Message_Block (0, // size
1034 ACE_Message_Type (0), // type
1038 0, // locking strategy
1040 current
->priority_
, // priority
1043 // Get a pointer to a
1044 // "duplicated" <ACE_Data_Block>
1045 // (will simply increment the
1046 // reference count).
1047 current
->data_block ()->duplicate (),
1048 current
->data_block ()->data_block_allocator (),
1049 current
->message_block_allocator_
));
1050 else // Otherwise, use the message_block_allocator passed in.
1051 ACE_NEW_MALLOC_NORETURN (cur_dup
,
1052 static_cast<ACE_Message_Block
*> (
1053 current
->message_block_allocator_
->malloc (sizeof (ACE_Message_Block
))),
1054 ACE_Message_Block (0, // size
1055 ACE_Message_Type (0), // type
1059 0, // locking strategy
1061 current
->priority_
, // priority
1064 // Get a pointer to a
1065 // "duplicated" <ACE_Data_Block>
1066 // (will simply increment the
1067 // reference count).
1068 current
->data_block ()->duplicate (),
1069 current
->data_block ()->data_block_allocator (),
1070 current
->message_block_allocator_
));
1073 // If allocation failed above, release everything done so far and return NULL
1083 // Set the read and write pointers in the new <Message_Block> to the
1084 // same relative offset as in the existing <Message_Block>. Note
1085 // that we are assuming that the data_block()->base() pointer
1086 // doesn't change when it's duplicated.
1087 cur_dup
->rd_ptr (current
->rd_ptr_
);
1088 cur_dup
->wr_ptr (current
->wr_ptr_
);
1092 /* First in the list: set leading pointers */
1093 nb_top
= nb
= cur_dup
;
1097 /* Continuing on: append to nb and walk down the list */
1098 nb
->cont_
= cur_dup
;
1102 current
= current
->cont_
;
1109 ACE_Message_Block::duplicate (const ACE_Message_Block
*mb
)
1111 ACE_TRACE ("ACE_Message_Block::duplicate");
1115 return mb
->duplicate ();
1119 ACE_Data_Block::clone (ACE_Message_Block::Message_Flags mask
) const
1121 ACE_TRACE ("ACE_Data_Block::clone");
1123 ACE_Data_Block
*nb
= this->clone_nocopy (mask
);
1125 // Copy all of the payload memory into the new object. The new block
1126 // was allocated with max_size_ (and, thus, it's cur_size_ is the same
1127 // as max_size_). Maintain the same "has been written" boundary in the
1128 // new block by only copying cur_size_ bytes.
1131 ACE_OS::memcpy (nb
->base_
,
1140 ACE_Data_Block::clone_nocopy (ACE_Message_Block::Message_Flags mask
,
1141 size_t max_size
) const
1143 ACE_FUNCTION_TIMEPROBE(ACE_DATA_BLOCK_CLONE_ENTER
);
1145 ACE_TRACE ("ACE_Data_Block::clone_nocopy");
1147 // You always want to clear this one to prevent memory leaks but you
1148 // might add some others later.
1149 const ACE_Message_Block::Message_Flags always_clear
=
1150 ACE_Message_Block::DONT_DELETE
;
1152 const size_t newsize
=
1153 max_size
== 0 ? this->max_size_
: max_size
;
1155 ACE_Data_Block
*nb
= 0;
1157 ACE_NEW_MALLOC_RETURN (nb
,
1158 static_cast<ACE_Data_Block
*> (
1159 this->data_block_allocator_
->malloc (sizeof (ACE_Data_Block
))),
1160 ACE_Data_Block (newsize
, // size
1161 this->type_
, // type
1163 this->allocator_strategy_
, // allocator
1164 this->locking_strategy_
, // locking strategy
1165 this->flags_
, // flags
1166 this->data_block_allocator_
),
1169 // Message block initialization may fail while the construction
1170 // succeds. Since as a matter of policy, ACE may throw no
1171 // exceptions, we have to do a separate check like this.
1172 if (nb
!= 0 && nb
->size () < newsize
)
1174 nb
->ACE_Data_Block::~ACE_Data_Block(); // placement destructor ...
1175 this->data_block_allocator_
->free (nb
); // free ...
1181 // Set new flags minus the mask...
1182 nb
->clr_flags (mask
| always_clear
);
1187 ACE_Message_Block::clone (Message_Flags mask
) const
1189 ACE_TRACE ("ACE_Message_Block::clone");
1191 const ACE_Message_Block
*old_message_block
= this;
1192 ACE_Message_Block
*new_message_block
= 0;
1193 ACE_Message_Block
*new_previous_message_block
= 0;
1194 ACE_Message_Block
*new_root_message_block
= 0;
1198 // Get a pointer to a "cloned"<ACE_Data_Block> (will copy the
1199 // values rather than increment the reference count).
1200 ACE_Data_Block
*db
= old_message_block
->data_block ()->clone (mask
);
1205 if(old_message_block
->message_block_allocator_
== 0)
1207 ACE_NEW_RETURN (new_message_block
,
1208 ACE_Message_Block (0, // size
1209 ACE_Message_Type (0), // type
1213 0, // locking strategy
1215 old_message_block
->priority_
, // priority
1216 ACE_EXECUTION_TIME
, // execution time
1217 ACE_DEADLINE_TIME
, // absolute time to deadline
1218 // Get a pointer to a
1219 // "duplicated"<ACE_Data_Block>
1220 // (will simply increment the
1221 // reference count).
1223 db
->data_block_allocator (),
1224 old_message_block
->message_block_allocator_
),
1229 // This is the ACE_NEW_MALLOC macro with the return check removed.
1230 // We need to do it this way because if it fails we need to release
1231 // the cloned data block that was created above. If we used
1232 // ACE_NEW_MALLOC_RETURN, there would be a memory leak because the
1233 // above db pointer would be left dangling.
1234 new_message_block
= static_cast<ACE_Message_Block
*> (old_message_block
->message_block_allocator_
->malloc (sizeof (ACE_Message_Block
)));
1235 if (new_message_block
!= 0)
1236 new (new_message_block
) ACE_Message_Block (0, // size
1237 ACE_Message_Type (0), // type
1241 0, // locking strategy
1243 old_message_block
->priority_
, // priority
1244 ACE_EXECUTION_TIME
, // execution time
1245 ACE_DEADLINE_TIME
, // absolute time to deadline
1247 db
->data_block_allocator (),
1248 old_message_block
->message_block_allocator_
);
1251 if (new_message_block
== 0)
1257 // Set the read and write pointers in the new <Message_Block> to the
1258 // same relative offset as in the existing <Message_Block>.
1259 new_message_block
->rd_ptr (old_message_block
->rd_ptr_
);
1260 new_message_block
->wr_ptr (old_message_block
->wr_ptr_
);
1261 // save the root message block to return
1262 if (new_root_message_block
== 0)
1263 new_root_message_block
= new_message_block
;
1264 if (new_previous_message_block
!= 0)
1265 // we're a continuation of the previous block, add ourself to its chain
1266 new_previous_message_block
->cont_
= new_message_block
;
1267 new_previous_message_block
= new_message_block
;
1268 old_message_block
= old_message_block
->cont ();
1270 while (old_message_block
!= 0);
1272 return new_root_message_block
;
1277 ACE_Message_Block::operator= (const ACE_Message_Block
&)
1279 ACE_TRACE ("ACE_Message_Block::operator=");
1284 ACE_Data_Block::base (char *msg_data
,
1286 ACE_Message_Block::Message_Flags msg_flags
)
1288 if (ACE_BIT_DISABLED (this->flags_
,
1289 ACE_Message_Block::DONT_DELETE
))
1290 this->allocator_strategy_
->free (this->base_
);
1292 this->max_size_
= msg_length
;
1293 this->cur_size_
= msg_length
;
1294 this->base_
= msg_data
;
1295 this->flags_
= msg_flags
;
1298 ACE_END_VERSIONED_NAMESPACE_DECL