summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlabancap <labancap@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2013-01-30 23:57:34 +0000
committerlabancap <labancap@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2013-01-30 23:57:34 +0000
commit278e1d5ebad775759e537b11a69f75a2bb8c8c69 (patch)
treefadeb07c88f435f86c236aacf99d760cea9bb5f9
parent4b6ee17726f4a5233cd73a7995be34fcccd47cf8 (diff)
downloadATCD-278e1d5ebad775759e537b11a69f75a2bb8c8c69.tar.gz
Applied bug 3247 duplicate patch
-rw-r--r--ACE/OCI_RE_ChangeLog14
-rw-r--r--ACE/ace/Message_Block.cpp139
-rw-r--r--ACE/tests/Message_Block_Large_Copy_Test.cpp142
-rw-r--r--ACE/tests/run_test.lst1
-rw-r--r--ACE/tests/tests.mpc7
5 files changed, 241 insertions, 62 deletions
diff --git a/ACE/OCI_RE_ChangeLog b/ACE/OCI_RE_ChangeLog
index 099be505663..cc843ecb8ee 100644
--- a/ACE/OCI_RE_ChangeLog
+++ b/ACE/OCI_RE_ChangeLog
@@ -1,3 +1,17 @@
+Wed Jan 30 23:54:14 UTC 2013 Phillip LaBanca <labancap@ociweb.com>
+
+ * ace/Message_Block.cpp:
+
+ Applied bug 3247 duplicate patch that replaced recursion with
+ iteration to support the copying of large message blocks.
+
+ * tests/Message_Block_Large_Copy_Test.cpp:
+ * tests/run_test.lst:
+ * tests/tests.mpc:
+
+ Created test to cover the cloning and duplication of
+ large Message_Blocks.
+
Tue Jan 29 15:15:09 UTC 2013 "Kevin Stanley" <stanleyk@ociweb.com>
* include/makeinclude/platform_sunos5_g++.GNU:
diff --git a/ACE/ace/Message_Block.cpp b/ACE/ace/Message_Block.cpp
index 867cf699bf1..f97a8d754f1 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*> (
+ 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 *
diff --git a/ACE/tests/Message_Block_Large_Copy_Test.cpp b/ACE/tests/Message_Block_Large_Copy_Test.cpp
new file mode 100644
index 00000000000..4d80091e362
--- /dev/null
+++ b/ACE/tests/Message_Block_Large_Copy_Test.cpp
@@ -0,0 +1,142 @@
+
+//=============================================================================
+/**
+ * @file Message_Block_Large_Copy_Test.cpp
+ *
+ * $Id$
+ *
+ * This test program tests large Message Block duplication and cloning.
+ *
+ *
+ * @author Phillip LaBanca <labancap@ociweb.com>
+ */
+//=============================================================================
+
+
+#include "test_config.h"
+#include "ace/Message_Block.h"
+
+size_t
+run_duplicate_test (size_t msg_block_count, size_t msg_block_size)
+{
+ size_t rc = 0;
+ char block[msg_block_size];
+
+ for(size_t j = 0 ; j != msg_block_size; j++)
+ block[j] = 'A';
+
+ block[msg_block_size-1] = 0;
+
+ ACE_Message_Block* mb_top = new ACE_Message_Block ();
+ ACE_Message_Block* mb = mb_top;
+
+ for (size_t j = 0; j != msg_block_count; ++j)
+ {
+ ACE_Message_Block* next = new ACE_Message_Block (block, msg_block_size);
+ next->copy (block);
+ mb->cont (next);
+ mb = next;
+ }
+
+ ACE_Message_Block* mb_test = mb_top->duplicate ();
+
+ if (mb_test != 0)
+ {
+ rc = mb_test->total_size();
+ ACE_ERROR ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) duplicated: %@ %d %d\n"),
+ mb_test,
+ mb_test->total_size(),
+ mb_test->total_length()));
+ mb_test-> release();
+ mb_top-> release();
+ }
+
+ return rc;
+}
+
+size_t
+run_clone_test (size_t msg_block_count, size_t msg_block_size)
+{
+ size_t rc = 0;
+ char block[msg_block_size];
+
+ for (size_t j = 0 ; j != msg_block_size; j++)
+ block[j] = 'A';
+
+ block[msg_block_size-1] = 0;
+
+ ACE_Message_Block* mb_top = new ACE_Message_Block ();
+ ACE_Message_Block* mb = mb_top;
+
+ for (size_t j = 0; j != msg_block_count; ++j)
+ {
+ ACE_Message_Block* next = new ACE_Message_Block (block, msg_block_size);
+ next->copy (block);
+ mb->cont (next);
+ mb = next;
+ }
+
+ ACE_Message_Block* mb_test = mb_top->clone ();
+
+ if (mb_test != 0)
+ {
+ rc = mb_test->total_size();
+ ACE_ERROR ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) cloned: %@ %d %d\n"),
+ mb_test,
+ mb_test->total_size(),
+ mb_test->total_length()));
+ mb_test-> release();
+ mb_top-> release();
+ }
+ return rc;
+}
+
+int
+run_main (int , ACE_TCHAR *[])
+{
+
+ int rc = 0;
+
+ ACE_START_TEST (ACE_TEXT ("Message_Block_Large_Copy_Test"));
+ {
+
+ // Message_Block size() and Length() of 24,000,000
+ const size_t MSG_BLOCK_COUNT = 8000;
+ const size_t MSG_BLOCK_SIZE = 3000;
+ const size_t MSG_BLOCK_TOTAL = MSG_BLOCK_COUNT * MSG_BLOCK_SIZE;
+
+ ACE_ERROR ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) %u blocks %u bytes each, total %u\n"),
+ MSG_BLOCK_COUNT,
+ MSG_BLOCK_SIZE,
+ MSG_BLOCK_TOTAL));
+
+ size_t duplicate_total = run_duplicate_test (
+ MSG_BLOCK_COUNT,
+ MSG_BLOCK_SIZE);
+ if (duplicate_total != MSG_BLOCK_TOTAL )
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) duplicate(): returned total of %u\n"),
+ duplicate_total));
+ rc = 1;
+ }
+
+ size_t clone_total = run_clone_test (
+ MSG_BLOCK_COUNT,
+ MSG_BLOCK_SIZE);
+ if (clone_total != MSG_BLOCK_TOTAL )
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) clone(): returned total of %u \n"),
+ clone_total));
+ rc = 1;
+ }
+
+ }
+ ACE_END_TEST;
+ return rc;
+}
+
diff --git a/ACE/tests/run_test.lst b/ACE/tests/run_test.lst
index 914b5699bb3..de4d8aeca49 100644
--- a/ACE/tests/run_test.lst
+++ b/ACE/tests/run_test.lst
@@ -138,6 +138,7 @@ Map_Test: !ACE_FOR_TAO
Max_Default_Port_Test: !ST
Mem_Map_Test: !VxWorks !nsk !ACE_FOR_TAO
Memcpy_Test: !ACE_FOR_TAO
+Message_Block_Large_Copy_Test
Message_Block_Test: !ACE_FOR_TAO
Message_Queue_Notifications_Test
Message_Queue_Test: !ACE_FOR_TAO
diff --git a/ACE/tests/tests.mpc b/ACE/tests/tests.mpc
index a5c13da5c2b..318b4d184dd 100644
--- a/ACE/tests/tests.mpc
+++ b/ACE/tests/tests.mpc
@@ -1407,6 +1407,13 @@ project(Simple Message Block Test) : acetest {
}
}
+project(Message Block Large Copy Test) : acetest {
+ exename = Message_Block_Large_Copy_Test
+ Source_Files {
+ Message_Block_Large_Copy_Test.cpp
+ }
+}
+
project(Singleton Test) : acetest {
exename = Singleton_Test
Source_Files {