[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / dep / ACE_wrappers / ace / Message_Block.cpp
blob9a1fd1adf385a8074ee613a11dccec2ddfff5793
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"
15 ACE_RCSID (ace,
16 Message_Block,
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"
39 enum
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
54 // Setup Timeprobes
55 ACE_TIMEPROBE_EVENT_DESCRIPTIONS (ACE_MB_Timeprobe_Description,
56 ACE_MESSAGE_BLOCK_INIT_I_ENTER);
58 #endif /* ACE_ENABLE_TIMEPROBES */
60 void
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 ());
77 int
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 ();
86 if (len < n)
88 errno = ENOSPC;
89 return -1;
91 else
93 (void) ACE_OS::memcpy (this->wr_ptr (),
94 buf,
95 n);
96 this->wr_ptr (n);
97 return 0;
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;
112 if (len < buflen)
114 errno = ENOSPC;
115 return -1;
117 else
119 (void) ACE_OS::memcpy (this->wr_ptr (),
120 buf,
121 buflen);
122 this->wr_ptr (buflen);
123 return 0;
128 ACE_Message_Block::crunch (void)
130 if (this->rd_ptr_ != 0)
132 if (this->rd_ptr_ > this->wr_ptr_)
133 return -1;
135 size_t const len = this->length ();
136 (void) ACE_OS::memmove (this->base (),
137 this->rd_ptr (),
138 len);
139 this->rd_ptr (this->base ());
140 this->wr_ptr (this->base () + len);
142 return 0;
145 void
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"),
161 this->type_,
162 this->cur_size_,
163 this->max_size_,
164 this->flags_,
165 this->base_,
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 */
173 void
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"),
188 this->priority_,
189 this->next_,
190 this->prev_,
191 this->cont_,
192 this->rd_ptr_,
193 this->wr_ptr_));
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;
220 else
222 // We need to resize!
223 char *buf = 0;
224 ACE_ALLOCATOR_RETURN (buf,
225 (char *) this->allocator_strategy_->malloc (length),
226 -1);
228 ACE_OS::memcpy (buf,
229 this->base_,
230 this->cur_size_);
231 if (ACE_BIT_DISABLED (this->flags_,
232 ACE_Message_Block::DONT_DELETE))
233 this->allocator_strategy_->free ((void *) this->base_);
234 else
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;
240 this->base_ = buf;
242 return 0;
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)
252 return -1;
254 return 0;
257 void
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;
264 i != 0;
265 i = i->cont ())
267 mb_size += i->size ();
268 mb_length += i->length ();
272 size_t
273 ACE_Message_Block::total_size (void) const
275 ACE_TRACE ("ACE_Message_Block::total_size");
277 size_t size = 0;
278 for (const ACE_Message_Block *i = this;
279 i != 0;
280 i = i->cont ())
281 size += i->size ();
283 return size;
286 size_t
287 ACE_Message_Block::total_length (void) const
289 ACE_TRACE ("ACE_Message_Block::total_length");
291 size_t length = 0;
292 for (const ACE_Message_Block *i = this;
293 i != 0;
294 i = i->cont ())
295 length += i->length ();
297 return length;
300 size_t
301 ACE_Message_Block::total_capacity (void) const
303 ACE_TRACE ("ACE_Message_Block::total_capacity");
305 size_t size = 0;
307 for (const ACE_Message_Block *i = this;
308 i != 0;
309 i = i->cont ())
310 size += i->capacity ();
312 return size;
315 ACE_Data_Block::ACE_Data_Block (void)
316 : type_ (ACE_Message_Block::MB_DATA),
317 cur_size_ (0),
318 max_size_ (0),
319 flags_ (ACE_Message_Block::DONT_DELETE),
320 base_ (0),
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)
343 : type_ (msg_type),
344 cur_size_ (0), // Reset later if memory alloc'd ok
345 max_size_ (0),
346 flags_ (flags),
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 ());
366 if (msg_data == 0)
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_,
372 '\0',
373 size);
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)
381 size = 0;
384 // The memory is legit, whether passed in or allocated, so set
385 // the size.
386 this->cur_size_ = this->max_size_ = size;
389 ACE_Message_Block::ACE_Message_Block (const char *data,
390 size_t size,
391 unsigned long priority)
392 : flags_ (0),
393 data_block_ (0)
395 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
397 if (this->init_i (size, // size
398 MB_DATA, // type
399 0, // cont
400 data, // data
401 0, // allocator
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
407 0, // data block
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)
415 : flags_ (0),
416 data_block_ (0)
418 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
420 if (this->init_i (0, // size
421 MB_DATA, // type
422 0, // cont
423 0, // data
424 0, // allocator
425 0, // locking strategy
426 ACE_Message_Block::DONT_DELETE, // flags
427 0, // priority
428 ACE_Time_Value::zero, // execution time
429 ACE_Time_Value::max_time, // absolute time of deadline
430 0, // data block
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)
448 :flags_ (0),
449 data_block_ (0)
451 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
453 if (this->init_i (size,
454 msg_type,
455 msg_cont,
456 msg_data,
457 allocator_strategy,
458 locking_strategy,
459 msg_data ? ACE_Message_Block::DONT_DELETE : 0,
460 priority,
461 execution_time,
462 deadline_time,
463 0, // data block
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,
486 msg_type,
487 msg_cont,
488 msg_data,
489 allocator_strategy,
490 locking_strategy,
491 msg_data ? ACE_Message_Block::DONT_DELETE : 0,
492 priority,
493 execution_time,
494 deadline_time,
495 0, // data block
496 data_block_allocator,
497 message_block_allocator);
501 ACE_Message_Block::init (const char *data,
502 size_t size)
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
508 MB_DATA, // type
509 0, // cont
510 data, // data
511 0, // allocator
512 0, // locking strategy
513 ACE_Message_Block::DONT_DELETE, // flags
514 0, // priority
515 ACE_Time_Value::zero, // execution time
516 ACE_Time_Value::max_time, // absolute time of deadline
517 0, // data block
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,
528 Message_Flags flags,
529 unsigned long priority,
530 const ACE_Time_Value &execution_time,
531 const ACE_Time_Value &deadline_time,
532 ACE_Data_Block *db,
533 ACE_Allocator *data_block_allocator,
534 ACE_Allocator *message_block_allocator)
535 : flags_ (0),
536 data_block_ (0)
538 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
540 if (this->init_i (size,
541 msg_type,
542 msg_cont,
543 msg_data,
544 allocator_strategy,
545 locking_strategy,
546 flags,
547 priority,
548 execution_time,
549 deadline_time,
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)
560 : flags_ (flags),
561 data_block_ (0)
563 ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
565 if (this->init_i (0, // size
566 MB_NORMAL, // type
567 0, // cont
568 0, // data
569 0, // allocator
570 0, // locking strategy
571 0, // flags
572 0, // priority
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,
583 size_t align)
584 :flags_ (0),
585 data_block_ (0)
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
593 MB_NORMAL, // type
594 0, // cont
595 0, // data
596 0, // allocator
597 0, // locking strategy
598 0, // flags
599 0, // priority
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)
608 // Align ourselves
609 char *start = ACE_ptr_align_binary (this->base (),
610 align);
611 #else
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);
620 else
622 if (this->init_i (0, // size
623 MB_NORMAL, // type
624 0, // cont
625 0, // data
626 0, // allocator
627 0, // locking strategy
628 0, // flags
629 0, // priority
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)
639 // Align ourselves
640 char *start = ACE_ptr_align_binary (this->base (),
641 align);
642 #else
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 (),
653 align);
654 #else
655 start = 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 (),
664 start,
665 wr_offset);
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,
683 Message_Flags flags,
684 unsigned long priority,
685 const ACE_Time_Value &execution_time,
686 const ACE_Time_Value &deadline_time,
687 ACE_Data_Block *db,
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);
694 this->rd_ptr_ = 0;
695 this->wr_ptr_ = 0;
696 this->priority_ = priority;
697 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
698 this->execution_time_ = execution_time;
699 this->deadline_time_ = deadline_time;
700 #else
701 ACE_UNUSED_ARG (execution_time);
702 ACE_UNUSED_ARG (deadline_time);
703 #endif /* ACE_HAS_TIMED_MESSAGE_BLOCKS */
704 this->cont_ = msg_cont;
705 this->next_ = 0;
706 this->prev_ = 0;
708 this->message_block_allocator_ = message_block_allocator;
710 if (this->data_block_ != 0)
712 this->data_block_->release ();
713 this->data_block_ = 0;
716 if (db == 0)
718 if (data_block_allocator == 0)
719 ACE_ALLOCATOR_RETURN (data_block_allocator,
720 ACE_Allocator::instance (),
721 -1);
723 ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC);
725 // Allocate the <ACE_Data_Block> portion, which is reference
726 // counted.
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,
731 msg_type,
732 msg_data,
733 allocator_strategy,
734 locking_strategy,
735 flags,
736 data_block_allocator),
737 -1);
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 ...
747 errno = ENOMEM;
748 return -1;
752 // Reset the data_block_ pointer.
753 this->data_block (db);
755 return 0;
758 ACE_Data_Block::~ACE_Data_Block (void)
760 // Sanity check...
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_);
770 this->base_ = 0;
774 ACE_Data_Block *
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
788 result = 0;
789 else
790 result = this;
792 return result;
795 ACE_Data_Block *
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
804 if (lock != 0)
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.
809 lock_to_be_used = 0;
811 // The lock passed in does not match our lock
812 else
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
817 else
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 ();
829 else
830 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,
849 allocator->free,
850 ACE_Data_Block);
851 return result;
854 ACE_Message_Block *
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;
867 ACE_Lock *lock = 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 ();
875 // if we have a lock
876 if (lock != 0)
878 // One guard for all
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
885 else
886 // Call non-guarded release with no lock
887 destroy_dblock = this->release_i (0);
889 else
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 ();
896 ACE_DES_FREE (tmp,
897 allocator->free,
898 ACE_Data_Block);
901 return 0;
905 ACE_Message_Block::release_i (ACE_Lock *lock)
907 ACE_TRACE ("ACE_Message_Block::release_i");
909 // Free up all the continuation messages.
910 if (this->cont_)
912 ACE_Message_Block *mb = this->cont_;
913 ACE_Message_Block *tmp = 0;
917 tmp = mb;
918 mb = mb->cont_;
919 tmp->cont_ = 0;
921 ACE_Data_Block *db = tmp->data_block ();
922 if (tmp->release_i (lock) != 0)
924 ACE_Allocator *allocator = db->data_block_allocator ();
925 ACE_DES_FREE (db,
926 allocator->free,
927 ACE_Data_Block);
930 while (mb);
932 this->cont_ = 0;
935 int result = 0;
937 if (ACE_BIT_DISABLED (this->flags_,
938 ACE_Message_Block::DONT_DELETE) &&
939 this->data_block ())
941 if (this->data_block ()->release_no_delete (lock) == 0)
942 result = 1;
943 this->data_block_ = 0;
946 // We will now commit suicide: this object *must* have come from the
947 // allocator given.
948 if (this->message_block_allocator_ == 0)
949 delete this;
950 else
952 ACE_Allocator *allocator = this->message_block_allocator_;
953 ACE_DES_FREE (this,
954 allocator->free,
955 ACE_Message_Block);
958 return result;
961 /* static */ ACE_Message_Block *
962 ACE_Message_Block::release (ACE_Message_Block *mb)
964 ACE_TRACE ("ACE_Message_Block::release");
966 if (mb != 0)
967 return mb->release ();
968 else
969 return 0;
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)&&
978 this->data_block ())
979 this->data_block ()->release ();
981 this->prev_ = 0;
982 this->next_ = 0;
985 ACE_Data_Block *
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_;
998 else
999 ++this->reference_count_;
1001 return this;
1004 #if defined (ACE_HAS_TIMED_MESSAGE_BLOCKS)
1005 #define ACE_EXECUTION_TIME this->execution_time_
1006 #define ACE_DEADLINE_TIME this->deadline_time_
1007 #else
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 */
1012 ACE_Message_Block *
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)
1025 ACE_NEW_RETURN (nb,
1026 ACE_Message_Block (0, // size
1027 ACE_Message_Type (0), // type
1028 0, // cont
1029 0, // data
1030 0, // allocator
1031 0, // locking strategy
1032 0, // flags
1033 this->priority_, // priority
1034 ACE_EXECUTION_TIME,
1035 ACE_DEADLINE_TIME,
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
1050 0, // cont
1051 0, // data
1052 0, // allocator
1053 0, // locking strategy
1054 0, // flags
1055 this->priority_, // priority
1056 ACE_EXECUTION_TIME,
1057 ACE_DEADLINE_TIME,
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.
1075 if (this->cont_)
1077 nb->cont_ = this->cont_->duplicate ();
1079 // If things go wrong, release all of our resources and return
1080 // 0.
1081 if (nb->cont_ == 0)
1083 nb->release ();
1084 nb = 0;
1088 return nb;
1091 ACE_Message_Block *
1092 ACE_Message_Block::duplicate (const ACE_Message_Block *mb)
1094 ACE_TRACE ("ACE_Message_Block::duplicate");
1095 if (mb == 0)
1096 return 0;
1097 else
1098 return mb->duplicate ();
1101 ACE_Data_Block *
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.
1112 if (nb != 0)
1114 ACE_OS::memcpy (nb->base_,
1115 this->base_,
1116 this->cur_size_);
1119 return nb;
1122 ACE_Data_Block *
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
1145 0, // data
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 ...
1159 errno = ENOMEM;
1160 return 0;
1164 // Set new flags minus the mask...
1165 nb->clr_flags (mask | always_clear);
1166 return nb;
1169 ACE_Message_Block *
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);
1178 if (db == 0)
1179 return 0;
1181 ACE_Message_Block *nb = 0;
1183 if(message_block_allocator_ == 0)
1185 ACE_NEW_RETURN (nb,
1186 ACE_Message_Block (0, // size
1187 ACE_Message_Type (0), // type
1188 0, // cont
1189 0, // data
1190 0, // allocator
1191 0, // locking strategy
1192 0, // flags
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_),
1205 else
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)));
1213 if(nb != 0)
1214 new (nb) ACE_Message_Block (0, // size
1215 ACE_Message_Type (0), // type
1216 0, // cont
1217 0, // data
1218 0, // allocator
1219 0, // locking strategy
1220 0, // flags
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_);
1229 if (nb == 0)
1231 db->release ();
1232 return 0;
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)
1244 nb->release ();
1245 return 0;
1247 return nb;
1250 // This is private.
1251 ACE_Message_Block &
1252 ACE_Message_Block::operator= (const ACE_Message_Block &)
1254 ACE_TRACE ("ACE_Message_Block::operator=");
1255 return *this;
1258 void
1259 ACE_Data_Block::base (char *msg_data,
1260 size_t msg_length,
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