From 385483de11a927d5ee4935a050530444aa671685 Mon Sep 17 00:00:00 2001 From: Phil Mesnier Date: Mon, 3 Jun 2013 21:24:44 +0000 Subject: Mon Jun 3 21:16:43 UTC 2013 Phil Mesnier --- TAO/ChangeLog | 37 ++++ TAO/bin/tao_other_tests.lst | 1 + .../ImplRepo_Service/AsyncAccessManager.cpp | 32 +++ TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp | 14 +- TAO/orbsvcs/ImplRepo_Service/LiveCheck.cpp | 78 ++++++- TAO/orbsvcs/ImplRepo_Service/LiveCheck.h | 9 + TAO/orbsvcs/tests/ImplRepo/ping_interrupt/README | 7 + .../ping_interrupt/Server_ORBInitializer.cpp | 53 +++++ .../ping_interrupt/Server_ORBInitializer.h | 51 +++++ TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test.idl | 10 + .../tests/ImplRepo/ping_interrupt/Test_i.cpp | 21 ++ TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.h | 24 +++ .../ImplRepo/ping_interrupt/ping_interrupt.mpc | 25 +++ .../tests/ImplRepo/ping_interrupt/run_test.pl | 231 +++++++++++++++++++++ .../tests/ImplRepo/ping_interrupt/server.cpp | 157 ++++++++++++++ .../ImplRepo/ping_interrupt/server_interceptor.cpp | 98 +++++++++ .../ImplRepo/ping_interrupt/server_interceptor.h | 62 ++++++ 17 files changed, 901 insertions(+), 9 deletions(-) create mode 100644 TAO/orbsvcs/tests/ImplRepo/ping_interrupt/README create mode 100644 TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.cpp create mode 100644 TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Server_ORBInitializer.h create mode 100644 TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test.idl create mode 100644 TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.cpp create mode 100644 TAO/orbsvcs/tests/ImplRepo/ping_interrupt/Test_i.h create mode 100644 TAO/orbsvcs/tests/ImplRepo/ping_interrupt/ping_interrupt.mpc create mode 100755 TAO/orbsvcs/tests/ImplRepo/ping_interrupt/run_test.pl create mode 100644 TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server.cpp create mode 100644 TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.cpp create mode 100644 TAO/orbsvcs/tests/ImplRepo/ping_interrupt/server_interceptor.h 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 + + * 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 * 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(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()); @@ -396,10 +423,33 @@ PingReceiver::~PingReceiver (void) { } +void +PingReceiver::cancel (void) +{ + if (ImR_Locator_i::debug () > 4) + { + const char *server = ""; + 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 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_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(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 */ -- cgit v1.2.1