diff options
author | dai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2010-02-22 23:07:40 +0000 |
---|---|---|
committer | dai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2010-02-22 23:07:40 +0000 |
commit | c96bdccf0fa1589250debf9773cf27cc6bc365a9 (patch) | |
tree | 97f5ca40ff317569ad1c1811ab090a3bb9328a62 | |
parent | a7ce04518cdcf226d1abfadae617f75d8befe1f6 (diff) | |
download | ATCD-c96bdccf0fa1589250debf9773cf27cc6bc365a9.tar.gz |
Mon Feb 22 23:04:23 UTC 2010 Yan Dai <dai_y@ociweb.com>
-rw-r--r-- | TAO/ChangeLog | 18 | ||||
-rw-r--r-- | TAO/tests/Bug_3812_Regression/Bug_3812_Regression.cpp | 132 | ||||
-rwxr-xr-x | TAO/tests/Bug_3812_Regression/Makefile.am | 72 | ||||
-rw-r--r-- | TAO/tests/Bug_3812_Regression/mock_ps.h | 13 | ||||
-rw-r--r-- | TAO/tests/Bug_3812_Regression/mock_tdi.h | 12 | ||||
-rw-r--r-- | TAO/tests/Bug_3812_Regression/mock_transport.h | 125 | ||||
-rwxr-xr-x | TAO/tests/Bug_3812_Regression/run_test.pl | 37 |
7 files changed, 406 insertions, 3 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 8db85b8ac5f..cfcb189d59f 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,16 +1,28 @@ +Mon Feb 22 23:04:23 UTC 2010 Yan Dai <dai_y@ociweb.com> + + + * tests/Bug_3812_Regression/Bug_3812_Regression.cpp: + * tests/Bug_3812_Regression/Makefile.am: + * tests/Bug_3812_Regression/mock_ps.h: + * tests/Bug_3812_Regression/mock_tdi.h: + * tests/Bug_3812_Regression/mock_transport.h: + * tests/Bug_3812_Regression/run_test.pl: + + Added a regression test for bugzilla #3812. + Mon Feb 22 21:20:15 UTC 2010 Jeff Parsons <j.parsons@vanderbilt.edu> * TAO_IDL/be/be_codegen.cpp: * TAO_IDL/be_include/be_codegen.h: - + Added random 6-character string to #ifdef guard generation, to prevent hiding when IDL files have the same name (but are in different directories, the #ifdef guard uses only the local filename). - + * TAO_IDL/be/be_visitor_connector/connector_dds_exs.cpp: * TAO_IDL/be/be_visitor_connector/connector_dds_exh.cpp: - + Added logic to check for inheritance from DDS_State or DDS_Event connectors, to generate inheritance in the connector impl from the correct Base connector template. diff --git a/TAO/tests/Bug_3812_Regression/Bug_3812_Regression.cpp b/TAO/tests/Bug_3812_Regression/Bug_3812_Regression.cpp new file mode 100644 index 00000000000..47f4506343c --- /dev/null +++ b/TAO/tests/Bug_3812_Regression/Bug_3812_Regression.cpp @@ -0,0 +1,132 @@ +// $Id$ +#include "ace/Get_Opt.h" +#include "ace/Argv_Type_Converter.h" +#include "ace/SString.h" +#include "ace/Manual_Event.h" +#include "ace/Task.h" +#include "ace/OS.h" + +#include "tao/Transport_Cache_Manager_T.h" +#include "tao/ORB.h" +#include "tao/Condition.h" + +class mock_transport; +class mock_tdi; +class mock_ps; + +static int global_purged_count = 0; + +#include "mock_tdi.h" +#include "mock_transport.h" +#include "mock_ps.h" + +static TCM* tcm = 0; +static int result = 0; +static ACE_Thread_Mutex test_lock; +static TAO_Condition<ACE_Thread_Mutex> test_condition(test_lock); +static int n_threads = 1; + +int +parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("t:")); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 't': + n_threads = ACE_OS::atoi(get_opts.opt_arg()); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-t <n_threads>" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +class Client_Task : public ACE_Task_Base +{ + public : + Client_Task (mock_tdi& tdi, mock_transport& trans) + : tdi_ (tdi), + trans_ (trans) + { + } + + + ~Client_Task () {}; + + void process_listen_point () + { + this->trans_.purge_entry (); + // Allocate a new char to avoid the cache_transport malloc/free entry + // on same address which makes it harder to verify test result. + char*x = new char[1]; + tcm->cache_transport (&tdi_, &trans_); + this->trans_.make_idle(); + delete x; + } + + int svc () + { + ACE_Guard<ACE_Thread_Mutex> lock (test_lock); + process_listen_point (); + test_condition.signal (); + return 0; + }; + + + private: + mock_tdi& tdi_; + mock_transport& trans_; +}; + + + + +int +ACE_TMAIN(int argc, ACE_TCHAR *argv[]) +{ + try + { + // We need an ORB to get an ORB core + CORBA::ORB_var orb = CORBA::ORB_init (argc, argv); + + if (parse_args (argc, argv) != 0) + return 1; + + size_t const transport_max = 10; + int cache_maximum = 10; + int purging_percentage = 20; + mock_transport mytransport(orb->orb_core ()); + mock_tdi mytdi; + mock_ps* myps = new mock_ps(1); + TCM my_cache (purging_percentage, myps, cache_maximum, false, 0); + + tcm = &my_cache; + tcm->cache_transport (&mytdi, &mytransport); + + Client_Task client_task(mytdi, mytransport); + if (client_task.activate (THR_NEW_LWP | THR_JOINABLE, 2, 1) == -1) + { + ACE_ERROR ((LM_ERROR, "Error activating client task\n")); + } + + client_task.wait (); + + orb->destroy (); + + } + catch (const CORBA::Exception&) + { + // Ignore exceptions.. + } + return result; +} diff --git a/TAO/tests/Bug_3812_Regression/Makefile.am b/TAO/tests/Bug_3812_Regression/Makefile.am new file mode 100755 index 00000000000..ec325af2e83 --- /dev/null +++ b/TAO/tests/Bug_3812_Regression/Makefile.am @@ -0,0 +1,72 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## C:\OCI\TAO\doc\ACE\bin\mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.TCM_Bug_3549_Regression.am + +if BUILD_EXCEPTIONS + +noinst_PROGRAMS += Bug_3549_Regression + +Bug_3549_Regression_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +Bug_3549_Regression_SOURCES = \ + Bug_3549_Regression.cpp \ + mock_ps.h \ + mock_tdi.h \ + mock_transport.h + +Bug_3549_Regression_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_EXCEPTIONS + +## Makefile.TCM_Bug_3558_Regression.am + +if BUILD_EXCEPTIONS + +noinst_PROGRAMS += Bug_3558_Regression + +Bug_3558_Regression_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +Bug_3558_Regression_SOURCES = \ + Bug_3558_Regression.cpp \ + mock_ps.h \ + mock_tdi.h \ + mock_transport.h + +Bug_3558_Regression_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_EXCEPTIONS + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/tests/Bug_3812_Regression/mock_ps.h b/TAO/tests/Bug_3812_Regression/mock_ps.h new file mode 100644 index 00000000000..6c6631d8c07 --- /dev/null +++ b/TAO/tests/Bug_3812_Regression/mock_ps.h @@ -0,0 +1,13 @@ +// $Id$ + +class mock_ps +{ +public: + mock_ps (int max) : maximum_ (max) {} + void update_item (mock_transport*) {} + int cache_maximum () { return this->maximum_;} +private: + int maximum_; +}; + + diff --git a/TAO/tests/Bug_3812_Regression/mock_tdi.h b/TAO/tests/Bug_3812_Regression/mock_tdi.h new file mode 100644 index 00000000000..341b9b31626 --- /dev/null +++ b/TAO/tests/Bug_3812_Regression/mock_tdi.h @@ -0,0 +1,12 @@ +// $Id$ + +class mock_tdi +{ +public: + mock_tdi () {} + u_long hash (void) {return static_cast<u_long> (reinterpret_cast<ptrdiff_t> (this));} + mock_tdi *duplicate (void) {return 0;} + CORBA::Boolean is_equivalent (const mock_tdi *) {return true;} + +}; + diff --git a/TAO/tests/Bug_3812_Regression/mock_transport.h b/TAO/tests/Bug_3812_Regression/mock_transport.h new file mode 100644 index 00000000000..6ea2e7b9b66 --- /dev/null +++ b/TAO/tests/Bug_3812_Regression/mock_transport.h @@ -0,0 +1,125 @@ +// $Id$ + +#include "tao/ORB_Core.h" + +typedef TAO::Transport_Cache_Manager_T<mock_transport, mock_tdi, mock_ps> TCM; + +extern TCM* tcm; +extern int result; +extern ACE_Thread_Mutex test_lock; +extern TAO_Condition<ACE_Thread_Mutex> test_condition; + + +class mock_transport +{ +public: + mock_transport (TAO_ORB_Core *orb_core) + : id_(0) + , is_connected_(false) + , entry_(0) + , purging_order_ (0) + , purged_count_ (0) + , handler_lock_ (orb_core->resource_factory ()->create_cached_connection_lock ()) + {} + + size_t id (void) const {return id_;} + void id (size_t id) { this->id_ = id;} + unsigned long purging_order (void) const {return purging_order_;} + void purging_order (unsigned long purging_order) { this->purging_order_ = purging_order;} + bool is_connected (void) const {return is_connected_;} + void is_connected (bool is_connected) { this->is_connected_ = is_connected;} + ACE_Event_Handler::Reference_Count add_reference (void) {return 0;} + ACE_Event_Handler::Reference_Count remove_reference (void) {return 0;} + + // Implementation needs be similar to TAO_Transport::cache_map_entry(). + void cache_map_entry (TCM::HASH_MAP_ENTRY *entry) { + ACE_GUARD (ACE_Lock, ace_mon, *this->handler_lock_); + ACE_DEBUG ((LM_DEBUG, "(%P|%t)cache_map_entry %X\n", entry)); + this->entry_ = entry; + } + TCM::HASH_MAP_ENTRY *cache_map_entry (void) {return this->entry_;} + void close_connection (void) { purged_count_ = ++global_purged_count;}; + int purged_count (void) { return this->purged_count_;} + bool can_be_purged (void) { return true;} + + // Implementation needs be similar to TAO_Transport::purge_entry(). + int purge_entry (void) + { + TCM::HASH_MAP_ENTRY* entry = 0; + { + ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->handler_lock_, -1); + ACE_DEBUG ((LM_DEBUG, "(%P|%t)purge_entry %X\n", this->entry_)); + entry = this->entry_; + this->entry_ = 0; + } + return tcm->purge_entry (entry); + } + + // Implementation needs be similar to TAO_Transport::make_idle(). + // + // int + // TAO_Transport::make_idle (void) + // { + // if (TAO_debug_level > 3) + // { + // ACE_DEBUG ((LM_DEBUG, + // ACE_TEXT ("TAO (%P|%t) - Transport[%d]::make_idle\n"), + // this->id ())); + // } + // + // return this->transport_cache_manager ().make_idle (this->cache_map_entry_); + // } + + // Code are added to simulate the situation that the cached entry pointer passed + // to TCM to make entry idle is deleted by another thread b/c of re-cache transport + // and cause TCM make idle on an invalid entry. Otherwise we need delay and similar + // code in TCM::make_idl() to reproduce the problem. + + int make_idle (void) + { + static bool is_first = true; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t)make_idle pass entry %X\n", this->entry_)); + + TCM::HASH_MAP_ENTRY* entry = this->entry_; + + // The first thread comes to this point, record the entry + // and wait for second thread to process listen point which + // re-cache transport. + if (is_first) + { + is_first = false; + test_condition.wait (); + } + + ACE_DEBUG ((LM_DEBUG, "(%P|%t)make_idle execute on entry %X and now entry %X\n", + entry, this->entry_)); + + // When the first thread is at this point, the entry is + // deleted by second thread, so make idle on the invalid + // entry cause SEGV. It's possible that the memory is still + // available then next checking if entry is changed should + // confirm if the entry is valid or not. + int ret = tcm->make_idle (entry); + if (entry != this->entry_) + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t)ERROR: Entry was changed ") + ACE_TEXT ("after passing to TCM and before calling make_idl.\n"))); + result = 1; + } + + return ret; + } + + +private: + size_t id_; + bool is_connected_; + TCM::HASH_MAP_ENTRY *entry_; + unsigned long purging_order_; + /// When did we got purged + int purged_count_; + mutable ACE_Lock *handler_lock_; +}; + + diff --git a/TAO/tests/Bug_3812_Regression/run_test.pl b/TAO/tests/Bug_3812_Regression/run_test.pl new file mode 100755 index 00000000000..231ddcd7576 --- /dev/null +++ b/TAO/tests/Bug_3812_Regression/run_test.pl @@ -0,0 +1,37 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::TestTarget; +use strict; + +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::TestTarget; + +my $status = 0; +my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n"; +my $P = $server->CreateProcess ("Bug_3812_Regression"); +print "Running Bug_3812_Regression ...\n"; +my $result = $P->Spawn (); +if ($result != 0) { + print "test FAILED\n"; + $status = 1; +} +$result = $P->WaitKill(100*$server->ProcessStartWaitInterval()); +if ($result != 0) { + print "test FAILED\n"; + $status = 1; +} + +exit $status; |