Fixed typos
[ACE_TAO.git] / ACE / ace / Message_Block.cpp
blobfca5f105a488ecf249d96b75f5f762fde9764d13
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"
35 enum
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
50 // Setup Timeprobes
51 ACE_TIMEPROBE_EVENT_DESCRIPTIONS (ACE_MB_Timeprobe_Description,
52 ACE_MESSAGE_BLOCK_INIT_I_ENTER);
54 #endif /* ACE_ENABLE_TIMEPROBES */
56 void
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 ());
73 int
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 ();
82 if (len < n)
84 errno = ENOSPC;
85 return -1;
87 else
89 (void) ACE_OS::memcpy (this->wr_ptr (),
90 buf,
91 n);
92 this->wr_ptr (n);
93 return 0;
97 int
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;
108 if (len < buflen)
110 errno = ENOSPC;
111 return -1;
113 else
115 (void) ACE_OS::memcpy (this->wr_ptr (),
116 buf,
117 buflen);
118 this->wr_ptr (buflen);
119 return 0;
124 ACE_Message_Block::crunch (void)
126 if (this->rd_ptr_ != 0)
128 if (this->rd_ptr_ > this->wr_ptr_)
129 return -1;
131 size_t const len = this->length ();
132 (void) ACE_OS::memmove (this->base (),
133 this->rd_ptr (),
134 len);
135 this->rd_ptr (this->base ());
136 this->wr_ptr (this->base () + len);
138 return 0;
141 void
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"),
157 this->type_,
158 this->cur_size_,
159 this->max_size_,
160 this->flags_,
161 this->base_,
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 */
169 void
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"),
184 this->priority_,
185 this->next_,
186 this->prev_,
187 this->cont_,
188 this->rd_ptr_,
189 this->wr_ptr_));
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;
216 else
218 // We need to resize!
219 char *buf = 0;
220 ACE_ALLOCATOR_RETURN (buf,
221 (char *) this->allocator_strategy_->malloc (length),
222 -1);
224 ACE_OS::memcpy (buf,
225 this->base_,
226 this->cur_size_);
227 if (ACE_BIT_DISABLED (this->flags_,
228 ACE_Message_Block::DONT_DELETE))
229 this->allocator_strategy_->free ((void *) this->base_);
230 else
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;
236 this->base_ = buf;
238 return 0;
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)
248 return -1;
250 return 0;
253 void
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;
260 i != 0;
261 i = i->cont ())
263 mb_size += i->size ();
264 mb_length += i->length ();
268 size_t
269 ACE_Message_Block::total_size (void) const
271 ACE_TRACE ("ACE_Message_Block::total_size");
273 size_t size = 0;
274 for (const ACE_Message_Block *i = this;
275 i != 0;
276 i = i->cont ())
277 size += i->size ();
279 return size;
282 size_t
283 ACE_Message_Block::total_length (void) const
285 ACE_TRACE ("ACE_Message_Block::total_length");
287 size_t length = 0;
288 for (const ACE_Message_Block *i = this;
289 i != 0;
290 i = i->cont ())
291 length += i->length ();
293 return length;
296 size_t
297 ACE_Message_Block::total_capacity (void) const
299 ACE_TRACE ("ACE_Message_Block::total_capacity");
301 size_t size = 0;
303 for (const ACE_Message_Block *i = this;
304 i != 0;
305 i = i->cont ())
306 size += i->capacity ();
308 return size;
311 ACE_Data_Block::ACE_Data_Block (void)
312 : type_ (ACE_Message_Block::MB_DATA),
313 cur_size_ (0),
314 max_size_ (0),
315 flags_ (ACE_Message_Block::DONT_DELETE),
316 base_ (0),
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)
339 : type_ (msg_type),
340 cur_size_ (0), // Reset later if memory alloc'd ok
341 max_size_ (0),
342 flags_ (flags),
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 ());
362 if (msg_data == 0)
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_,
368 '\0',
369 size);
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)
377 size = 0;
380 // The memory is legit, whether passed in or allocated, so set
381 // the size.
382 this->cur_size_ = this->max_size_ = size;
385 ACE_Message_Block::ACE_Message_Block (const char *data,
386 size_t size,
387 unsigned long priority)
388 : flags_ (0),
389 data_block_ (0)
391 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
393 if (this->init_i (size, // size
394 MB_DATA, // type
395 0, // cont
396 data, // data
397 0, // 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 0, // data block
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)
411 : flags_ (0),
412 data_block_ (0)
414 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
416 if (this->init_i (0, // size
417 MB_DATA, // type
418 0, // cont
419 0, // data
420 0, // allocator
421 0, // locking strategy
422 ACE_Message_Block::DONT_DELETE, // flags
423 0, // priority
424 ACE_Time_Value::zero, // execution time
425 ACE_Time_Value::max_time, // absolute time of deadline
426 0, // data block
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)
444 :flags_ (0),
445 data_block_ (0)
447 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
449 if (this->init_i (size,
450 msg_type,
451 msg_cont,
452 msg_data,
453 allocator_strategy,
454 locking_strategy,
455 msg_data ? ACE_Message_Block::DONT_DELETE : 0,
456 priority,
457 execution_time,
458 deadline_time,
459 0, // data block
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,
482 msg_type,
483 msg_cont,
484 msg_data,
485 allocator_strategy,
486 locking_strategy,
487 msg_data ? ACE_Message_Block::DONT_DELETE : 0,
488 priority,
489 execution_time,
490 deadline_time,
491 0, // data block
492 data_block_allocator,
493 message_block_allocator);
497 ACE_Message_Block::init (const char *data,
498 size_t size)
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
504 MB_DATA, // type
505 0, // cont
506 data, // data
507 0, // allocator
508 0, // locking strategy
509 ACE_Message_Block::DONT_DELETE, // flags
510 0, // priority
511 ACE_Time_Value::zero, // execution time
512 ACE_Time_Value::max_time, // absolute time of deadline
513 0, // data block
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,
524 Message_Flags flags,
525 unsigned long priority,
526 const ACE_Time_Value &execution_time,
527 const ACE_Time_Value &deadline_time,
528 ACE_Data_Block *db,
529 ACE_Allocator *data_block_allocator,
530 ACE_Allocator *message_block_allocator)
531 : flags_ (0),
532 data_block_ (0)
534 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
536 if (this->init_i (size,
537 msg_type,
538 msg_cont,
539 msg_data,
540 allocator_strategy,
541 locking_strategy,
542 flags,
543 priority,
544 execution_time,
545 deadline_time,
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)
556 : flags_ (flags),
557 data_block_ (0)
559 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
561 if (this->init_i (0, // size
562 MB_NORMAL, // type
563 0, // cont
564 0, // data
565 0, // allocator
566 0, // locking strategy
567 0, // flags
568 0, // priority
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,
579 size_t align)
580 :flags_ (0),
581 data_block_ (0)
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
589 MB_NORMAL, // type
590 0, // cont
591 0, // data
592 0, // allocator
593 0, // locking strategy
594 0, // flags
595 0, // priority
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)
604 // Align ourselves
605 char *start = ACE_ptr_align_binary (this->base (),
606 align);
607 #else
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);
616 else
618 if (this->init_i (0, // size
619 MB_NORMAL, // type
620 0, // cont
621 0, // data
622 0, // allocator
623 0, // locking strategy
624 0, // flags
625 0, // priority
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)
635 // Align ourselves
636 char *start = ACE_ptr_align_binary (this->base (),
637 align);
638 #else
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 (),
649 align);
650 #else
651 start = 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 (),
660 start,
661 wr_offset);
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,
679 Message_Flags flags,
680 unsigned long priority,
681 const ACE_Time_Value &execution_time,
682 const ACE_Time_Value &deadline_time,
683 ACE_Data_Block *db,
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);
690 this->rd_ptr_ = 0;
691 this->wr_ptr_ = 0;
692 this->priority_ = priority;
693 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
694 this->execution_time_ = execution_time;
695 this->deadline_time_ = deadline_time;
696 #else
697 ACE_UNUSED_ARG (execution_time);
698 ACE_UNUSED_ARG (deadline_time);
699 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
700 this->cont_ = msg_cont;
701 this->next_ = 0;
702 this->prev_ = 0;
704 this->message_block_allocator_ = message_block_allocator;
706 if (this->data_block_ != 0)
708 this->data_block_->release ();
709 this->data_block_ = 0;
712 if (db == 0)
714 if (data_block_allocator == 0)
715 ACE_ALLOCATOR_RETURN (data_block_allocator,
716 ACE_Allocator::instance (),
717 -1);
719 ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC);
721 // Allocate the <ACE_Data_Block> portion, which is reference
722 // counted.
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,
727 msg_type,
728 msg_data,
729 allocator_strategy,
730 locking_strategy,
731 flags,
732 data_block_allocator),
733 -1);
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 ...
743 errno = ENOMEM;
744 return -1;
748 // Reset the data_block_ pointer.
749 this->data_block (db);
751 return 0;
754 ACE_Data_Block::~ACE_Data_Block (void)
756 // Sanity check...
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_);
766 this->base_ = 0;
770 ACE_Data_Block *
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
784 result = 0;
785 else
786 result = this;
788 return result;
791 ACE_Data_Block *
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
800 if (lock != 0)
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.
805 lock_to_be_used = 0;
807 // The lock passed in does not match our lock
808 else
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
813 else
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 ();
827 else
829 result = this->release_i ();
832 return result;
835 ACE_Data_Block *
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
846 // pointer!
847 if (result == 0)
848 ACE_DES_FREE_THIS (allocator->free,
849 ACE_Data_Block);
850 return result;
853 ACE_Message_Block *
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;
866 ACE_Lock *lock = 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 ();
874 // if we have a lock
875 if (lock != 0)
877 // One guard for all
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
884 else
885 // Call non-guarded release with no lock
886 destroy_dblock = this->release_i (0);
888 else
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 ();
895 ACE_DES_FREE (tmp,
896 allocator->free,
897 ACE_Data_Block);
900 return 0;
904 ACE_Message_Block::release_i (ACE_Lock *lock)
906 ACE_TRACE ("ACE_Message_Block::release_i");
908 // Free up all the continuation messages.
909 if (this->cont_)
911 ACE_Message_Block *mb = this->cont_;
912 ACE_Message_Block *tmp = 0;
916 tmp = mb;
917 mb = mb->cont_;
918 tmp->cont_ = 0;
920 ACE_Data_Block *db = tmp->data_block ();
921 if (tmp->release_i (lock) != 0)
923 ACE_Allocator *allocator = db->data_block_allocator ();
924 ACE_DES_FREE (db,
925 allocator->free,
926 ACE_Data_Block);
929 while (mb);
931 this->cont_ = 0;
934 int result = 0;
936 if (ACE_BIT_DISABLED (this->flags_,
937 ACE_Message_Block::DONT_DELETE) &&
938 this->data_block ())
940 if (this->data_block ()->release_no_delete (lock) == 0)
941 result = 1;
942 this->data_block_ = 0;
945 // We will now commit suicide: this object *must* have come from the
946 // allocator given.
947 if (this->message_block_allocator_ == 0)
948 delete this;
949 else
951 ACE_Allocator *allocator = this->message_block_allocator_;
952 ACE_DES_FREE_THIS (allocator->free,
953 ACE_Message_Block);
956 return result;
959 /* static */ ACE_Message_Block *
960 ACE_Message_Block::release (ACE_Message_Block *mb)
962 ACE_TRACE ("ACE_Message_Block::release");
964 if (mb != 0)
965 return mb->release ();
966 else
967 return 0;
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)&&
976 this->data_block ())
977 this->data_block ()->release ();
979 this->prev_ = 0;
980 this->next_ = 0;
981 this->cont_ = 0;
984 ACE_Data_Block *
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_;
997 else
998 ++this->reference_count_;
1000 return this;
1003 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
1004 #define ACE_EXECUTION_TIME this->execution_time_
1005 #define ACE_DEADLINE_TIME this->deadline_time_
1006 #else
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 */
1011 ACE_Message_Block *
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.
1022 while (current)
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
1035 0, // cont
1036 0, // data
1037 0, // allocator
1038 0, // locking strategy
1039 0, // flags
1040 current->priority_, // priority
1041 ACE_EXECUTION_TIME,
1042 ACE_DEADLINE_TIME,
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
1056 0, // cont
1057 0, // data
1058 0, // allocator
1059 0, // locking strategy
1060 0, // flags
1061 current->priority_, // priority
1062 ACE_EXECUTION_TIME,
1063 ACE_DEADLINE_TIME,
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
1074 if (cur_dup == 0)
1076 if (nb_top != 0)
1078 nb_top->release ();
1080 return 0;
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_);
1090 if (!nb)
1092 /* First in the list: set leading pointers */
1093 nb_top = nb = cur_dup;
1095 else
1097 /* Continuing on: append to nb and walk down the list */
1098 nb->cont_ = cur_dup;
1099 nb = nb->cont_;
1102 current = current->cont_;
1105 return nb_top;
1108 ACE_Message_Block *
1109 ACE_Message_Block::duplicate (const ACE_Message_Block *mb)
1111 ACE_TRACE ("ACE_Message_Block::duplicate");
1112 if (mb == 0)
1113 return 0;
1114 else
1115 return mb->duplicate ();
1118 ACE_Data_Block *
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.
1129 if (nb != 0)
1131 ACE_OS::memcpy (nb->base_,
1132 this->base_,
1133 this->cur_size_);
1136 return nb;
1139 ACE_Data_Block *
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
1162 0, // data
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 ...
1176 errno = ENOMEM;
1177 return 0;
1181 // Set new flags minus the mask...
1182 nb->clr_flags (mask | always_clear);
1183 return nb;
1186 ACE_Message_Block *
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);
1202 if (db == 0)
1203 return 0;
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
1210 0, // cont
1211 0, // data
1212 0, // allocator
1213 0, // locking strategy
1214 0, // flags
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_),
1227 else
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
1238 0, // cont
1239 0, // data
1240 0, // allocator
1241 0, // locking strategy
1242 0, // flags
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)
1253 db->release ();
1254 return 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;
1275 // This is private.
1276 ACE_Message_Block &
1277 ACE_Message_Block::operator= (const ACE_Message_Block &)
1279 ACE_TRACE ("ACE_Message_Block::operator=");
1280 return *this;
1283 void
1284 ACE_Data_Block::base (char *msg_data,
1285 size_t msg_length,
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