summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Mesnier <mesnier_p@ociweb.com>2013-06-03 21:24:44 +0000
committerPhil Mesnier <mesnier_p@ociweb.com>2013-06-03 21:24:44 +0000
commit385483de11a927d5ee4935a050530444aa671685 (patch)
tree480cd693d7dc56d11c139c234b7d1b7a8b7ce00e
parentc2a9008be6b9bffe9d43946913ae7b1af27df1ae (diff)
downloadATCD-385483de11a927d5ee4935a050530444aa671685.tar.gz
Mon Jun 3 21:16:43 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com>
-rw-r--r--TAO/ChangeLog37
-rw-r--r--TAO/bin/tao_other_tests.lst1
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp32
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp14
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/LiveCheck.cpp78
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/LiveCheck.h9
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/ping_interrupt/README7
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.cpp53
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.h51
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test.idl10
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.cpp21
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.h24
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/ping_interrupt/ping_interrupt.mpc25
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/ping_interrupt/run_test.pl231
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server.cpp157
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.cpp98
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.h62
17 files changed, 901 insertions, 9 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index d4f7555668b..9c60aac9fa1 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,40 @@
+Mon Jun 3 21:16:43 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * bin/tao_other_tests.lst:
+
+ Add new test to suite.
+
+ * orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp:
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+
+ Add more high-verbosity logging output.
+
+ * orbsvcs/ImplRepo_Service/LiveCheck.h:
+ * orbsvcs/ImplRepo_Service/LiveCheck.cpp:
+
+ Add code to guard against server termination while waiting
+ for a ping response. This can happen if the target POA gets
+ shutdown while another thread was handling a ping request from
+ the IMR. If the POA's server_is_shutting_down call gets back
+ to the ImR before the ping reply. The ImR was not properly
+ cleaning up the callback object, this would lead to a call
+ to a deleted object triggering the crash.
+
+ * orbsvcs/tests/ImplRepo/ping_interrupt/README:
+ * orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.h:
+ * orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.cpp:
+ * orbsvcs/tests/ImplRepo/ping_interrupt/Test.idl:
+ * orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.h:
+ * orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.cpp:
+ * orbsvcs/tests/ImplRepo/ping_interrupt/ping_interrupt.mpc:
+ * orbsvcs/tests/ImplRepo/ping_interrupt/run_test.pl:
+ * orbsvcs/tests/ImplRepo/ping_interrupt/server.cpp:
+ * orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.h:
+ * orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.cpp:
+
+ Added a test to simulate the above by using a server interceptor
+ to trigger the POA shutdown before sending the ping result.
+
Thu May 30 18:52:55 UTC 2013 Johnny Willemsen <jwillemsen@remedy.nl>
* orbsvcs/tests/Trading/colocated_test.cpp:
diff --git a/TAO/bin/tao_other_tests.lst b/TAO/bin/tao_other_tests.lst
index 3d95906e13f..4f9322f3b99 100644
--- a/TAO/bin/tao_other_tests.lst
+++ b/TAO/bin/tao_other_tests.lst
@@ -141,6 +141,7 @@ TAO/orbsvcs/tests/ImplRepo/servers_interact_on_startup/run_test.pl: !ST !MINIMUM
TAO/orbsvcs/tests/ImplRepo/servers_interact_on_startup/run_test.pl -delay 20 -imr_start: !ST !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !LynxOS !OpenVMS
TAO/orbsvcs/tests/ImplRepo/servers_interact_on_startup/run_test.pl -hide_server -imr_start: !ST !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !LynxOS !OpenVMS
TAO/orbsvcs/tests/ImplRepo/servers_interact_on_startup/run_test.pl -multistart: !ST !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !LynxOS !OpenVMS
+TAO/orbsvcs/tests/ImplRepo/ping_interrupt/run_test.pl: !ST !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !LynxOS !OpenVMS
TAO/orbsvcs/examples/ImR/Combined_Service/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !STATIC !ST !ACE_FOR_TAO !LynxOS
TAO/orbsvcs/examples/CosEC/TypedSimple/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !NO_IFR !ACE_FOR_TAO !WCHAR
TAO/orbsvcs/tests/CosEvent/Timeout/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ST !NO_MESSAGING !ACE_FOR_TAO !LynxOS
diff --git a/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp b/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp
index 5ccef1c12d2..a37a5e62f9a 100644
--- a/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp
@@ -23,6 +23,13 @@ AsyncAccessManager::AsyncAccessManager (const Server_Info &info,
lock_()
{
this->info_ = new Server_Info (info);
+ if (ImR_Locator_i::debug () > 4)
+ {
+ ORBSVCS_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) AsyncAccessManager::ctor server = %s\n"),
+ this->info_->name.c_str()));
+ }
+
}
AsyncAccessManager::~AsyncAccessManager (void)
@@ -50,6 +57,12 @@ AsyncAccessManager::add_interest (ImR_ResponseHandler *rh)
ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_);
this->rh_list_.push_back (rh);
}
+ if (ImR_Locator_i::debug () > 4)
+ {
+ ORBSVCS_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) AsyncAccessManager::add_interest\n")));
+ }
+
if (this->info_->activation_mode == ImplementationRepository::PER_CLIENT)
{
@@ -189,6 +202,12 @@ void
AsyncAccessManager::server_is_running (const char *partial_ior,
ImplementationRepository::ServerObject_ptr ref)
{
+ if (ImR_Locator_i::debug () > 4)
+ {
+ ORBSVCS_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) AsyncAccessManager::server_is_running\n")));
+ }
+
this->status (AAM_WAIT_FOR_ALIVE);
this->info_->partial_ior = partial_ior;
this->info_->server = ImplementationRepository::ServerObject::_duplicate (ref);
@@ -238,6 +257,13 @@ AsyncAccessManager::notify_child_death (void)
void
AsyncAccessManager::ping_replied (LiveStatus server)
{
+ if (ImR_Locator_i::debug () > 4)
+ {
+ ORBSVCS_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) AsyncAccessManager::ping_replied %s\n"),
+ LiveEntry::status_name (server)));
+ }
+
switch (server)
{
case LS_ALIVE:
@@ -269,6 +295,12 @@ AsyncAccessManager::ping_replied (LiveStatus server)
bool
AsyncAccessManager::send_start_request (void)
{
+ if (ImR_Locator_i::debug () > 4)
+ {
+ ORBSVCS_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) AsyncAccessManager::send_start_request\n")));
+ }
+
if (this->info_->activation_mode == ImplementationRepository::MANUAL &&
!this->manual_start_)
{
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
index 0ce84d357d8..b7e34b9a29b 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
@@ -1005,9 +1005,21 @@ ImR_Locator_i::server_is_running
AsyncAccessManager_ptr aam(this->find_aam (name.c_str()));
if (!aam.is_nil())
- aam->server_is_running (partial_ior, s.in());
+ {
+ if (ImR_Locator_i::debug () > 4)
+ {
+ ORBSVCS_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) ImR_Locator_i::send_start_request aam is not nil\n")));
+ }
+ aam->server_is_running (partial_ior, s.in());
+ }
else
{
+ if (ImR_Locator_i::debug () > 4)
+ {
+ ORBSVCS_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) ImR_Locator_i::send_start_request aam is nil\n")));
+ }
if (info->activation_mode != ImplementationRepository::PER_CLIENT)
{
AsyncAccessManager *aam_raw;
diff --git a/TAO/orbsvcs/ImplRepo_Service/LiveCheck.cpp b/TAO/orbsvcs/ImplRepo_Service/LiveCheck.cpp
index 450cf94976c..c0c5d3bb69b 100644
--- a/TAO/orbsvcs/ImplRepo_Service/LiveCheck.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/LiveCheck.cpp
@@ -123,12 +123,33 @@ LiveEntry::LiveEntry (LiveCheck *owner,
max_retry_ (LiveEntry::reping_limit_),
may_ping_ (may_ping),
listeners_ (),
- lock_ ()
+ lock_ (),
+ callback_ (0)
{
+ if (ImR_Locator_i::debug () > 4)
+ {
+ ORBSVCS_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) LiveEntry::ctor server = %s, may_ping = %d\n"),
+ server, may_ping));
+ }
}
LiveEntry::~LiveEntry (void)
{
+ if (this->callback_.in () != 0)
+ {
+ PingReceiver *rec = dynamic_cast<PingReceiver *>(this->callback_.in());
+ if (rec != 0)
+ {
+ rec->cancel ();
+ }
+ }
+}
+
+void
+LiveEntry::release_callback (void)
+{
+ this->callback_ = 0;
}
void
@@ -248,6 +269,12 @@ LiveEntry::next_check (void) const
return this->next_check_;
}
+const char *
+LiveEntry::server_name (void) const
+{
+ return this->server_.c_str();
+}
+
bool
LiveEntry::validate_ping (bool &want_reping, ACE_Time_Value& next)
{
@@ -352,8 +379,8 @@ LiveEntry::validate_ping (bool &want_reping, ACE_Time_Value& next)
void
LiveEntry::do_ping (PortableServer::POA_ptr poa)
{
- PortableServer::ServantBase_var callback = new PingReceiver (this, poa);
- PortableServer::ObjectId_var oid = poa->activate_object (callback.in());
+ this->callback_ = new PingReceiver (this, poa);
+ PortableServer::ObjectId_var oid = poa->activate_object (this->callback_.in());
CORBA::Object_var obj = poa->id_to_reference (oid.in());
ImplementationRepository::AMI_ServerObjectHandler_var cb =
ImplementationRepository::AMI_ServerObjectHandler::_narrow (obj.in());
@@ -397,9 +424,32 @@ PingReceiver::~PingReceiver (void)
}
void
+PingReceiver::cancel (void)
+{
+ if (ImR_Locator_i::debug () > 4)
+ {
+ const char *server = "<not available>";
+ if (this->entry_ != 0)
+ {
+ server = this->entry_->server_name ();
+ }
+ ORBSVCS_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) PingReceiver::cancel server = %s\n"),
+ server));
+ }
+
+ this->entry_ = 0;
+ PortableServer::ObjectId_var oid = this->poa_->servant_to_id (this);
+ poa_->deactivate_object (oid.in());
+}
+
+void
PingReceiver::ping (void)
{
- this->entry_->status (LS_ALIVE);
+ if (this->entry_ != 0)
+ {
+ this->entry_->status (LS_ALIVE);
+ }
PortableServer::ObjectId_var oid = this->poa_->servant_to_id (this);
poa_->deactivate_object (oid.in());
}
@@ -419,22 +469,34 @@ PingReceiver::ping_excep (Messaging::ExceptionHolder * excep_holder)
case TAO_POA_DISCARDING:
case TAO_POA_HOLDING:
{
- this->entry_->status (LS_TRANSIENT);
+ if (this->entry_ != 0)
+ {
+ this->entry_->status (LS_TRANSIENT);
+ }
break;
}
default: //case TAO_INVOCATION_SEND_REQUEST_MINOR_CODE:
{
- this->entry_->status (LS_DEAD);
+ if (this->entry_ != 0)
+ {
+ this->entry_->status (LS_DEAD);
+ }
}
}
}
catch (CORBA::TIMEOUT &)
{
- this->entry_->status (LS_TIMEDOUT);
+ if (this->entry_ != 0)
+ {
+ this->entry_->status (LS_TIMEDOUT);
+ }
}
catch (CORBA::Exception &)
{
- this->entry_->status (LS_DEAD);
+ if (this->entry_ != 0)
+ {
+ this->entry_->status (LS_DEAD);
+ }
}
PortableServer::ObjectId_var oid = this->poa_->servant_to_id (this);
diff --git a/TAO/orbsvcs/ImplRepo_Service/LiveCheck.h b/TAO/orbsvcs/ImplRepo_Service/LiveCheck.h
index 42e93be8810..293c215e9f2 100644
--- a/TAO/orbsvcs/ImplRepo_Service/LiveCheck.h
+++ b/TAO/orbsvcs/ImplRepo_Service/LiveCheck.h
@@ -27,6 +27,7 @@
class LiveCheck;
class LiveEntry;
+class PingReceiver;
//---------------------------------------------------------------------------
/*
@@ -120,6 +121,7 @@ class Locator_Export LiveEntry
ImplementationRepository::ServerObject_ptr ref);
~LiveEntry (void);
+ void release_callback (void);
void add_listener (LiveListener *ll);
LiveStatus status (void) const;
void status (LiveStatus l);
@@ -136,6 +138,7 @@ class Locator_Export LiveEntry
bool reping_available (void);
int next_reping (void);
void max_retry_msec (int max);
+ const char *server_name (void) const;
private:
LiveCheck *owner_;
@@ -150,6 +153,8 @@ class Locator_Export LiveEntry
typedef ACE_Unbounded_Set<LiveListener_ptr> Listen_Set;
Listen_Set listeners_;
TAO_SYNCH_MUTEX lock_;
+ PortableServer::ServantBase_var callback_;
+
static const int reping_msec_ [];
static int reping_limit_;
@@ -171,6 +176,10 @@ class Locator_Export PingReceiver :
PingReceiver (LiveEntry * entry, PortableServer::POA_ptr poa);
virtual ~PingReceiver (void);
+ /// Called by the entry if it is no longer interested in the result of
+ /// a ping.
+ void cancel (void);
+
/// Called when an anticipated ping reply is received
void ping (void);
diff --git a/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/README b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/README
new file mode 100644
index 00000000000..3bbc70e0d48
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/README
@@ -0,0 +1,7 @@
+$Id$
+
+This test runs checks the behavior of the IMR when a server shuts down
+while it is in the middle of handling a ping request from the ImR
+Locator. This scenario could happen in an MT server, although to avoid
+a race, an interceptor is used. The test succeeds if the ImR Locator
+does not crash.
diff --git a/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.cpp b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.cpp
new file mode 100644
index 00000000000..e1325a2aa8b
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.cpp
@@ -0,0 +1,53 @@
+// -*- C++ -*-
+//
+// $Id$
+//
+
+#include "Server_ORBInitializer.h"
+#include "server_interceptor.h"
+
+Server_ORBInitializer::Server_ORBInitializer (int *counter)
+ : counter_ (counter),
+ intr_ (0)
+{
+}
+
+void
+Server_ORBInitializer::pre_init (
+ PortableInterceptor::ORBInitInfo_ptr)
+{
+}
+
+void
+Server_ORBInitializer::post_init (
+ PortableInterceptor::ORBInitInfo_ptr info)
+{
+ if (this->intr_ != 0)
+ {
+ return;
+ }
+
+ PortableInterceptor::ServerRequestInterceptor_ptr interceptor =
+ PortableInterceptor::ServerRequestInterceptor::_nil ();
+
+ // Install the Echo server request interceptor
+ ACE_NEW_THROW_EX (this->intr_,
+ Ping_Death_Request_Interceptor (this->counter_),
+ CORBA::NO_MEMORY ());
+
+ PortableInterceptor::ServerRequestInterceptor_var
+ server_interceptor = interceptor;
+
+ info->add_server_request_interceptor (this->intr_); //server_interceptor.in ());
+}
+
+void
+Server_ORBInitializer::set_poa (PortableServer::POA_ptr poa)
+{
+ if (this->intr_ == 0)
+ {
+ return;
+ }
+
+ this->intr_->set_poa (poa);
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.h b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.h
new file mode 100644
index 00000000000..c1d0a17a924
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.h
@@ -0,0 +1,51 @@
+// -*- C++ -*-
+//
+// $Id$
+//
+
+#ifndef TAO_SERVER_ORB_INITIALIZER_H
+#define TAO_SERVER_ORB_INITIALIZER_H
+#include /**/ "ace/pre.h"
+
+#include "tao/PI/PI.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/LocalObject.h"
+#include "server_interceptor.h"
+
+// This is to remove "inherits via dominance" warnings from MSVC.
+// MSVC is being a little too paranoid.
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4250)
+#endif /* _MSC_VER */
+
+/// Server ORB initializer.
+class Server_ORBInitializer :
+ public virtual PortableInterceptor::ORBInitializer,
+ public virtual ::CORBA::LocalObject
+{
+public:
+ /// Constructor
+ Server_ORBInitializer (int *counter);
+
+ void set_poa (PortableServer::POA_ptr poa);
+
+ virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr info);
+
+ virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info);
+
+private:
+ int *counter_;
+ Ping_Death_Request_Interceptor *intr_;
+};
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif /* _MSC_VER */
+
+#include /**/ "ace/post.h"
+#endif /* TAO_SERVER_ORB_INITIALIZER_H */
diff --git a/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test.idl b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test.idl
new file mode 100644
index 00000000000..c05ecbf1d64
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test.idl
@@ -0,0 +1,10 @@
+// $Id$
+
+interface Test
+{
+
+ // Return the number of the server after a delay
+ short get_server_num (in short delay_secs);
+
+};
+
diff --git a/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.cpp b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.cpp
new file mode 100644
index 00000000000..0582552fdce
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.cpp
@@ -0,0 +1,21 @@
+/* -*- C++ -*- $Id$ */
+
+#include "Test_i.h"
+#include "ace/OS_NS_unistd.h"
+
+Test_i::Test_i (CORBA::Short server_num)
+ : server_num_ (server_num)
+{
+}
+
+Test_i::~Test_i ()
+{
+}
+
+CORBA::Short
+Test_i::get_server_num (const CORBA::Short delay_secs)
+{
+ ACE_OS::sleep (delay_secs);
+ return this->server_num_;
+}
+
diff --git a/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.h b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.h
new file mode 100644
index 00000000000..9693977cc8c
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.h
@@ -0,0 +1,24 @@
+/* -*- C++ -*- $Id$ */
+
+#ifndef TEST_I_H_
+#define TEST_I_H_
+
+#include "TestS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class Test_i : public virtual POA_Test
+{
+public:
+ Test_i (short server_num);
+ virtual ~Test_i ();
+
+ virtual CORBA::Short get_server_num (CORBA::Short delay_secs);
+
+private:
+ CORBA::Short server_num_;
+};
+
+#endif /* TEST_I_H_ */
diff --git a/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/ping_interrupt.mpc b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/ping_interrupt.mpc
new file mode 100644
index 00000000000..158a6f6408e
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/ping_interrupt.mpc
@@ -0,0 +1,25 @@
+// $Id$
+
+project(*idl): taoidldefaults {
+ IDL_Files {
+ Test.idl
+ }
+
+ custom_only = 1
+}
+
+project(*server): portableserver, orbsvcsexe, avoids_minimum_corba, iortable, imr_client, avoids_corba_e_micro, threads, pi_server, interceptors {
+ after += *idl
+ exename = server
+ IDL_Files {
+ }
+ Source_Files {
+ Test_i.cpp
+ Server_ORBInitializer.cpp
+ server_interceptor.cpp
+ server.cpp
+ TestC.cpp
+ TestS.cpp
+ }
+}
+
diff --git a/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/run_test.pl b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/run_test.pl
new file mode 100755
index 00000000000..fdb71282609
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/run_test.pl
@@ -0,0 +1,231 @@
+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;
+
+$status = 0;
+$imr_debug = "";
+
+if ($#ARGV >= 0) {
+ for (my $i = 0; $i <= $#ARGV; $i++) {
+ if ($ARGV[$i] eq '-debug') {
+ $imr_debug = "-d 5 -ORBDebugLevel 10 -ORBVerboseLogging 1 -ORBLogFile imr_loc.log";
+ $i++;
+ }
+ else {
+ usage();
+ exit 1;
+ }
+ }
+}
+
+#$ENV{ACE_TEST_VERBOSE} = "1";
+
+my $tgt_num = 0;
+my $imr = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+my $act = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+my $ti = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+my $srv = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+
+my $refstyle = " -ORBobjrefstyle URL";
+my $obj_count = 1;
+my $port = 9876;
+
+my $objprefix = "TestObject_0";
+my $client_wait_time = 10;
+
+$imriorfile = "imr_locator.ior";
+$actiorfile = "imr_activator.ior";
+$persistxml = "persist.xml";
+$persistdat = "persist.dat";
+
+my $imr_imriorfile = $imr->LocalFile ($imriorfile);
+my $act_imriorfile = $act->LocalFile ($imriorfile);
+my $ti_imriorfile = $ti->LocalFile ($imriorfile);
+my $act_actiorfile = $act->LocalFile ($actiorfile);
+my $imr_persistxml = $imr->LocalFile ($persistxml);
+my $imr_persistdat = $imr->LocalFile ($persistdat);
+
+$IMR = $imr->CreateProcess ("$ENV{TAO_ROOT}/orbsvcs/ImplRepo_Service/tao_imr_locator");
+$ACT = $act->CreateProcess ("$ENV{TAO_ROOT}/orbsvcs/ImplRepo_Service/tao_imr_activator");
+$TI = $ti->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_imr");
+
+# Make sure the files are gone, so we can wait on them.
+$imr->DeleteFile ($imriorfile);
+$act->DeleteFile ($imriorfile);
+$ti->DeleteFile ($imriorfile);
+$act->DeleteFile ($actiorfile);
+$imr->DeleteFile ($persistxml);
+$imr->DeleteFile ($persistdat);
+
+my $stdout_file = "test.out";
+my $stderr_file = "test.err";
+my $ti_stdout_file = $ti->LocalFile ($stdout_file);
+my $ti_stderr_file = $ti->LocalFile ($stderr_file);
+
+# Clean up after exit call
+END
+{
+ $imr->DeleteFile ($imriorfile);
+ $act->DeleteFile ($imriorfile);
+ $ti->DeleteFile ($imriorfile);
+ $act->DeleteFile ($actiorfile);
+ $imr->DeleteFile ($persistxml);
+ $imr->DeleteFile ($persistdat);
+
+ $ti->DeleteFile ($stdout_file);
+ $ti->DeleteFile ($stderr_file);
+
+ # Remove any stray server status files caused by aborting services
+ unlink <*.status>;
+}
+
+sub redirect_output()
+{
+ open(OLDOUT, ">&", \*STDOUT) or die "Can't dup STDOUT: $!";
+ open(OLDERR, ">&", \*STDERR) or die "Can't dup STDERR: $!";
+ open STDERR, '>', $ti_stderr_file;
+ open STDOUT, '>', $ti_stdout_file;
+}
+
+sub restore_output()
+{
+ open(STDERR, ">&OLDERR") or die "Can't dup OLDERR: $!";
+ open(STDOUT, ">&OLDOUT") or die "Can't dup OLDOUT: $!";
+}
+
+sub server_setup ()
+{
+ print "initializing activator\n";
+
+ $ACT->Arguments ("-d 0 -l -o $act_actiorfile -ORBInitRef ImplRepoService=file://$act_imriorfile");
+
+ $ACT_status = $ACT->Spawn ();
+ if ($ACT_status != 0) {
+ print STDERR "ERROR: ImR Activator returned $ACT_status\n";
+ return 1;
+ }
+ if ($act->WaitForFileTimed ($actiorfile,$act->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$act_imriorfile>\n";
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+
+ my $SRV = $srv->CreateProcess ("server");
+ my $server_cmd = $SRV->Executable();
+ my $srv_server_cmd = $imr->LocalFile ($server_cmd);
+
+ ##### Add servers to activator #####
+ print "adding server\n";
+ my $status_file_name = $objprefix . ".status";
+
+ $act->DeleteFile ($status_file_name);
+ $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
+ "add $objprefix -c \"$srv_server_cmd -ORBUseIMR 1 ".
+ "-ORBInitRef ImplRepoService=file://$imr_imriorfile\"");
+
+ $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr returned $TI_status\n";
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+
+
+ $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
+ "start $objprefix");
+
+ $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ if ($TI_status != 0 && $TI_status != 4) {
+ print STDERR "ERROR: tao_imr returned $TI_status\n";
+ $ACT->Kill (); $ACT->TimedWait (1);
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ $TI_status = 0;
+}
+
+
+sub interrupt_ping_test
+{
+ print "Running interrupt ping test.\n";
+
+ my $result = 0;
+ my $start_time = time();
+
+ $IMR->Arguments ("-i $imr_debug -o $imr_imriorfile -orbendpoint iiop://:$port");
+
+ ##### Start ImplRepo #####
+ $IMR_status = $IMR->Spawn ();
+ if ($IMR_status != 0) {
+ print STDERR "ERROR: ImplRepo Service returned $IMR_status\n";
+ return 1;
+ }
+ if ($imr->WaitForFileTimed ($imriorfile, $imr->ProcessStartWaitInterval()) == -1) {
+ print STDERR "ERROR: cannot find file <$imr_imriorfile>\n";
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ if ($imr->GetFile ($imriorfile) == -1) {
+ print STDERR "ERROR: cannot retrieve file <$imr_imriorfile>\n";
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ if ($act->PutFile ($imriorfile) == -1) {
+ print STDERR "ERROR: cannot set file <$act_imriorfile>\n";
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ if ($ti->PutFile ($imriorfile) == -1) {
+ print STDERR "ERROR: cannot set file <$ti_imriorfile>\n";
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+ if ($srv->PutFile ($imriorfile) == -1) {
+ print STDERR "ERROR: cannot set file <$srv_imriorfile>\n";
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+
+ server_setup();
+
+ sleep (2);
+
+ my $ACT_status = $ACT->TerminateWaitKill ($act->ProcessStopWaitInterval());
+ if ($ACT_status != 0) {
+ print STDERR "ERROR: IMR Activator returned $ACT_status\n";
+ $status = 1;
+ }
+
+ my $IMR_status = $IMR->TerminateWaitKill ($imr->ProcessStopWaitInterval());
+ if ($IMR_status != 0) {
+ print STDERR "ERROR: IMR returned $IMR_status\n";
+ $status = 1;
+ }
+
+ my $test_time = time() - $start_time;
+
+ print "\nFinished. The test took $test_time seconds.\n";
+
+ return $status;
+}
+
+sub usage() {
+ print "Usage: run_test.pl ".
+ "[-debug]\n";
+}
+
+###############################################################################
+###############################################################################
+
+my $ret = interrupt_ping_test();
+
+exit $ret;
diff --git a/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server.cpp b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server.cpp
new file mode 100644
index 00000000000..ec65d4c619d
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server.cpp
@@ -0,0 +1,157 @@
+// $Id$
+
+// server.cpp
+// This version uses the Implementation Repository.
+
+#include "Test_i.h"
+#include "Server_ORBInitializer.h"
+
+#include "tao/IORTable/IORTable.h"
+#include "tao/PortableServer/Root_POA.h"
+#include "tao/ImR_Client/ImR_Client.h"
+#include "tao/ORBInitializer_Registry.h"
+
+#include "ace/streams.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_unistd.h"
+
+namespace
+{
+ ACE_CString toStr(int n)
+ {
+ char buf[20];
+ return ACE_OS::itoa(n, buf, 10);
+ }
+}
+
+PortableServer::POA_ptr
+createPOA (PortableServer::POA_ptr root_poa,
+ bool share_mgr,
+ const char* poa_name)
+{
+ PortableServer::LifespanPolicy_var life =
+ root_poa->create_lifespan_policy(PortableServer::PERSISTENT);
+
+ PortableServer::IdAssignmentPolicy_var assign =
+ root_poa->create_id_assignment_policy(PortableServer::USER_ID);
+
+ CORBA::PolicyList pols;
+ pols.length(2);
+ pols[0] = PortableServer::LifespanPolicy::_duplicate(life.in());
+ pols[1] = PortableServer::IdAssignmentPolicy::_duplicate(assign.in());
+
+ PortableServer::POAManager_var mgr = PortableServer::POAManager::_nil();
+ if (share_mgr)
+ {
+ mgr = root_poa->the_POAManager();
+ }
+ PortableServer::POA_var poa =
+ root_poa->create_POA(poa_name, mgr.in(), pols);
+
+ life->destroy();
+ assign->destroy();
+
+ return poa._retn();
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ int server_num = 0;
+ int die_on_ping = 1;
+ int ping_count = 0;
+
+ for (int i = 1; i < argc; i++)
+ {
+ ACE_TCHAR *c = argv[i];
+ if (ACE_OS::strcasecmp ("-n", c) == 0)
+ {
+ server_num = ACE_OS::atoi (argv[++i]);
+ }
+ else if (ACE_OS::strcasecmp ("-?",c) == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "usage: %s "
+ "-n Number of the server\n",
+ argv[0]));
+ return 1;
+ }
+ }
+
+ Server_ORBInitializer * temp_initializer;
+
+ ACE_NEW_RETURN (temp_initializer,
+ Server_ORBInitializer (&ping_count),
+ -1); // No exceptions yet!
+ PortableInterceptor::ORBInitializer_var initializer =
+ temp_initializer;
+
+ PortableInterceptor::register_orb_initializer (initializer.in ());
+
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
+
+ CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
+ PortableServer::POA_var root_poa = PortableServer::POA::_narrow(obj.in());
+
+ PortableServer::POAManager_var mgr = root_poa->the_POAManager();
+
+ ACE_CString poa_name_base = ACE_CString("TestObject_") + toStr (server_num);
+ PortableServer::POA_var test_poa;
+ test_poa = createPOA(root_poa.in (), true, poa_name_base.c_str ());
+ temp_initializer->set_poa (test_poa.in());
+
+ mgr->activate();
+
+ PortableServer::Servant_var<Test_i> test_servant =
+ new Test_i(server_num);
+
+ PortableServer::ObjectId_var object_id =
+ PortableServer::string_to_ObjectId("test_object");
+
+ //
+ // Activate the servant with the test POA,
+ // obtain its object reference, and get a
+ // stringified IOR.
+ //
+ test_poa->activate_object_with_id(object_id.in(), test_servant.in());
+
+ //
+ // Create binding between "TestService" and
+ // the test object reference in the IOR Table.
+ // Use a TAO extension to get the non imrified poa
+ // to avoid forwarding requests back to the ImR.
+
+ TAO_Root_POA* tpoa = dynamic_cast<TAO_Root_POA*>(test_poa.in());
+ obj = tpoa->id_to_reference_i(object_id.in(), false);
+ CORBA::String_var test_ior = orb->object_to_string(obj.in());
+ obj = orb->resolve_initial_references("IORTable");
+ IORTable::Table_var table = IORTable::Table::_narrow(obj.in());
+ table->bind(poa_name_base.c_str (), test_ior.in());
+
+ ACE_DEBUG ((LM_DEBUG, "Started Server %s \n",
+ poa_name_base.c_str()));
+
+ {
+ ACE_CString status_file = poa_name_base + ACE_CString(".status");
+ ofstream out(status_file.c_str ());
+ out << "started" << endl;
+ }
+
+ while (ping_count < die_on_ping)
+ {
+ orb->perform_work ();
+ }
+
+ root_poa->destroy(1,1);
+ orb->destroy();
+
+ }
+ catch(const CORBA::Exception& ex) {
+ ex._tao_print_exception ("Server main()");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.cpp b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.cpp
new file mode 100644
index 00000000000..7a1877b3a29
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.cpp
@@ -0,0 +1,98 @@
+// $Id$
+
+#include "server_interceptor.h"
+#include "tao/OctetSeqC.h"
+
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+
+Ping_Death_Request_Interceptor::Ping_Death_Request_Interceptor (int *counter)
+ : myname_ ("Ping_Death_Interceptor"),
+ counter_ (counter),
+ poa_ (PortableServer::POA::_nil())
+{
+}
+
+Ping_Death_Request_Interceptor::~Ping_Death_Request_Interceptor (void)
+{
+}
+
+void
+Ping_Death_Request_Interceptor::set_poa (PortableServer::POA_ptr poa)
+{
+ poa_ = PortableServer::POA::_duplicate (poa);
+}
+
+char *
+Ping_Death_Request_Interceptor::name (void)
+{
+ return CORBA::string_dup (this->myname_);
+}
+
+void
+Ping_Death_Request_Interceptor::destroy (void)
+{
+}
+
+void
+Ping_Death_Request_Interceptor::receive_request_service_contexts (
+ PortableInterceptor::ServerRequestInfo_ptr ri)
+{
+ CORBA::String_var operation = ri->operation ();
+
+ if (ACE_OS::strcmp (operation.in(), "ping") != 0)
+ {
+ return;
+ }
+
+ if (this->counter_ != 0)
+ {
+ ++(*counter_);
+ }
+ if (CORBA::is_nil(this->poa_))
+ {
+ return;
+ }
+ try
+ {
+ this->poa_->destroy (1,1);
+ }
+ catch (CORBA::Exception &ex)
+ {
+ ACE_DEBUG ((LM_DEBUG, "(%P) deactivate raised %s\n",
+ ex._name()));
+ }
+ throw ::CORBA::TRANSIENT
+ ( CORBA::SystemException::_tao_minor_code (TAO_POA_HOLDING, 1),
+ CORBA::COMPLETED_NO);
+
+}
+
+
+void
+Ping_Death_Request_Interceptor::receive_request (
+ PortableInterceptor::ServerRequestInfo_ptr)
+{
+ // Do nothing
+}
+
+void
+Ping_Death_Request_Interceptor::send_reply (
+ PortableInterceptor::ServerRequestInfo_ptr)
+{
+ // Do Nothing
+}
+
+void
+Ping_Death_Request_Interceptor::send_exception (
+ PortableInterceptor::ServerRequestInfo_ptr)
+{
+ // Do Nothing
+}
+
+void
+Ping_Death_Request_Interceptor::send_other (
+ PortableInterceptor::ServerRequestInfo_ptr)
+{
+ // Do Nothing
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.h b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.h
new file mode 100644
index 00000000000..934b92a2264
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.h
@@ -0,0 +1,62 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#ifndef TAO_SERVER_INTERCEPTOR_H
+#define TAO_SERVER_INTERCEPTOR_H
+
+#include "tao/PI_Server/PI_Server.h"
+#include "tao/PortableInterceptorC.h"
+#include "tao/PortableServer/POAC.h"
+#include "tao/LocalObject.h"
+#include "tao/ORB.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4250)
+#endif /* _MSC_VER */
+
+class Ping_Death_Request_Interceptor
+ : public virtual PortableInterceptor::ServerRequestInterceptor,
+ public virtual ::CORBA::LocalObject
+{
+ // = Server-side echo interceptor. For checking interceptor visually only.
+public:
+ Ping_Death_Request_Interceptor (int *counter);
+ // cotr.
+
+ ~Ping_Death_Request_Interceptor ();
+ // dotr.
+ void set_poa (PortableServer::POA_ptr poa);
+
+ virtual char * name (void);
+ // Canonical name of the interceptor.
+
+ virtual void destroy (void);
+
+ virtual void receive_request (PortableInterceptor::ServerRequestInfo_ptr ri);
+
+ virtual void receive_request_service_contexts (
+ PortableInterceptor::ServerRequestInfo_ptr);
+
+ virtual void send_reply (PortableInterceptor::ServerRequestInfo_ptr ri);
+
+ virtual void send_exception (PortableInterceptor::ServerRequestInfo_ptr ri);
+
+ virtual void send_other (PortableInterceptor::ServerRequestInfo_ptr);
+
+private:
+ const char *myname_;
+ int *counter_;
+ PortableServer::POA_var poa_;
+};
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif /* _MSC_VER */
+
+#endif /* TAO_SERVER_INTERCEPTOR_H */