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 ()
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 () 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 () 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 () 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 () const
271 ACE_TRACE ("ACE_Message_Block::total_size");
274 for (const ACE_Message_Block
*i
= this;
283 ACE_Message_Block::total_length () 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 () 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 ()
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
397 nullptr, // allocator
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
403 nullptr, // data block
404 nullptr, // 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
420 nullptr, // allocator
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
426 nullptr, // data block
427 nullptr, // 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
, size_t size
)
499 ACE_TRACE ("ACE_Message_Block::init");
500 // Should we also initialize all the other fields, as well?
502 return this->init_i (size
, // size
506 nullptr, // allocator
507 0, // locking strategy
508 ACE_Message_Block::DONT_DELETE
, // flags
510 ACE_Time_Value::zero
, // execution time
511 ACE_Time_Value::max_time
, // absolute time of deadline
512 nullptr, // data block
513 nullptr, // data_block allocator
514 nullptr); // message_block allocator
517 ACE_Message_Block::ACE_Message_Block (size_t size
,
518 ACE_Message_Type msg_type
,
519 ACE_Message_Block
*msg_cont
,
520 const char *msg_data
,
521 ACE_Allocator
*allocator_strategy
,
522 ACE_Lock
*locking_strategy
,
524 unsigned long priority
,
525 const ACE_Time_Value
&execution_time
,
526 const ACE_Time_Value
&deadline_time
,
528 ACE_Allocator
*data_block_allocator
,
529 ACE_Allocator
*message_block_allocator
)
531 data_block_ (nullptr)
533 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
535 if (this->init_i (size
,
546 data_block_allocator
,
547 message_block_allocator
) == -1)
548 ACELIB_ERROR ((LM_ERROR
,
549 ACE_TEXT ("ACE_Message_Block")));
552 ACE_Message_Block::ACE_Message_Block (ACE_Data_Block
*data_block
,
553 ACE_Message_Block::Message_Flags flags
,
554 ACE_Allocator
*message_block_allocator
)
556 data_block_ (nullptr)
558 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
560 if (this->init_i (0, // size
565 0, // locking strategy
568 ACE_Time_Value::zero
, // execution time
569 ACE_Time_Value::max_time
, // absolute time of deadline
570 data_block
, // data block
571 data_block
->data_block_allocator (),
572 message_block_allocator
) == -1)
573 ACELIB_ERROR ((LM_ERROR
,
574 ACE_TEXT ("ACE_Message_Block")));
577 ACE_Message_Block::ACE_Message_Block (const ACE_Message_Block
&mb
,
580 data_block_ (nullptr)
582 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
584 if (ACE_BIT_DISABLED (mb
.flags_
,
585 ACE_Message_Block::DONT_DELETE
))
587 if (this->init_i (0, // size
591 nullptr, // allocator
592 nullptr, // locking strategy
595 ACE_Time_Value::zero
, // execution time
596 ACE_Time_Value::max_time
, // absolute time of deadline
597 mb
.data_block ()->duplicate (), // data block
598 mb
.data_block ()->data_block_allocator (),
599 mb
.message_block_allocator_
) == -1)
600 ACELIB_ERROR ((LM_ERROR
,
601 ACE_TEXT ("ACE_Message_Block")));
602 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
604 char *start
= ACE_ptr_align_binary (this->base (),
607 char *start
= this->base ();
608 #endif /* ACE_LACKS_CDR_ALIGNMENT */
610 // Set our rd & wr pointers
611 this->rd_ptr (start
);
612 this->wr_ptr (start
);
616 if (this->init_i (0, // size
620 nullptr, // allocator
621 nullptr, // locking strategy
624 ACE_Time_Value::zero
, // execution time
625 ACE_Time_Value::max_time
, // absolute time of deadline
626 mb
.data_block ()->clone_nocopy (),// data block
627 mb
.data_block ()->data_block_allocator (),
628 mb
.message_block_allocator_
) == -1)
629 ACELIB_ERROR ((LM_ERROR
,
630 ACE_TEXT ("ACE_Message_Block")));
632 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
634 char *start
= ACE_ptr_align_binary (this->base (),
637 char *start
= this->base ();
638 #endif /* ACE_LACKS_CDR_ALIGNMENT */
640 // Set our rd & wr pointers
641 this->rd_ptr (start
);
642 this->wr_ptr (start
);
644 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
645 // Get the alignment offset of the incoming ACE_Message_Block
646 start
= ACE_ptr_align_binary (mb
.base (), align
);
649 #endif /* ACE_LACKS_CDR_ALIGNMENT */
651 // Actual offset for the incoming message block assuming that it
652 // is also aligned to the same "align" byte
653 size_t const wr_offset
= mb
.wr_ptr_
- (start
- mb
.base ());
655 // Copy wr_offset amount of data in to <this->data_block>
656 (void) ACE_OS::memcpy (this->wr_ptr (),
660 // Don't move the write pointer, just leave it to the application
661 // to do what it wants
663 #if defined (ACE_LACKS_CDR_ALIGNMENT)
664 ACE_UNUSED_ARG (align
);
665 #endif /* ACE_LACKS_CDR_ALIGNMENT */
669 ACE_Message_Block::init_i (size_t size
,
670 ACE_Message_Type msg_type
,
671 ACE_Message_Block
*msg_cont
,
672 const char *msg_data
,
673 ACE_Allocator
*allocator_strategy
,
674 ACE_Lock
*locking_strategy
,
676 unsigned long priority
,
677 const ACE_Time_Value
&execution_time
,
678 const ACE_Time_Value
&deadline_time
,
680 ACE_Allocator
*data_block_allocator
,
681 ACE_Allocator
*message_block_allocator
)
683 ACE_TRACE ("ACE_Message_Block::init_i");
684 ACE_FUNCTION_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_ENTER
);
688 this->priority_
= priority
;
689 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
690 this->execution_time_
= execution_time
;
691 this->deadline_time_
= deadline_time
;
693 ACE_UNUSED_ARG (execution_time
);
694 ACE_UNUSED_ARG (deadline_time
);
695 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
696 this->cont_
= msg_cont
;
697 this->next_
= nullptr;
698 this->prev_
= nullptr;
700 this->message_block_allocator_
= message_block_allocator
;
702 if (this->data_block_
!= 0)
704 this->data_block_
->release ();
705 this->data_block_
= 0;
710 if (data_block_allocator
== 0)
711 ACE_ALLOCATOR_RETURN (data_block_allocator
,
712 ACE_Allocator::instance (),
715 ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC
);
717 // Allocate the <ACE_Data_Block> portion, which is reference
719 ACE_NEW_MALLOC_RETURN (db
,
720 static_cast<ACE_Data_Block
*> (
721 data_block_allocator
->malloc (sizeof (ACE_Data_Block
))),
722 ACE_Data_Block (size
,
728 data_block_allocator
),
730 ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_CTOR
);
732 // Message block initialization may fail, while the construction
733 // succeeds. Since ACE may throw no exceptions, we have to do a
734 // separate check and clean up, like this:
735 if (db
!= 0 && db
->size () < size
)
737 db
->ACE_Data_Block::~ACE_Data_Block(); // placement destructor ...
738 data_block_allocator
->free (db
); // free ...
744 // Reset the data_block_ pointer.
745 this->data_block (db
);
750 ACE_Data_Block::~ACE_Data_Block ()
753 ACE_ASSERT (this->reference_count_
<= 1);
755 // Just to be safe...
756 this->reference_count_
= 0;
758 if (ACE_BIT_DISABLED (this->flags_
,
759 ACE_Message_Block::DONT_DELETE
))
761 this->allocator_strategy_
->free ((void *) this->base_
);
762 this->base_
= nullptr;
767 ACE_Data_Block::release_i ()
769 ACE_TRACE ("ACE_Data_Block::release_i");
771 ACE_ASSERT (this->reference_count_
> 0);
773 ACE_Data_Block
*result
= nullptr;
775 // decrement reference count
776 --this->reference_count_
;
778 if (this->reference_count_
== 0)
779 // this will cause deletion of this
788 ACE_Data_Block::release_no_delete (ACE_Lock
*lock
)
790 ACE_TRACE ("ACE_Data_Block::release_no_delete");
792 ACE_Data_Block
*result
= nullptr;
793 ACE_Lock
*lock_to_be_used
= nullptr;
795 // Check if we were passed in a lock
798 // Make sure that the lock passed in and our lock are the same
799 if (lock
== this->locking_strategy_
)
800 // In this case no locking is required.
803 // The lock passed in does not match our lock
805 // Lock to be used is our lock
806 lock_to_be_used
= this->locking_strategy_
;
808 // This is the case when no lock was passed in
811 // Lock to be used is our lock
812 lock_to_be_used
= this->locking_strategy_
;
815 // If there's a locking strategy then we need to acquire the lock
816 // before decrementing the count.
817 if (lock_to_be_used
!= 0)
819 ACE_GUARD_RETURN (ACE_Lock
, ace_mon
, *lock_to_be_used
, 0);
821 result
= this->release_i ();
825 result
= this->release_i ();
832 ACE_Data_Block::release (ACE_Lock
*lock
)
834 ACE_TRACE ("ACE_Data_Block::release");
836 ACE_Allocator
*allocator
= this->data_block_allocator_
;
838 ACE_Data_Block
*result
= this->release_no_delete (lock
);
840 // We must delete this outside the scope of the locking_strategy_
841 // since otherwise we'd be trying to "release" through a deleted
843 if (result
== nullptr)
844 ACE_DES_FREE_THIS (allocator
->free
,
850 ACE_Message_Block::release ()
852 ACE_TRACE ("ACE_Message_Block::release");
854 // We want to hold the data block in a temporary variable because we
855 // invoked "delete this;" at some point, so using this->data_block_
856 // could be a bad idea.
857 ACE_Data_Block
*tmp
= this->data_block ();
859 // This flag is set to 1 when we have to destroy the data_block
860 int destroy_dblock
= 0;
864 // Do we have a valid data block
865 if (this->data_block ())
867 // Grab the lock that belongs to my data block
868 lock
= this->data_block ()->locking_strategy ();
874 ACE_GUARD_RETURN (ACE_Lock
, ace_mon
, *lock
, 0);
876 // Call non-guarded release with @a lock
877 destroy_dblock
= this->release_i (lock
);
879 // This is the case when we have a valid data block but no lock
881 // Call non-guarded release with no lock
882 destroy_dblock
= this->release_i (0);
885 // This is the case when we don't even have a valid data block
886 destroy_dblock
= this->release_i (0);
888 if (destroy_dblock
!= 0)
890 ACE_Allocator
*allocator
= tmp
->data_block_allocator ();
900 ACE_Message_Block::release_i (ACE_Lock
*lock
)
902 ACE_TRACE ("ACE_Message_Block::release_i");
904 // Free up all the continuation messages.
907 ACE_Message_Block
*mb
= this->cont_
;
908 ACE_Message_Block
*tmp
= nullptr;
916 ACE_Data_Block
*db
= tmp
->data_block ();
917 if (tmp
->release_i (lock
) != 0)
919 ACE_Allocator
*allocator
= db
->data_block_allocator ();
932 if (ACE_BIT_DISABLED (this->flags_
,
933 ACE_Message_Block::DONT_DELETE
) &&
936 if (this->data_block ()->release_no_delete (lock
) == 0)
938 this->data_block_
= nullptr;
941 // We will now commit suicide: this object *must* have come from the
943 if (this->message_block_allocator_
== nullptr)
947 ACE_Allocator
*allocator
= this->message_block_allocator_
;
948 ACE_DES_FREE_THIS (allocator
->free
,
955 /* static */ ACE_Message_Block
*
956 ACE_Message_Block::release (ACE_Message_Block
*mb
)
958 ACE_TRACE ("ACE_Message_Block::release");
961 return mb
->release ();
966 ACE_Message_Block::~ACE_Message_Block ()
968 ACE_TRACE ("ACE_Message_Block::~ACE_Message_Block");
970 if (ACE_BIT_DISABLED (this->flags_
, ACE_Message_Block::DONT_DELETE
) &&
973 this->data_block ()->release ();
976 this->prev_
= nullptr;
977 this->next_
= nullptr;
978 this->cont_
= nullptr;
982 ACE_Data_Block::duplicate ()
984 ACE_TRACE ("ACE_Data_Block::duplicate");
986 // Create a new <ACE_Message_Block>, but share the <base_> pointer
987 // data (i.e., don't copy that).
988 if (this->locking_strategy_
)
990 // We need to acquire the lock before incrementing the count.
991 ACE_GUARD_RETURN (ACE_Lock
, ace_mon
, *this->locking_strategy_
, 0);
992 ++this->reference_count_
;
995 ++this->reference_count_
;
1000 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
1001 #define ACE_EXECUTION_TIME this->execution_time_
1002 #define ACE_DEADLINE_TIME this->deadline_time_
1004 #define ACE_EXECUTION_TIME ACE_Time_Value::zero
1005 #define ACE_DEADLINE_TIME ACE_Time_Value::max_time
1006 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
1009 ACE_Message_Block::duplicate () const
1011 ACE_TRACE ("ACE_Message_Block::duplicate");
1013 ACE_Message_Block
*nb_top
= nullptr;
1014 ACE_Message_Block
*nb
= nullptr;
1015 const ACE_Message_Block
*current
= this;
1017 // Increment the reference counts of all the continuation messages.
1020 ACE_Message_Block
* cur_dup
= 0;
1022 // Create a new <ACE_Message_Block> that contains unique copies of
1023 // the message block fields, but a reference counted duplicate of
1024 // the <ACE_Data_Block>.
1026 // If there is no allocator, use the standard new and delete calls.
1027 if (current
->message_block_allocator_
== 0)
1028 ACE_NEW_NORETURN (cur_dup
,
1029 ACE_Message_Block (0, // size
1030 ACE_Message_Type (0), // type
1033 nullptr, // allocator
1034 nullptr, // locking strategy
1036 current
->priority_
, // priority
1039 // Get a pointer to a
1040 // "duplicated" <ACE_Data_Block>
1041 // (will simply increment the
1042 // reference count).
1043 current
->data_block ()->duplicate (),
1044 current
->data_block ()->data_block_allocator (),
1045 current
->message_block_allocator_
));
1046 else // Otherwise, use the message_block_allocator passed in.
1047 ACE_NEW_MALLOC_NORETURN (cur_dup
,
1048 static_cast<ACE_Message_Block
*> (
1049 current
->message_block_allocator_
->malloc (sizeof (ACE_Message_Block
))),
1050 ACE_Message_Block (0, // size
1051 ACE_Message_Type (0), // type
1054 nullptr, // allocator
1055 nullptr, // locking strategy
1057 current
->priority_
, // priority
1060 // Get a pointer to a
1061 // "duplicated" <ACE_Data_Block>
1062 // (will simply increment the
1063 // reference count).
1064 current
->data_block ()->duplicate (),
1065 current
->data_block ()->data_block_allocator (),
1066 current
->message_block_allocator_
));
1069 // If allocation failed above, release everything done so far and return NULL
1079 // Set the read and write pointers in the new <Message_Block> to the
1080 // same relative offset as in the existing <Message_Block>. Note
1081 // that we are assuming that the data_block()->base() pointer
1082 // doesn't change when it's duplicated.
1083 cur_dup
->rd_ptr (current
->rd_ptr_
);
1084 cur_dup
->wr_ptr (current
->wr_ptr_
);
1088 /* First in the list: set leading pointers */
1089 nb_top
= nb
= cur_dup
;
1093 /* Continuing on: append to nb and walk down the list */
1094 nb
->cont_
= cur_dup
;
1098 current
= current
->cont_
;
1105 ACE_Message_Block::duplicate (const ACE_Message_Block
*mb
)
1107 ACE_TRACE ("ACE_Message_Block::duplicate");
1111 return mb
->duplicate ();
1115 ACE_Data_Block::clone (ACE_Message_Block::Message_Flags mask
) const
1117 ACE_TRACE ("ACE_Data_Block::clone");
1119 ACE_Data_Block
*nb
= this->clone_nocopy (mask
);
1121 // Copy all of the payload memory into the new object. The new block
1122 // was allocated with max_size_ (and, thus, it's cur_size_ is the same
1123 // as max_size_). Maintain the same "has been written" boundary in the
1124 // new block by only copying cur_size_ bytes.
1127 ACE_OS::memcpy (nb
->base_
,
1136 ACE_Data_Block::clone_nocopy (ACE_Message_Block::Message_Flags mask
,
1137 size_t max_size
) const
1139 ACE_FUNCTION_TIMEPROBE(ACE_DATA_BLOCK_CLONE_ENTER
);
1141 ACE_TRACE ("ACE_Data_Block::clone_nocopy");
1143 // You always want to clear this one to prevent memory leaks but you
1144 // might add some others later.
1145 const ACE_Message_Block::Message_Flags always_clear
= ACE_Message_Block::DONT_DELETE
;
1146 const size_t newsize
= max_size
== 0 ? this->max_size_
: max_size
;
1147 ACE_Data_Block
*nb
= nullptr;
1149 ACE_NEW_MALLOC_RETURN (nb
,
1150 static_cast<ACE_Data_Block
*> (
1151 this->data_block_allocator_
->malloc (sizeof (ACE_Data_Block
))),
1152 ACE_Data_Block (newsize
, // size
1153 this->type_
, // type
1155 this->allocator_strategy_
, // allocator
1156 this->locking_strategy_
, // locking strategy
1157 this->flags_
, // flags
1158 this->data_block_allocator_
),
1161 // Message block initialization may fail while the construction
1162 // succeeds. Since as a matter of policy, ACE may throw no
1163 // exceptions, we have to do a separate check like this.
1164 if (nb
!= 0 && nb
->size () < newsize
)
1166 nb
->ACE_Data_Block::~ACE_Data_Block(); // placement destructor ...
1167 this->data_block_allocator_
->free (nb
); // free ...
1172 // Set new flags minus the mask...
1173 nb
->clr_flags (mask
| always_clear
);
1178 ACE_Message_Block::clone (Message_Flags mask
) const
1180 ACE_TRACE ("ACE_Message_Block::clone");
1182 const ACE_Message_Block
*old_message_block
= this;
1183 ACE_Message_Block
*new_message_block
{};
1184 ACE_Message_Block
*new_previous_message_block
{};
1185 ACE_Message_Block
*new_root_message_block
{};
1189 // Get a pointer to a "cloned" ACE_Data_Block (will copy the
1190 // values rather than increment the reference count).
1191 ACE_Data_Block
*db
= old_message_block
->data_block ()->clone (mask
);
1196 if(old_message_block
->message_block_allocator_
== nullptr)
1198 ACE_NEW_NORETURN (new_message_block
,
1199 ACE_Message_Block (0, // size
1200 ACE_Message_Type (0), // type
1203 nullptr, // allocator
1204 nullptr, // locking strategy
1206 old_message_block
->priority_
, // priority
1207 ACE_EXECUTION_TIME
, // execution time
1208 ACE_DEADLINE_TIME
, // absolute time to deadline
1209 // Get a pointer to a
1210 // "duplicated"<ACE_Data_Block>
1211 // (will simply increment the
1212 // reference count).
1214 db
->data_block_allocator (),
1215 old_message_block
->message_block_allocator_
));
1219 // This is the ACE_NEW_MALLOC macro with the return check removed.
1220 // We need to do it this way because if it fails we need to release
1221 // the cloned data block that was created above. If we used
1222 // ACE_NEW_MALLOC_RETURN, there would be a memory leak because the
1223 // above db pointer would be left dangling.
1224 new_message_block
= static_cast<ACE_Message_Block
*> (old_message_block
->message_block_allocator_
->malloc (sizeof (ACE_Message_Block
)));
1225 if (new_message_block
!= nullptr)
1226 new (new_message_block
) ACE_Message_Block (0, // size
1227 ACE_Message_Type (0), // type
1230 nullptr, // allocator
1231 nullptr, // locking strategy
1233 old_message_block
->priority_
, // priority
1234 ACE_EXECUTION_TIME
, // execution time
1235 ACE_DEADLINE_TIME
, // absolute time to deadline
1237 db
->data_block_allocator (),
1238 old_message_block
->message_block_allocator_
);
1241 if (new_message_block
== nullptr)
1247 // Set the read and write pointers in the new <Message_Block> to the
1248 // same relative offset as in the existing <Message_Block>.
1249 new_message_block
->rd_ptr (old_message_block
->rd_ptr_
);
1250 new_message_block
->wr_ptr (old_message_block
->wr_ptr_
);
1251 // save the root message block to return
1252 if (new_root_message_block
== nullptr)
1253 new_root_message_block
= new_message_block
;
1254 if (new_previous_message_block
!= nullptr)
1255 // we're a continuation of the previous block, add ourself to its chain
1256 new_previous_message_block
->cont_
= new_message_block
;
1257 new_previous_message_block
= new_message_block
;
1258 old_message_block
= old_message_block
->cont ();
1260 while (old_message_block
!= nullptr);
1262 return new_root_message_block
;
1267 ACE_Message_Block::operator= (const ACE_Message_Block
&)
1269 ACE_TRACE ("ACE_Message_Block::operator=");
1274 ACE_Data_Block::base (char *msg_data
,
1276 ACE_Message_Block::Message_Flags msg_flags
)
1278 if (ACE_BIT_DISABLED (this->flags_
,
1279 ACE_Message_Block::DONT_DELETE
))
1280 this->allocator_strategy_
->free (this->base_
);
1282 this->max_size_
= msg_length
;
1283 this->cur_size_
= msg_length
;
1284 this->base_
= msg_data
;
1285 this->flags_
= msg_flags
;
1288 ACE_END_VERSIONED_NAMESPACE_DECL