summaryrefslogtreecommitdiff
path: root/ACE/ace/Message_Block.cpp
diff options
context:
space:
mode:
authorstanleyk <stanleyk@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2013-02-05 21:11:03 +0000
committerstanleyk <stanleyk@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2013-02-05 21:11:03 +0000
commit5e030faf84086ab02059fcbcc3faed224bd57b95 (patch)
tree3a62df45ac6ccf599fb07cf6a03d672456ce2e3d /ACE/ace/Message_Block.cpp
parent9d296f7fa51116ff7040ecb2ad18612cd94b5fd1 (diff)
downloadATCD-5e030faf84086ab02059fcbcc3faed224bd57b95.tar.gz
Merge in OCI_Reliability_Enhancements branch.
Diffstat (limited to 'ACE/ace/Message_Block.cpp')
-rw-r--r--ACE/ace/Message_Block.cpp141
1 files changed, 78 insertions, 63 deletions
diff --git a/ACE/ace/Message_Block.cpp b/ACE/ace/Message_Block.cpp
index 867cf699bf1..d4ad6ad4488 100644
--- a/ACE/ace/Message_Block.cpp
+++ b/ACE/ace/Message_Block.cpp
@@ -1016,78 +1016,93 @@ ACE_Message_Block::duplicate (void) const
{
ACE_TRACE ("ACE_Message_Block::duplicate");
+ ACE_Message_Block *nb_top = 0;
ACE_Message_Block *nb = 0;
- // Create a new <ACE_Message_Block> that contains unique copies of
- // the message block fields, but a reference counted duplicate of
- // the <ACE_Data_Block>.
-
- // If there is no allocator, use the standard new and delete calls.
- if (this->message_block_allocator_ == 0)
- ACE_NEW_RETURN (nb,
- ACE_Message_Block (0, // size
- ACE_Message_Type (0), // type
- 0, // cont
- 0, // data
- 0, // allocator
- 0, // locking strategy
- 0, // flags
- this->priority_, // priority
- ACE_EXECUTION_TIME,
- ACE_DEADLINE_TIME,
- // Get a pointer to a
- // "duplicated" <ACE_Data_Block>
- // (will simply increment the
- // reference count).
- this->data_block ()->duplicate (),
- this->data_block ()->data_block_allocator (),
- this->message_block_allocator_),
- 0);
- else // Otherwise, use the message_block_allocator passed in.
- ACE_NEW_MALLOC_RETURN (nb,
- static_cast<ACE_Message_Block*> (
- message_block_allocator_->malloc (sizeof (ACE_Message_Block))),
- ACE_Message_Block (0, // size
- ACE_Message_Type (0), // type
- 0, // cont
- 0, // data
- 0, // allocator
- 0, // locking strategy
- 0, // flags
- this->priority_, // priority
- ACE_EXECUTION_TIME,
- ACE_DEADLINE_TIME,
- // Get a pointer to a
- // "duplicated" <ACE_Data_Block>
- // (will simply increment the
- // reference count).
- this->data_block ()->duplicate (),
- this->data_block ()->data_block_allocator (),
- this->message_block_allocator_),
- 0);
-
- // Set the read and write pointers in the new <Message_Block> to the
- // same relative offset as in the existing <Message_Block>. Note
- // that we are assuming that the data_block()->base() pointer
- // doesn't change when it's duplicated.
- nb->rd_ptr (this->rd_ptr_);
- nb->wr_ptr (this->wr_ptr_);
+ const ACE_Message_Block *current = this;
// Increment the reference counts of all the continuation messages.
- if (this->cont_)
+ while (current)
{
- nb->cont_ = this->cont_->duplicate ();
+ ACE_Message_Block* cur_dup = 0;
+
+ // Create a new <ACE_Message_Block> that contains unique copies of
+ // the message block fields, but a reference counted duplicate of
+ // the <ACE_Data_Block>.
+
+ // If there is no allocator, use the standard new and delete calls.
+ if (current->message_block_allocator_ == 0)
+ ACE_NEW_NORETURN (cur_dup,
+ ACE_Message_Block (0, // size
+ ACE_Message_Type (0), // type
+ 0, // cont
+ 0, // data
+ 0, // allocator
+ 0, // locking strategy
+ 0, // flags
+ current->priority_, // priority
+ ACE_EXECUTION_TIME,
+ ACE_DEADLINE_TIME,
+ // Get a pointer to a
+ // "duplicated" <ACE_Data_Block>
+ // (will simply increment the
+ // reference count).
+ current->data_block ()->duplicate (),
+ current->data_block ()->data_block_allocator (),
+ current->message_block_allocator_));
+ else // Otherwise, use the message_block_allocator passed in.
+ ACE_NEW_MALLOC_NORETURN (cur_dup,
+ static_cast<ACE_Message_Block*> (
+ current->message_block_allocator_->malloc (sizeof (ACE_Message_Block))),
+ ACE_Message_Block (0, // size
+ ACE_Message_Type (0), // type
+ 0, // cont
+ 0, // data
+ 0, // allocator
+ 0, // locking strategy
+ 0, // flags
+ current->priority_, // priority
+ ACE_EXECUTION_TIME,
+ ACE_DEADLINE_TIME,
+ // Get a pointer to a
+ // "duplicated" <ACE_Data_Block>
+ // (will simply increment the
+ // reference count).
+ current->data_block ()->duplicate (),
+ current->data_block ()->data_block_allocator (),
+ current->message_block_allocator_));
+
+
+ // If allocation failed above, release everything done so far and return NULL
+ if (cur_dup == 0)
+ {
+ nb_top->release ();
+ return NULL;
+ }
+
+ // Set the read and write pointers in the new <Message_Block> to the
+ // same relative offset as in the existing <Message_Block>. Note
+ // that we are assuming that the data_block()->base() pointer
+ // doesn't change when it's duplicated.
+ cur_dup->rd_ptr (current->rd_ptr_);
+ cur_dup->wr_ptr (current->wr_ptr_);
- // If things go wrong, release all of our resources and return
- // 0.
- if (nb->cont_ == 0)
+ if (!nb)
+ {
+ /* First in the list: set leading pointers */
+ nb_top = nb = cur_dup;
+ }
+ else
{
- nb->release ();
- nb = 0;
+ /* Continuing on: append to nb and walk down the list */
+ nb->cont_ = cur_dup;
+ nb = nb->cont_;
}
+
+ current = current->cont_;
}
- return nb;
+ return nb_top;
}
ACE_Message_Block *
@@ -1216,7 +1231,7 @@ ACE_Message_Block::clone (Message_Flags mask) const
// the cloned data block that was created above. If we used
// ACE_NEW_MALLOC_RETURN, there would be a memory leak because the
// above db pointer would be left dangling.
- new_message_block = static_cast<ACE_Message_Block*> (message_block_allocator_->malloc (sizeof (ACE_Message_Block)));
+ new_message_block = static_cast<ACE_Message_Block*> (old_message_block->message_block_allocator_->malloc (sizeof (ACE_Message_Block)));
if (new_message_block != 0)
new (new_message_block) ACE_Message_Block (0, // size
ACE_Message_Type (0), // type