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_Msg.h"
9 #include "ace/Malloc_Base.h"
10 #include "ace/OS_NS_string.h"
12 //#define ACE_ENABLE_TIMEPROBES
13 #include "ace/Timeprobe.h"
17 "$Id: Message_Block.cpp 80826 2008-03-04 14:51:23Z wotte $")
19 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
21 ACE_ALLOC_HOOK_DEFINE (ACE_Message_Block
)
23 #if defined (ACE_ENABLE_TIMEPROBES)
25 static const char *ACE_MB_Timeprobe_Description
[] =
27 "Message_Block::init_i - enter",
28 "Message_Block::init_i - leave",
29 "Message_Block::init_i - db alloc",
30 "Message_Block::init_i - db ctor",
31 "Data_Block::ctor[1] - enter",
32 "Data_Block::ctor[1] - leave",
33 "Data_Block::ctor[2] - enter",
34 "Data_Block::ctor[2] - leave",
35 "Data_Block::clone - enter",
36 "Data_Block::clone - leave"
41 ACE_MESSAGE_BLOCK_INIT_I_ENTER
= 3000,
42 ACE_MESSAGE_BLOCK_INIT_I_LEAVE
,
43 ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC
,
44 ACE_MESSAGE_BLOCK_INIT_I_DB_CTOR
,
45 ACE_DATA_BLOCK_CTOR1_ENTER
,
46 ACE_DATA_BLOCK_CTOR1_LEAVE
,
47 ACE_DATA_BLOCK_CTOR2_ENTER
,
48 ACE_DATA_BLOCK_CTOR2_LEAVE
,
49 ACE_DATA_BLOCK_CLONE_ENTER
,
50 ACE_DATA_BLOCK_CLONE_LEAVE
55 ACE_TIMEPROBE_EVENT_DESCRIPTIONS (ACE_MB_Timeprobe_Description
,
56 ACE_MESSAGE_BLOCK_INIT_I_ENTER
);
58 #endif /* ACE_ENABLE_TIMEPROBES */
61 ACE_Message_Block::data_block (ACE_Data_Block
*db
)
63 ACE_TRACE ("ACE_Message_Block::data_block");
64 if (ACE_BIT_DISABLED (this->flags_
,
65 ACE_Message_Block::DONT_DELETE
)
66 && this->data_block_
!= 0)
67 this->data_block_
->release ();
69 this->data_block_
= db
;
71 // Set the read and write pointers in the <Message_Block> to point
72 // to the buffer in the <ACE_Data_Block>.
73 this->rd_ptr (this->data_block ()->base ());
74 this->wr_ptr (this->data_block ()->base ());
78 ACE_Message_Block::copy (const char *buf
, size_t n
)
80 ACE_TRACE ("ACE_Message_Block::copy");
82 /*size_t len = static_cast<size_t> (this->end () - this->wr_ptr ());*/
83 // Note that for this to work correct, end () *must* be >= mark ().
84 size_t len
= this->space ();
93 (void) ACE_OS::memcpy (this->wr_ptr (),
102 ACE_Message_Block::copy (const char *buf
)
104 ACE_TRACE ("ACE_Message_Block::copy");
106 /* size_t len = static_cast<size_t> (this->end () - this->wr_ptr ()); */
107 // Note that for this to work correct, end() *must* be >= wr_ptr().
108 size_t len
= this->space ();
110 size_t buflen
= ACE_OS::strlen (buf
) + 1;
119 (void) ACE_OS::memcpy (this->wr_ptr (),
122 this->wr_ptr (buflen
);
128 ACE_Message_Block::crunch (void)
130 if (this->rd_ptr_
!= 0)
132 if (this->rd_ptr_
> this->wr_ptr_
)
135 size_t const len
= this->length ();
136 (void) ACE_OS::memmove (this->base (),
139 this->rd_ptr (this->base ());
140 this->wr_ptr (this->base () + len
);
146 ACE_Data_Block::dump (void) const
148 #if defined (ACE_HAS_DUMP)
149 ACE_TRACE ("ACE_Data_Block::dump");
150 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
151 ACE_DEBUG ((LM_DEBUG
,
152 ACE_TEXT ("-----( Data Block )-----\n")
153 ACE_TEXT ("type_ = %d\n")
154 ACE_TEXT ("cur_size_ = %u\n")
155 ACE_TEXT ("max_size_ = %u\n")
156 ACE_TEXT ("flags_ = %u\n")
157 ACE_TEXT ("base_ = %u\n")
158 ACE_TEXT ("locking_strategy_ = %u\n")
159 ACE_TEXT ("reference_count_ = %u\n")
160 ACE_TEXT ("---------------------------\n"),
166 this->locking_strategy_
,
167 this->reference_count_
));
168 this->allocator_strategy_
->dump ();
169 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
170 #endif /* ACE_HAS_DUMP */
174 ACE_Message_Block::dump (void) const
176 #if defined (ACE_HAS_DUMP)
177 ACE_TRACE ("ACE_Message_Block::dump");
178 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
179 ACE_DEBUG ((LM_DEBUG
,
180 ACE_TEXT ("-----( Message Block )-----\n")
181 ACE_TEXT ("priority_ = %d\n")
182 ACE_TEXT ("next_ = %u\n")
183 ACE_TEXT ("prev_ = %u\n")
184 ACE_TEXT ("cont_ = %u\n")
185 ACE_TEXT ("rd_ptr_ = %u\n")
186 ACE_TEXT ("wr_ptr_ = %u\n")
187 ACE_TEXT ("---------------------------\n"),
194 this->data_block ()->dump ();
195 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
196 #endif /* ACE_HAS_DUMP */
200 ACE_Data_Block::reference_count (void) const
202 if (this->locking_strategy_
)
204 // We need to acquire the lock before retrieving the count
205 ACE_GUARD_RETURN (ACE_Lock
, ace_mon
, *this->locking_strategy_
, 0);
207 return this->reference_count_i ();
210 return this->reference_count_i ();
214 ACE_Data_Block::size (size_t length
)
216 ACE_TRACE ("ACE_Data_Block::size");
218 if (length
<= this->max_size_
)
219 this->cur_size_
= length
;
222 // We need to resize!
224 ACE_ALLOCATOR_RETURN (buf
,
225 (char *) this->allocator_strategy_
->malloc (length
),
231 if (ACE_BIT_DISABLED (this->flags_
,
232 ACE_Message_Block::DONT_DELETE
))
233 this->allocator_strategy_
->free ((void *) this->base_
);
235 // We now assume ownership.
236 ACE_CLR_BITS (this->flags_
,
237 ACE_Message_Block::DONT_DELETE
);
238 this->max_size_
= length
;
239 this->cur_size_
= length
;
246 ACE_Message_Block::size (size_t length
)
248 ACE_TRACE ("ACE_Message_Block::size");
250 // Resize the underlying <ACE_Data_Block>.
251 if (this->data_block ()->size (length
) == -1)
258 ACE_Message_Block::total_size_and_length (size_t &mb_size
,
259 size_t &mb_length
) const
261 ACE_TRACE ("ACE_Message_Block::total_size_and_length");
263 for (const ACE_Message_Block
*i
= this;
267 mb_size
+= i
->size ();
268 mb_length
+= i
->length ();
273 ACE_Message_Block::total_size (void) const
275 ACE_TRACE ("ACE_Message_Block::total_size");
278 for (const ACE_Message_Block
*i
= this;
287 ACE_Message_Block::total_length (void) const
289 ACE_TRACE ("ACE_Message_Block::total_length");
292 for (const ACE_Message_Block
*i
= this;
295 length
+= i
->length ();
301 ACE_Message_Block::total_capacity (void) const
303 ACE_TRACE ("ACE_Message_Block::total_capacity");
307 for (const ACE_Message_Block
*i
= this;
310 size
+= i
->capacity ();
315 ACE_Data_Block::ACE_Data_Block (void)
316 : type_ (ACE_Message_Block::MB_DATA
),
319 flags_ (ACE_Message_Block::DONT_DELETE
),
321 allocator_strategy_ (0),
322 locking_strategy_ (0),
323 reference_count_ (1),
324 data_block_allocator_ (0)
326 ACE_TRACE ("ACE_Data_Block::ACE_Data_Block");
327 ACE_FUNCTION_TIMEPROBE (ACE_DATA_BLOCK_CTOR1_ENTER
);
329 ACE_ALLOCATOR (this->allocator_strategy_
,
330 ACE_Allocator::instance ());
332 ACE_ALLOCATOR (this->data_block_allocator_
,
333 ACE_Allocator::instance ());
336 ACE_Data_Block::ACE_Data_Block (size_t size
,
337 ACE_Message_Block::ACE_Message_Type msg_type
,
338 const char *msg_data
,
339 ACE_Allocator
*allocator_strategy
,
340 ACE_Lock
*locking_strategy
,
341 ACE_Message_Block::Message_Flags flags
,
342 ACE_Allocator
*data_block_allocator
)
344 cur_size_ (0), // Reset later if memory alloc'd ok
347 base_ (const_cast <char *> (msg_data
)),
348 allocator_strategy_ (allocator_strategy
),
349 locking_strategy_ (locking_strategy
),
350 reference_count_ (1),
351 data_block_allocator_ (data_block_allocator
)
353 ACE_TRACE ("ACE_Data_Block::ACE_Data_Block");
354 ACE_FUNCTION_TIMEPROBE (ACE_DATA_BLOCK_CTOR2_ENTER
);
356 // If the user didn't pass one in, let's use the
357 // <ACE_Allocator::instance>.
358 if (this->allocator_strategy_
== 0)
359 ACE_ALLOCATOR (this->allocator_strategy_
,
360 ACE_Allocator::instance ());
362 if (this->data_block_allocator_
== 0)
363 ACE_ALLOCATOR (this->data_block_allocator_
,
364 ACE_Allocator::instance ());
368 ACE_ALLOCATOR (this->base_
,
369 (char *) this->allocator_strategy_
->malloc (size
));
370 #if defined (ACE_INITIALIZE_MEMORY_BEFORE_USE)
371 (void) ACE_OS::memset (this->base_
,
374 #endif /* ACE_INITIALIZE_MEMORY_BEFORE_USE */
377 // ACE_ALLOCATOR returns on alloc failure but we cant throw, so setting
378 // the size to 0 (i.e. "bad bit") ...
379 if (this->base_
== 0)
384 // The memory is legit, whether passed in or allocated, so set
386 this->cur_size_
= this->max_size_
= size
;
389 ACE_Message_Block::ACE_Message_Block (const char *data
,
391 unsigned long priority
)
395 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
397 if (this->init_i (size
, // size
402 0, // locking strategy
403 ACE_Message_Block::DONT_DELETE
, // flags
404 priority
, // priority
405 ACE_Time_Value::zero
, // execution time
406 ACE_Time_Value::max_time
, // absolute time of deadline
408 0, // data_block allocator
409 0) == -1) // message_block allocator
410 ACE_ERROR ((LM_ERROR
,
411 ACE_TEXT ("ACE_Message_Block")));
414 ACE_Message_Block::ACE_Message_Block (ACE_Allocator
*message_block_allocator
)
418 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
420 if (this->init_i (0, // size
425 0, // locking strategy
426 ACE_Message_Block::DONT_DELETE
, // flags
428 ACE_Time_Value::zero
, // execution time
429 ACE_Time_Value::max_time
, // absolute time of deadline
431 0, // data_block allocator
432 message_block_allocator
) == -1) // message_block allocator
433 ACE_ERROR ((LM_ERROR
,
434 ACE_TEXT ("ACE_Message_Block")));
437 ACE_Message_Block::ACE_Message_Block (size_t size
,
438 ACE_Message_Type msg_type
,
439 ACE_Message_Block
*msg_cont
,
440 const char *msg_data
,
441 ACE_Allocator
*allocator_strategy
,
442 ACE_Lock
*locking_strategy
,
443 unsigned long priority
,
444 const ACE_Time_Value
&execution_time
,
445 const ACE_Time_Value
&deadline_time
,
446 ACE_Allocator
*data_block_allocator
,
447 ACE_Allocator
*message_block_allocator
)
451 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
453 if (this->init_i (size
,
459 msg_data
? ACE_Message_Block::DONT_DELETE
: 0,
464 data_block_allocator
,
465 message_block_allocator
) == -1)
466 ACE_ERROR ((LM_ERROR
,
467 ACE_TEXT ("ACE_Message_Block")));
471 ACE_Message_Block::init (size_t size
,
472 ACE_Message_Type msg_type
,
473 ACE_Message_Block
*msg_cont
,
474 const char *msg_data
,
475 ACE_Allocator
*allocator_strategy
,
476 ACE_Lock
*locking_strategy
,
477 unsigned long priority
,
478 const ACE_Time_Value
&execution_time
,
479 const ACE_Time_Value
&deadline_time
,
480 ACE_Allocator
*data_block_allocator
,
481 ACE_Allocator
*message_block_allocator
)
483 ACE_TRACE ("ACE_Message_Block::init");
485 return this->init_i (size
,
491 msg_data
? ACE_Message_Block::DONT_DELETE
: 0,
496 data_block_allocator
,
497 message_block_allocator
);
501 ACE_Message_Block::init (const char *data
,
504 ACE_TRACE ("ACE_Message_Block::init");
505 // Should we also initialize all the other fields, as well?
507 return this->init_i (size
, // size
512 0, // locking strategy
513 ACE_Message_Block::DONT_DELETE
, // flags
515 ACE_Time_Value::zero
, // execution time
516 ACE_Time_Value::max_time
, // absolute time of deadline
518 0, // data_block allocator
519 0); // message_block allocator
522 ACE_Message_Block::ACE_Message_Block (size_t size
,
523 ACE_Message_Type msg_type
,
524 ACE_Message_Block
*msg_cont
,
525 const char *msg_data
,
526 ACE_Allocator
*allocator_strategy
,
527 ACE_Lock
*locking_strategy
,
529 unsigned long priority
,
530 const ACE_Time_Value
&execution_time
,
531 const ACE_Time_Value
&deadline_time
,
533 ACE_Allocator
*data_block_allocator
,
534 ACE_Allocator
*message_block_allocator
)
538 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
540 if (this->init_i (size
,
551 data_block_allocator
,
552 message_block_allocator
) == -1)
553 ACE_ERROR ((LM_ERROR
,
554 ACE_TEXT ("ACE_Message_Block")));
557 ACE_Message_Block::ACE_Message_Block (ACE_Data_Block
*data_block
,
558 ACE_Message_Block::Message_Flags flags
,
559 ACE_Allocator
*message_block_allocator
)
563 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
565 if (this->init_i (0, // size
570 0, // locking strategy
573 ACE_Time_Value::zero
, // execution time
574 ACE_Time_Value::max_time
, // absolute time of deadline
575 data_block
, // data block
576 data_block
->data_block_allocator (),
577 message_block_allocator
) == -1)
578 ACE_ERROR ((LM_ERROR
,
579 ACE_TEXT ("ACE_Message_Block")));
582 ACE_Message_Block::ACE_Message_Block (const ACE_Message_Block
&mb
,
587 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
589 if (ACE_BIT_DISABLED (mb
.flags_
,
590 ACE_Message_Block::DONT_DELETE
))
592 if (this->init_i (0, // size
597 0, // locking strategy
600 ACE_Time_Value::zero
, // execution time
601 ACE_Time_Value::max_time
, // absolute time of deadline
602 mb
.data_block ()->duplicate (), // data block
603 mb
.data_block ()->data_block_allocator (),
604 mb
.message_block_allocator_
) == -1)
605 ACE_ERROR ((LM_ERROR
,
606 ACE_TEXT ("ACE_Message_Block")));
607 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
609 char *start
= ACE_ptr_align_binary (this->base (),
612 char *start
= this->base ();
613 #endif /* ACE_LACKS_CDR_ALIGNMENT */
615 // Set our rd & wr pointers
616 this->rd_ptr (start
);
617 this->wr_ptr (start
);
622 if (this->init_i (0, // size
627 0, // locking strategy
630 ACE_Time_Value::zero
, // execution time
631 ACE_Time_Value::max_time
, // absolute time of deadline
632 mb
.data_block ()->clone_nocopy (),// data block
633 mb
.data_block ()->data_block_allocator (),
634 mb
.message_block_allocator_
) == -1)
635 ACE_ERROR ((LM_ERROR
,
636 ACE_TEXT ("ACE_Message_Block")));
638 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
640 char *start
= ACE_ptr_align_binary (this->base (),
643 char *start
= this->base ();
644 #endif /* ACE_LACKS_CDR_ALIGNMENT */
646 // Set our rd & wr pointers
647 this->rd_ptr (start
);
648 this->wr_ptr (start
);
650 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
651 // Get the alignment offset of the incoming ACE_Message_Block
652 start
= ACE_ptr_align_binary (mb
.base (),
656 #endif /* ACE_LACKS_CDR_ALIGNMENT */
658 // Actual offset for the incoming message block assuming that it
659 // is also aligned to the same "align" byte
660 size_t const wr_offset
= mb
.wr_ptr_
- (start
- mb
.base ());
662 // Copy wr_offset amount of data in to <this->data_block>
663 (void) ACE_OS::memcpy (this->wr_ptr (),
667 // Dont move the write pointer, just leave it to the application
668 // to do what it wants
671 #if defined (ACE_LACKS_CDR_ALIGNMENT)
672 ACE_UNUSED_ARG (align
);
673 #endif /* ACE_LACKS_CDR_ALIGNMENT */
677 ACE_Message_Block::init_i (size_t size
,
678 ACE_Message_Type msg_type
,
679 ACE_Message_Block
*msg_cont
,
680 const char *msg_data
,
681 ACE_Allocator
*allocator_strategy
,
682 ACE_Lock
*locking_strategy
,
684 unsigned long priority
,
685 const ACE_Time_Value
&execution_time
,
686 const ACE_Time_Value
&deadline_time
,
688 ACE_Allocator
*data_block_allocator
,
689 ACE_Allocator
*message_block_allocator
)
691 ACE_TRACE ("ACE_Message_Block::init_i");
692 ACE_FUNCTION_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_ENTER
);
696 this->priority_
= priority
;
697 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
698 this->execution_time_
= execution_time
;
699 this->deadline_time_
= deadline_time
;
701 ACE_UNUSED_ARG (execution_time
);
702 ACE_UNUSED_ARG (deadline_time
);
703 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
704 this->cont_
= msg_cont
;
708 this->message_block_allocator_
= message_block_allocator
;
710 if (this->data_block_
!= 0)
712 this->data_block_
->release ();
713 this->data_block_
= 0;
718 if (data_block_allocator
== 0)
719 ACE_ALLOCATOR_RETURN (data_block_allocator
,
720 ACE_Allocator::instance (),
723 ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC
);
725 // Allocate the <ACE_Data_Block> portion, which is reference
727 ACE_NEW_MALLOC_RETURN (db
,
728 static_cast<ACE_Data_Block
*> (
729 data_block_allocator
->malloc (sizeof (ACE_Data_Block
))),
730 ACE_Data_Block (size
,
736 data_block_allocator
),
738 ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_CTOR
);
740 // Message block initialization may fail, while the construction
741 // succeds. Since ACE may throw no exceptions, we have to do a
742 // separate check and clean up, like this:
743 if (db
!= 0 && db
->size () < size
)
745 db
->ACE_Data_Block::~ACE_Data_Block(); // placement destructor ...
746 data_block_allocator
->free (db
); // free ...
752 // Reset the data_block_ pointer.
753 this->data_block (db
);
758 ACE_Data_Block::~ACE_Data_Block (void)
761 ACE_ASSERT (this->reference_count_
<= 1);
763 // Just to be safe...
764 this->reference_count_
= 0;
766 if (ACE_BIT_DISABLED (this->flags_
,
767 ACE_Message_Block::DONT_DELETE
))
769 this->allocator_strategy_
->free ((void *) this->base_
);
775 ACE_Data_Block::release_i (void)
777 ACE_TRACE ("ACE_Data_Block::release_i");
779 ACE_ASSERT (this->reference_count_
> 0);
781 ACE_Data_Block
*result
= 0;
783 // decrement reference count
784 --this->reference_count_
;
786 if (this->reference_count_
== 0)
787 // this will cause deletion of this
796 ACE_Data_Block::release_no_delete (ACE_Lock
*lock
)
798 ACE_TRACE ("ACE_Data_Block::release_no_delete");
800 ACE_Data_Block
*result
= 0;
801 ACE_Lock
*lock_to_be_used
= 0;
803 // Check if we were passed in a lock
806 // Make sure that the lock passed in and our lock are the same
807 if (lock
== this->locking_strategy_
)
808 // In this case no locking is required.
811 // The lock passed in does not match our lock
813 // Lock to be used is our lock
814 lock_to_be_used
= this->locking_strategy_
;
816 // This is the case when no lock was passed in
818 // Lock to be used is our lock
819 lock_to_be_used
= this->locking_strategy_
;
821 // If there's a locking strategy then we need to acquire the lock
822 // before decrementing the count.
823 if (lock_to_be_used
!= 0)
825 ACE_GUARD_RETURN (ACE_Lock
, ace_mon
, *lock_to_be_used
, 0);
827 result
= this->release_i ();
830 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
855 ACE_Message_Block::release (void)
857 ACE_TRACE ("ACE_Message_Block::release");
859 // We want to hold the data block in a temporary variable because we
860 // invoked "delete this;" at some point, so using this->data_block_
861 // could be a bad idea.
862 ACE_Data_Block
*tmp
= this->data_block ();
864 // This flag is set to 1 when we have to destroy the data_block
865 int destroy_dblock
= 0;
869 // Do we have a valid data block
870 if (this->data_block ())
872 // Grab the lock that belongs to my data block
873 lock
= this->data_block ()->locking_strategy ();
879 ACE_GUARD_RETURN (ACE_Lock
, ace_mon
, *lock
, 0);
881 // Call non-guarded release with <lock>
882 destroy_dblock
= this->release_i (lock
);
884 // This is the case when we have a valid data block but no lock
886 // Call non-guarded release with no lock
887 destroy_dblock
= this->release_i (0);
890 // This is the case when we don't even have a valid data block
891 destroy_dblock
= this->release_i (0);
893 if (destroy_dblock
!= 0)
895 ACE_Allocator
*allocator
= tmp
->data_block_allocator ();
905 ACE_Message_Block::release_i (ACE_Lock
*lock
)
907 ACE_TRACE ("ACE_Message_Block::release_i");
909 // Free up all the continuation messages.
912 ACE_Message_Block
*mb
= this->cont_
;
913 ACE_Message_Block
*tmp
= 0;
921 ACE_Data_Block
*db
= tmp
->data_block ();
922 if (tmp
->release_i (lock
) != 0)
924 ACE_Allocator
*allocator
= db
->data_block_allocator ();
937 if (ACE_BIT_DISABLED (this->flags_
,
938 ACE_Message_Block::DONT_DELETE
) &&
941 if (this->data_block ()->release_no_delete (lock
) == 0)
943 this->data_block_
= 0;
946 // We will now commit suicide: this object *must* have come from the
948 if (this->message_block_allocator_
== 0)
952 ACE_Allocator
*allocator
= this->message_block_allocator_
;
961 /* static */ ACE_Message_Block
*
962 ACE_Message_Block::release (ACE_Message_Block
*mb
)
964 ACE_TRACE ("ACE_Message_Block::release");
967 return mb
->release ();
972 ACE_Message_Block::~ACE_Message_Block (void)
974 ACE_TRACE ("ACE_Message_Block::~ACE_Message_Block");
976 if (ACE_BIT_DISABLED (this->flags_
,
977 ACE_Message_Block::DONT_DELETE
)&&
979 this->data_block ()->release ();
986 ACE_Data_Block::duplicate (void)
988 ACE_TRACE ("ACE_Data_Block::duplicate");
990 // Create a new <ACE_Message_Block>, but share the <base_> pointer
991 // data (i.e., don't copy that).
992 if (this->locking_strategy_
)
994 // We need to acquire the lock before incrementing the count.
995 ACE_GUARD_RETURN (ACE_Lock
, ace_mon
, *this->locking_strategy_
, 0);
996 ++this->reference_count_
;
999 ++this->reference_count_
;
1004 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
1005 #define ACE_EXECUTION_TIME this->execution_time_
1006 #define ACE_DEADLINE_TIME this->deadline_time_
1008 #define ACE_EXECUTION_TIME ACE_Time_Value::zero
1009 #define ACE_DEADLINE_TIME ACE_Time_Value::max_time
1010 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
1013 ACE_Message_Block::duplicate (void) const
1015 ACE_TRACE ("ACE_Message_Block::duplicate");
1017 ACE_Message_Block
*nb
= 0;
1019 // Create a new <ACE_Message_Block> that contains unique copies of
1020 // the message block fields, but a reference counted duplicate of
1021 // the <ACE_Data_Block>.
1023 // If there is no allocator, use the standard new and delete calls.
1024 if (this->message_block_allocator_
== 0)
1026 ACE_Message_Block (0, // size
1027 ACE_Message_Type (0), // type
1031 0, // locking strategy
1033 this->priority_
, // priority
1036 // Get a pointer to a
1037 // "duplicated" <ACE_Data_Block>
1038 // (will simply increment the
1039 // reference count).
1040 this->data_block ()->duplicate (),
1041 this->data_block ()->data_block_allocator (),
1042 this->message_block_allocator_
),
1044 else // Otherwise, use the message_block_allocator passed in.
1045 ACE_NEW_MALLOC_RETURN (nb
,
1046 static_cast<ACE_Message_Block
*> (
1047 message_block_allocator_
->malloc (sizeof (ACE_Message_Block
))),
1048 ACE_Message_Block (0, // size
1049 ACE_Message_Type (0), // type
1053 0, // locking strategy
1055 this->priority_
, // priority
1058 // Get a pointer to a
1059 // "duplicated" <ACE_Data_Block>
1060 // (will simply increment the
1061 // reference count).
1062 this->data_block ()->duplicate (),
1063 this->data_block ()->data_block_allocator (),
1064 this->message_block_allocator_
),
1067 // Set the read and write pointers in the new <Message_Block> to the
1068 // same relative offset as in the existing <Message_Block>. Note
1069 // that we are assuming that the data_block()->base() pointer
1070 // doesn't change when it's duplicated.
1071 nb
->rd_ptr (this->rd_ptr_
);
1072 nb
->wr_ptr (this->wr_ptr_
);
1074 // Increment the reference counts of all the continuation messages.
1077 nb
->cont_
= this->cont_
->duplicate ();
1079 // If things go wrong, release all of our resources and return
1092 ACE_Message_Block::duplicate (const ACE_Message_Block
*mb
)
1094 ACE_TRACE ("ACE_Message_Block::duplicate");
1098 return mb
->duplicate ();
1102 ACE_Data_Block::clone (ACE_Message_Block::Message_Flags mask
) const
1104 ACE_TRACE ("ACE_Data_Block::clone");
1106 ACE_Data_Block
*nb
= this->clone_nocopy (mask
);
1108 // Copy all of the payload memory into the new object. The new block
1109 // was allocated with max_size_ (and, thus, it's cur_size_ is the same
1110 // as max_size_). Maintain the same "has been written" boundary in the
1111 // new block by only copying cur_size_ bytes.
1114 ACE_OS::memcpy (nb
->base_
,
1123 ACE_Data_Block::clone_nocopy (ACE_Message_Block::Message_Flags mask
,
1124 size_t max_size
) const
1126 ACE_FUNCTION_TIMEPROBE(ACE_DATA_BLOCK_CLONE_ENTER
);
1128 ACE_TRACE ("ACE_Data_Block::clone_nocopy");
1130 // You always want to clear this one to prevent memory leaks but you
1131 // might add some others later.
1132 const ACE_Message_Block::Message_Flags always_clear
=
1133 ACE_Message_Block::DONT_DELETE
;
1135 const size_t newsize
=
1136 max_size
== 0 ? this->max_size_
: max_size
;
1138 ACE_Data_Block
*nb
= 0;
1140 ACE_NEW_MALLOC_RETURN (nb
,
1141 static_cast<ACE_Data_Block
*> (
1142 this->data_block_allocator_
->malloc (sizeof (ACE_Data_Block
))),
1143 ACE_Data_Block (newsize
, // size
1144 this->type_
, // type
1146 this->allocator_strategy_
, // allocator
1147 this->locking_strategy_
, // locking strategy
1148 this->flags_
, // flags
1149 this->data_block_allocator_
),
1152 // Message block initialization may fail while the construction
1153 // succeds. Since as a matter of policy, ACE may throw no
1154 // exceptions, we have to do a separate check like this.
1155 if (nb
!= 0 && nb
->size () < newsize
)
1157 nb
->ACE_Data_Block::~ACE_Data_Block(); // placement destructor ...
1158 this->data_block_allocator_
->free (nb
); // free ...
1164 // Set new flags minus the mask...
1165 nb
->clr_flags (mask
| always_clear
);
1170 ACE_Message_Block::clone (Message_Flags mask
) const
1172 ACE_TRACE ("ACE_Message_Block::clone");
1174 // Get a pointer to a "cloned" <ACE_Data_Block> (will copy the
1175 // values rather than increment the reference count).
1176 ACE_Data_Block
*db
= this->data_block ()->clone (mask
);
1181 ACE_Message_Block
*nb
= 0;
1183 if(message_block_allocator_
== 0)
1186 ACE_Message_Block (0, // size
1187 ACE_Message_Type (0), // type
1191 0, // locking strategy
1193 this->priority_
, // priority
1194 ACE_EXECUTION_TIME
, // execution time
1195 ACE_DEADLINE_TIME
, // absolute time to deadline
1196 // Get a pointer to a
1197 // "duplicated" <ACE_Data_Block>
1198 // (will simply increment the
1199 // reference count).
1201 db
->data_block_allocator (),
1202 this->message_block_allocator_
),
1207 // This is the ACE_NEW_MALLOC macro with the return check removed.
1208 // We need to do it this way because if it fails we need to release
1209 // the cloned data block that was created above. If we used
1210 // ACE_NEW_MALLOC_RETURN, there would be a memory leak because the
1211 // above db pointer would be left dangling.
1212 nb
= static_cast<ACE_Message_Block
*> (message_block_allocator_
->malloc (sizeof (ACE_Message_Block
)));
1214 new (nb
) ACE_Message_Block (0, // size
1215 ACE_Message_Type (0), // type
1219 0, // locking strategy
1221 this->priority_
, // priority
1222 ACE_EXECUTION_TIME
, // execution time
1223 ACE_DEADLINE_TIME
, // absolute time to deadline
1225 db
->data_block_allocator (),
1226 this->message_block_allocator_
);
1235 // Set the read and write pointers in the new <Message_Block> to the
1236 // same relative offset as in the existing <Message_Block>.
1237 nb
->rd_ptr (this->rd_ptr_
);
1238 nb
->wr_ptr (this->wr_ptr_
);
1240 // Clone all the continuation messages if necessary.
1241 if (this->cont () != 0
1242 && (nb
->cont_
= this->cont ()->clone (mask
)) == 0)
1252 ACE_Message_Block::operator= (const ACE_Message_Block
&)
1254 ACE_TRACE ("ACE_Message_Block::operator=");
1259 ACE_Data_Block::base (char *msg_data
,
1261 ACE_Message_Block::Message_Flags msg_flags
)
1263 if (ACE_BIT_DISABLED (this->flags_
,
1264 ACE_Message_Block::DONT_DELETE
))
1265 this->allocator_strategy_
->free (this->base_
);
1267 this->max_size_
= msg_length
;
1268 this->cur_size_
= msg_length
;
1269 this->base_
= msg_data
;
1270 this->flags_
= msg_flags
;
1273 ACE_END_VERSIONED_NAMESPACE_DECL