From 278e1d5ebad775759e537b11a69f75a2bb8c8c69 Mon Sep 17 00:00:00 2001 From: labancap Date: Wed, 30 Jan 2013 23:57:34 +0000 Subject: Applied bug 3247 duplicate patch --- ACE/OCI_RE_ChangeLog | 14 +++ ACE/ace/Message_Block.cpp | 139 +++++++++++++++------------ ACE/tests/Message_Block_Large_Copy_Test.cpp | 142 ++++++++++++++++++++++++++++ ACE/tests/run_test.lst | 1 + ACE/tests/tests.mpc | 7 ++ 5 files changed, 241 insertions(+), 62 deletions(-) create mode 100644 ACE/tests/Message_Block_Large_Copy_Test.cpp 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 + + * 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" * 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 that contains unique copies of - // the message block fields, but a reference counted duplicate of - // the . - - // 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" - // (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 ( - 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" - // (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 to the - // same relative offset as in the existing . 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 that contains unique copies of + // the message block fields, but a reference counted duplicate of + // the . + + // 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" + // (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 ( + 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" + // (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 to the + // same relative offset as in the existing . 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 + */ +//============================================================================= + + +#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 { -- cgit v1.2.1