summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2010-02-22 23:07:40 +0000
committerdai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2010-02-22 23:07:40 +0000
commitc96bdccf0fa1589250debf9773cf27cc6bc365a9 (patch)
tree97f5ca40ff317569ad1c1811ab090a3bb9328a62
parenta7ce04518cdcf226d1abfadae617f75d8befe1f6 (diff)
downloadATCD-c96bdccf0fa1589250debf9773cf27cc6bc365a9.tar.gz
Mon Feb 22 23:04:23 UTC 2010 Yan Dai <dai_y@ociweb.com>
-rw-r--r--TAO/ChangeLog18
-rw-r--r--TAO/tests/Bug_3812_Regression/Bug_3812_Regression.cpp132
-rwxr-xr-xTAO/tests/Bug_3812_Regression/Makefile.am72
-rw-r--r--TAO/tests/Bug_3812_Regression/mock_ps.h13
-rw-r--r--TAO/tests/Bug_3812_Regression/mock_tdi.h12
-rw-r--r--TAO/tests/Bug_3812_Regression/mock_transport.h125
-rwxr-xr-xTAO/tests/Bug_3812_Regression/run_test.pl37
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;