summaryrefslogtreecommitdiff
path: root/TAO
diff options
context:
space:
mode:
authorPhil Mesnier <mesnier_p@ociweb.com>2013-12-04 17:15:34 +0000
committerPhil Mesnier <mesnier_p@ociweb.com>2013-12-04 17:15:34 +0000
commit323aff2a5b4a1d71f4cff6544f8fd270b07a5f56 (patch)
tree5502c5b92b41948b975da842dc0b9be4dbdb5c8b /TAO
parentfa6fd7ade3195bd4213a27e360af7e6aaf9fea30 (diff)
downloadATCD-323aff2a5b4a1d71f4cff6544f8fd270b07a5f56.tar.gz
Wed Dec 4 17:13:02 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com>
* bin/tao_other_tests.lst: Added new test. * orbsvcs/ImplRepo_Service/AsyncAccessManager.h: * orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp: * orbsvcs/ImplRepo_Service/ImR_Activator.idl: * orbsvcs/ImplRepo_Service/ImR_Activator_i.h: * orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp: * orbsvcs/ImplRepo_Service/ImR_Locator.idl: * orbsvcs/ImplRepo_Service/ImR_Locator_i.h: * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp: * orbsvcs/ImplRepo_Service/tao_imr_i.h: * orbsvcs/ImplRepo_Service/tao_imr_i.cpp: Adding two new features to the IMR client interface. First is a kill command that has the activator send a signal to a child process. Also a new link command that allows the ImR locator to recognize two or more POAs are part of the same process. The link command implementation is still under development. * orbsvcs/tests/ImplRepo/kill_server: New test case for the kill command. * tao/ImR_Client/ImplRepo.idl: New extension interface added to define new operations.
Diffstat (limited to 'TAO')
-rw-r--r--TAO/ChangeLog27
-rw-r--r--TAO/bin/tao_other_tests.lst1
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp12
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.h3
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Activator.idl10
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp43
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h15
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl2
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp79
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h10
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp218
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/tao_imr_i.h49
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/kill_server/README4
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/kill_server/Terminator.cpp45
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/kill_server/Terminator.h13
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/kill_server/Test.idl11
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/kill_server/Test_i.cpp73
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/kill_server/Test_i.h41
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/kill_server/client.cpp79
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/kill_server/kill_server.mpc34
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/kill_server/run_test.pl338
-rw-r--r--TAO/orbsvcs/tests/ImplRepo/kill_server/server.cpp177
-rw-r--r--TAO/tao/ImR_Client/ImplRepo.idl28
23 files changed, 1287 insertions, 25 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index 7e388bc9bd2..aabf4afaa15 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,30 @@
+Wed Dec 4 17:13:02 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com>
+
+ * bin/tao_other_tests.lst:
+ Added new test.
+
+ * orbsvcs/ImplRepo_Service/AsyncAccessManager.h:
+ * orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp:
+ * orbsvcs/ImplRepo_Service/ImR_Activator.idl:
+ * orbsvcs/ImplRepo_Service/ImR_Activator_i.h:
+ * orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp:
+ * orbsvcs/ImplRepo_Service/ImR_Locator.idl:
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.h:
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+ * orbsvcs/ImplRepo_Service/tao_imr_i.h:
+ * orbsvcs/ImplRepo_Service/tao_imr_i.cpp:
+ Adding two new features to the IMR client interface. First is
+ a kill command that has the activator send a signal to a child
+ process. Also a new link command that allows the ImR locator
+ to recognize two or more POAs are part of the same process.
+ The link command implementation is still under development.
+
+ * orbsvcs/tests/ImplRepo/kill_server:
+ New test case for the kill command.
+
+ * tao/ImR_Client/ImplRepo.idl:
+ New extension interface added to define new operations.
+
Wed Nov 27 02:37:17 UTC 2013 Douglas C. Schmidt <schmidt@dre.vanderbilt.edu>
* VERSION: Updated the URL to point to Vandy not WUSTl.
diff --git a/TAO/bin/tao_other_tests.lst b/TAO/bin/tao_other_tests.lst
index d6dbc8c3b13..24e3f66d2ca 100644
--- a/TAO/bin/tao_other_tests.lst
+++ b/TAO/bin/tao_other_tests.lst
@@ -127,6 +127,7 @@ TAO/orbsvcs/tests/ImplRepo/run_test.pl persistent_listingcorrupt -replica: !MINI
TAO/orbsvcs/tests/ImplRepo/run_test.pl persistent_activatorcorrupt -replica: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !Win32
TAO/orbsvcs/tests/ImplRepo/run_test.pl persistent_servercorrupt -replica: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !Win32
TAO/orbsvcs/tests/ImplRepo/NameService/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO
+TAO/orbsvcs/tests/ImplRepo/kill_server/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !LynxOS !ACE_FOR_TAO
TAO/orbsvcs/tests/ImplRepo/locked/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !LynxOS !ACE_FOR_TAO
TAO/orbsvcs/tests/ImplRepo/scale/run_test.pl -servers 5 -objects 5: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !LynxOS
TAO/orbsvcs/tests/ImplRepo/scale_clients/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !LynxOS
diff --git a/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp b/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp
index b4c8b29e356..47291ceeaf6 100644
--- a/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.cpp
@@ -405,6 +405,18 @@ ActivatorReceiver::shutdown_excep (Messaging::ExceptionHolder * )
// no-op, just satisfy virtual function
}
+void
+ActivatorReceiver::kill_server (CORBA::Boolean )
+{
+ // no-op, just satisfy virtual function
+}
+
+void
+ActivatorReceiver::kill_server_excep (Messaging::ExceptionHolder * )
+{
+ // no-op, just satisfy virtual function
+}
+
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
diff --git a/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.h b/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.h
index 02c490c7bb9..e729e750a8b 100644
--- a/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.h
+++ b/TAO/orbsvcs/ImplRepo_Service/AsyncAccessManager.h
@@ -131,6 +131,9 @@ public:
void shutdown (void);
void shutdown_excep (Messaging::ExceptionHolder * excep_holder);
+ void kill_server (CORBA::Boolean);
+ void kill_server_excep (Messaging::ExceptionHolder * excep_holder);
+
private:
AsyncAccessManager_ptr aam_;
PortableServer::POA_var poa_;
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator.idl b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator.idl
index 3dce9f3009d..9dc608fce75 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator.idl
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator.idl
@@ -9,10 +9,16 @@ module ImplementationRepository
interface Activator
{
/// Tells the activator to launch a server with the given information.
- void start_server(in string name, in string cmdline,
+ void start_server (in string name, in string cmdline,
in string dir, in EnvironmentList env) raises(CannotActivate);
- oneway void shutdown();
+ oneway void shutdown ();
+ };
+
+ interface ActivatorExt : Activator
+ {
+ /// Tells the activator to send a signal to a child process
+ boolean kill_server (in string name, in short signum);
};
};
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
index d75b0b0b367..4857ab3f665 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
@@ -11,6 +11,8 @@
#include "ace/ARGV.h"
#include "ace/OS_NS_unistd.h"
#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_signal.h"
+
#include "ace/os_include/os_netdb.h"
static ACE_CString getHostName ()
@@ -138,8 +140,8 @@ ImR_Activator_i::init_with_orb (CORBA::ORB_ptr orb, const Activator_Options& opt
PortableServer::ObjectId_var id = PortableServer::string_to_ObjectId ("ImR_Activator");
this->imr_poa_->activate_object_with_id (id.in (), this);
obj = this->imr_poa_->id_to_reference (id.in ());
- ImplementationRepository::Activator_var activator =
- ImplementationRepository::Activator::_narrow (obj.in ());
+ ImplementationRepository::ActivatorExt_var activator =
+ ImplementationRepository::ActivatorExt::_narrow (obj.in ());
ACE_ASSERT(! CORBA::is_nil (activator.in ()));
CORBA::String_var ior = this->orb_->object_to_string (activator.in ());
@@ -280,6 +282,30 @@ ImR_Activator_i::shutdown (bool wait_for_completion)
this->orb_->shutdown (wait_for_completion);
}
+CORBA::Boolean
+ImR_Activator_i::kill_server (const char* name, CORBA::Short signum)
+{
+ if (debug_ > 1)
+ ORBSVCS_DEBUG((LM_DEBUG,
+ "ImR Activator: Killing server <%s>...\n",
+ name));
+ for (ProcessMap::iterator iter = process_map_.begin();
+ iter != process_map_.end (); iter++)
+ {
+ if (iter->item () == name)
+ {
+ pid_t pid = iter->key ();
+ if (debug_ > 1)
+ ORBSVCS_DEBUG((LM_DEBUG,
+ "ImR Activator: Killing server <%s> "
+ "signal %d to pid %d\n",
+ name, signum, pid));
+ return ACE_OS::kill (pid, signum) == 0;
+ }
+ }
+ return false;
+}
+
void
ImR_Activator_i::start_server(const char* name,
const char* cmdline,
@@ -345,13 +371,7 @@ ImR_Activator_i::start_server(const char* name,
"ImR Activator: register death handler for process %d\n", pid));
}
this->process_mgr_.register_handler (this, pid);
-
- // We only bind to the process_map_ if we want to notify
- // the locator of a process' death.
- if (notify_imr_)
- {
- this->process_map_.rebind (pid, name);
- }
+ this->process_map_.rebind (pid, name);
}
if (debug_ > 0)
@@ -388,7 +408,10 @@ ImR_Activator_i::handle_exit (ACE_Process * process)
ACE_TEXT ("ImR Activator: Notifying ImR that %s has exited.\n"),
name.c_str()));
}
- this->locator_->notify_child_death (name.c_str());
+ if (this->notify_imr_)
+ {
+ this->locator_->notify_child_death (name.c_str());
+ }
}
}
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h
index c0b22e1877e..54d169d2aa7 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h
@@ -57,17 +57,18 @@ struct ACE_Equal_To_pid_t
* that can be done by the ImR_Activator.
*
*/
-class Activator_Export ImR_Activator_i : public POA_ImplementationRepository::Activator,
+class Activator_Export ImR_Activator_i : public POA_ImplementationRepository::ActivatorExt,
public ACE_Event_Handler
{
-public:
+ public:
ImR_Activator_i (void);
- void start_server (
- const char* name,
- const char* cmdline,
- const char* dir,
- const ImplementationRepository::EnvironmentList & env);
+ void start_server (const char* name,
+ const char* cmdline,
+ const char* dir,
+ const ImplementationRepository::EnvironmentList & env);
+
+ CORBA::Boolean kill_server (const char* name, CORBA::Short signum);
void shutdown(void);
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl
index c61361b8165..992cc695f72 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl
@@ -5,7 +5,7 @@
module ImplementationRepository
{
- interface Locator : Administration
+ interface Locator : AdministrationExt
{
/// returns a token that can be used (along with activator name) to
/// unregister the activator.
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
index b7e34b9a29b..151086cb1c6 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
@@ -735,6 +735,85 @@ ImR_Locator_i::parse_id (const char* id,
}
void
+ImR_Locator_i::link_servers
+(ImplementationRepository::AMH_AdministrationExtResponseHandler_ptr _tao_rh,
+ const char * name,
+ const CORBA::StringSeq & peers)
+{
+ Server_Info_Ptr root_si;
+ if (!this->get_info_for_name (name, root_si))
+ {
+ CORBA::Exception *ex =
+ new ImplementationRepository::NotFound;
+ ImplementationRepository::AMH_AdministrationExtExceptionHolder h (ex);
+ _tao_rh->link_servers_excep (&h);
+ return;
+ }
+
+ for (size_t i = 0; i < peers.length(); i++)
+ {
+ Server_Info_Ptr si;
+ if (this->get_info_for_name (peers[i], si))
+ {
+ }
+ }
+
+ _tao_rh->link_servers ();
+ return;
+}
+
+void
+ImR_Locator_i::kill_server
+(ImplementationRepository::AMH_AdministrationExtResponseHandler_ptr _tao_rh,
+ const char * name,
+ CORBA::Short signum)
+{
+ Server_Info_Ptr si;
+ if (!this->get_info_for_name (name, si))
+ {
+ CORBA::Exception *ex =
+ new ImplementationRepository::NotFound;
+ ImplementationRepository::AMH_AdministrationExtExceptionHolder h (ex);
+ _tao_rh->kill_server_excep (&h);
+ return;
+ }
+
+ UpdateableServerInfo info (this->repository_.get(), si, true);
+ if (info->activation_mode == ImplementationRepository::PER_CLIENT)
+ {
+ CORBA::Exception *ex =
+ new ImplementationRepository::CannotComplete ("per-client server");
+ ImplementationRepository::AMH_AdministrationExtExceptionHolder h (ex);
+ _tao_rh->kill_server_excep (&h);
+ return;
+ }
+
+ Activator_Info_Ptr ainfo = this->get_activator (si->activator);
+ ImplementationRepository::ActivatorExt_var actext =
+ ImplementationRepository::ActivatorExt::_narrow (ainfo->activator.in());
+ if (CORBA::is_nil (actext.in()))
+ {
+ CORBA::Exception *ex =
+ new ImplementationRepository::CannotComplete ("activator incompatible");
+ ImplementationRepository::AMH_AdministrationExtExceptionHolder h (ex);
+ _tao_rh->kill_server_excep (&h);
+ return;
+ }
+ if (!actext->kill_server (name, signum))
+ {
+ CORBA::Exception *ex =
+ new ImplementationRepository::NotFound;
+ ImplementationRepository::AMH_AdministrationExtExceptionHolder h (ex);
+ _tao_rh->kill_server_excep (&h);
+ }
+ else
+ {
+ _tao_rh->kill_server ();
+ }
+ return;
+}
+
+void
ImR_Locator_i::remove_server
(ImplementationRepository::AMH_AdministrationResponseHandler_ptr _tao_rh,
const char* name)
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h
index ebc01e2c2b3..45a39b60cee 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h
@@ -89,6 +89,16 @@ public:
const char * name,
const ImplementationRepository::StartupOptions &options);
+ virtual void link_servers
+ (ImplementationRepository::AMH_AdministrationExtResponseHandler_ptr _tao_rh,
+ const char * name,
+ const CORBA::StringSeq & peers);
+
+ virtual void kill_server
+ (ImplementationRepository::AMH_AdministrationExtResponseHandler_ptr _tao_rh,
+ const char * name,
+ CORBA::Short signum);
+
virtual void remove_server
(ImplementationRepository::AMH_AdministrationResponseHandler_ptr _tao_rh,
const char * name);
diff --git a/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp b/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp
index 4a51e64ff7a..ba9cc6235d7 100644
--- a/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp
@@ -156,6 +156,10 @@ TAO_IMR_Op::make_op (const ACE_TCHAR *op_name)
return new TAO_IMR_Op_Autostart();
else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("ior")) == 0)
return new TAO_IMR_Op_IOR();
+ else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("kill")) == 0)
+ return new TAO_IMR_Op_Kill ();
+ else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("link")) == 0)
+ return new TAO_IMR_Op_Link ();
else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("list")) == 0)
return new TAO_IMR_Op_List ();
else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("remove")) == 0)
@@ -394,6 +398,122 @@ TAO_IMR_Op_IOR::parse (int argc, ACE_TCHAR **argv)
}
void
+TAO_IMR_Op_Kill::print_usage (void)
+{
+ ORBSVCS_ERROR ((LM_ERROR, "Sends a signal to the designated process\n"
+ "The process must have been started by the ImR and may not use\n"
+ "per-client activation\n"
+ "Usage: tao_imr [options] kill [name] [command-arguments]\n"
+ " where [options] are ORB options\n"
+ " where [name] is the registered POA name the peers link to\n"
+ " where [command-arguments] can be\n"
+ " -s signum default 2, the signal to be sent to the process for"
+ " named server\n"));
+}
+
+int
+TAO_IMR_Op_Kill::parse (int argc, ACE_TCHAR **argv)
+{
+ int server_flag = 0;
+
+ if (argc > 1 && argv[1][0] != '-')
+ {
+ this->server_name_ = ACE_TEXT_ALWAYS_CHAR(argv[1]);
+ server_flag = 2;
+ }
+
+ // Skip both the program name and the "list" command
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("s:h"), server_flag);
+
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ {
+ switch (c)
+ {
+ case 's': //signum
+ this->signum_ = ACE_OS::strtol (get_opts.opt_arg (), 0, 10);
+ break;
+ case 'h': // display help
+ this->print_usage ();
+ return -1;
+ default:
+ ORBSVCS_ERROR((LM_ERROR, "ERROR : Unknown option '%c'\n", (char) c));
+ this->print_usage ();
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void
+TAO_IMR_Op_Link::print_usage (void)
+{
+ ORBSVCS_ERROR ((LM_ERROR, "Links multiple POAs to a single executable\n"
+ "\n"
+ "Usage: tao_imr [options] link [name] [peers]\n"
+ " where [options] are ORB options\n"
+ " where [name] is the registered POA name the peers link to\n"
+ " where [command-arguments] can be\n"
+ " -p peers provides a comma separated list of additional POAs that are\n"
+ " part of the same executable. -p may be repeated\n"));
+}
+
+int
+TAO_IMR_Op_Link::parse (int argc, ACE_TCHAR **argv)
+{
+ int server_flag = 0;
+
+ if (argc > 1 && argv[1][0] != '-')
+ {
+ this->server_name_ = ACE_TEXT_ALWAYS_CHAR(argv[1]);
+ server_flag = 2;
+ }
+
+ // Skip both the program name and the "list" command
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("p:h"), server_flag);
+
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ {
+ switch (c)
+ {
+ case 'p': //list of peers
+ {
+ char *arg = get_opts.opt_arg ();
+ size_t last = this->peers_.length ();
+ size_t num = 0;
+ char *c = arg;
+ while (c != 0)
+ {
+ num++;
+ c = ACE_OS::strchr (c, ',');
+ }
+ num += last;
+ this->peers_.length (num);
+ while (last < num)
+ {
+ c = ACE_OS::strchr (arg, ',');
+ *c = 0;
+ this->peers_[last++] = CORBA::string_dup (arg);
+ arg = c+1;
+ }
+ break;
+ }
+ case 'h': // display help
+ this->print_usage ();
+ return -1;
+ default:
+ ORBSVCS_ERROR((LM_ERROR, "ERROR : Unknown option '%c'\n", (char) c));
+ this->print_usage ();
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void
TAO_IMR_Op_List::print_usage (void)
{
ORBSVCS_ERROR ((LM_ERROR, "Lists all or one of the servers in the Implementation Repository\n"
@@ -709,9 +829,10 @@ TAO_IMR_Op_Activate::run (void)
}
catch (const ImplementationRepository::CannotActivate& ex)
{
- ORBSVCS_ERROR ((LM_ERROR, "Cannot activate server <%C>, reason: <%s>\n",
- this->server_name_.c_str (),
- ex.reason.in ()));
+ ORBSVCS_ERROR ((LM_ERROR,
+ "Cannot activate server <%C>, reason: <%s>\n",
+ this->server_name_.c_str (),
+ ex.reason.in ()));
return TAO_IMR_Op::CANNOT_ACTIVATE;
}
catch (const ImplementationRepository::NotFound&)
@@ -863,6 +984,93 @@ TAO_IMR_Op_IOR::run (void)
}
int
+TAO_IMR_Op_Kill::run (void)
+{
+ ACE_ASSERT (! CORBA::is_nil(imr_));
+
+ ImplementationRepository::AdministrationExt_var imrext =
+ ImplementationRepository::AdministrationExt::_narrow (imr_);
+ if (CORBA::is_nil (imrext.in()))
+ {
+ ORBSVCS_ERROR_RETURN
+ ((LM_ERROR,
+ ACE_TEXT ("Error: requested IMR does not support the kill operation\n")),
+ -1);
+ }
+
+ try
+ {
+ imrext->kill_server (this->server_name_.c_str(), this->signum_);
+ }
+ catch (const ImplementationRepository::NotFound &)
+ {
+ ORBSVCS_ERROR ((LM_ERROR,
+ "Could not find server <%C>.\n",
+ this->server_name_.c_str ()));
+ return TAO_IMR_Op::NOT_FOUND;
+ }
+ catch (const ImplementationRepository::CannotComplete& ex)
+ {
+ ORBSVCS_ERROR ((LM_ERROR,
+ "Cannot complete kill of <%C>, reason: <%s>\n",
+ this->server_name_.c_str (),
+ ex.reason.in ()));
+ return TAO_IMR_Op::CANNOT_COMPLETE;
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Kill");
+ return TAO_IMR_Op::UNKNOWN;
+ }
+
+ return TAO_IMR_Op::NORMAL;
+}
+
+int
+TAO_IMR_Op_Link::run (void)
+{
+ ACE_ASSERT (! CORBA::is_nil(imr_));
+
+ ImplementationRepository::AdministrationExt_var imrext =
+ ImplementationRepository::AdministrationExt::_narrow (imr_);
+ if (CORBA::is_nil (imrext.in()))
+ {
+ ORBSVCS_ERROR_RETURN
+ ((LM_ERROR,
+ ACE_TEXT ("Error: requested IMR does not support the kill operation\n")),
+ -1);
+ }
+
+ try
+ {
+ imrext->link_servers (this->server_name_.c_str(), this->peers_);
+ }
+ catch (const ImplementationRepository::NotFound &)
+ {
+ ORBSVCS_ERROR ((LM_ERROR,
+ "Could not find server <%C>.\n",
+ this->server_name_.c_str ()));
+ return TAO_IMR_Op::NOT_FOUND;
+ }
+ catch (const ImplementationRepository::CannotComplete& ex)
+ {
+ ORBSVCS_ERROR ((LM_ERROR,
+ "Cannot complete kill of <%C>, reason: <%s>\n",
+ this->server_name_.c_str (),
+ ex.reason.in ()));
+ return TAO_IMR_Op::CANNOT_COMPLETE;
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Kill");
+ return TAO_IMR_Op::UNKNOWN;
+ }
+
+ return TAO_IMR_Op::NORMAL;
+}
+
+
+int
TAO_IMR_Op_List::run (void)
{
ACE_ASSERT (! CORBA::is_nil(imr_));
@@ -905,7 +1113,9 @@ TAO_IMR_Op_List::run (void)
}
catch (const ImplementationRepository::NotFound&)
{
- ORBSVCS_ERROR ((LM_ERROR, "Could not find server <%C>.\n", this->server_name_.c_str ()));
+ ORBSVCS_ERROR ((LM_ERROR,
+ "Could not find server <%C>.\n",
+ this->server_name_.c_str ()));
return TAO_IMR_Op::NOT_FOUND;
}
catch (const CORBA::Exception& ex)
diff --git a/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.h b/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.h
index 36e5de34c49..8c939680041 100644
--- a/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.h
+++ b/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.h
@@ -85,7 +85,8 @@ public:
NO_PERMISSION,
ALREADY_REGISTERED,
CANNOT_ACTIVATE,
- NOT_FOUND
+ NOT_FOUND,
+ CANNOT_COMPLETE
};
/// Factory.
@@ -182,6 +183,52 @@ protected:
/**
+ * @class TAO_IMR_Op_Kill
+ *
+ * @brief Kill Operation
+ *
+ * Kill is used to unregister a server in the IMR.
+ */
+class TAO_IMR_Op_Kill : public TAO_IMR_Op
+{
+public:
+ virtual int parse (int argc, ACE_TCHAR **argv);
+ virtual int run (void);
+
+protected:
+ /// Prints a message about the usage
+ void print_usage (void);
+
+ ACE_CString server_name_;
+ int signum_;
+};
+
+
+/**
+ * @class TAO_IMR_Op_Link
+ *
+ * @brief Link Operation
+ *
+ * Link is used to unregister a server in the IMR.
+ */
+class TAO_IMR_Op_Link : public TAO_IMR_Op
+{
+public:
+ virtual int parse (int argc, ACE_TCHAR **argv);
+ virtual int run (void);
+
+protected:
+ /// Prints a message about the usage
+ void print_usage (void);
+
+ ACE_CString server_name_;
+
+ CORBA::StringSeq peers_;
+};
+
+
+
+/**
* @class TAO_IMR_Op_List
*
* @brief List Operation
diff --git a/TAO/orbsvcs/tests/ImplRepo/kill_server/README b/TAO/orbsvcs/tests/ImplRepo/kill_server/README
new file mode 100644
index 00000000000..a0bbae99648
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/kill_server/README
@@ -0,0 +1,4 @@
+$Id$
+
+This test starts up servers then uses the tao_imr kill command to force server
+termination via signal. \ No newline at end of file
diff --git a/TAO/orbsvcs/tests/ImplRepo/kill_server/Terminator.cpp b/TAO/orbsvcs/tests/ImplRepo/kill_server/Terminator.cpp
new file mode 100644
index 00000000000..88fb72467bf
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/kill_server/Terminator.cpp
@@ -0,0 +1,45 @@
+/* -*- C++ -*- $Id$ */
+
+#include "Terminator.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_unistd.h"
+
+int
+Terminator::open(void*)
+{
+ if(this->activate (THR_NEW_LWP | THR_JOINABLE,
+ 1) == -1)
+ {
+ ACE_ERROR_RETURN((LM_ERROR,
+ ACE_TEXT("Terminator::open Error spawning thread %p\n"),
+ "err="),
+ -1);
+ }
+ return 0;
+}
+
+int
+Terminator::svc()
+{
+ while (1)
+ {
+ ACE_Message_Block* mb = 0;
+ if (this->getq(mb) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t|%T) ERROR: Terminator::svc() could not get "
+ "message block from queue"), -1);
+ }
+
+ if (mb->msg_type () == ACE_Message_Block::MB_HANGUP)
+ {
+ mb->release ();
+ this->close ();
+ break;
+ }
+ int delay_secs = ACE_OS::atoi(mb->rd_ptr());
+ ACE_OS::sleep(delay_secs);
+ ACE_OS::abort();
+ }
+ return 0;
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/kill_server/Terminator.h b/TAO/orbsvcs/tests/ImplRepo/kill_server/Terminator.h
new file mode 100644
index 00000000000..29be200f03e
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/kill_server/Terminator.h
@@ -0,0 +1,13 @@
+/* -*- C++ -*- $Id$ */
+
+#include "ace/Task_T.h"
+
+class Terminator : public ACE_Task<ACE_MT_SYNCH>
+{
+ public:
+
+ virtual int open(void*);
+
+ virtual int svc();
+};
+
diff --git a/TAO/orbsvcs/tests/ImplRepo/kill_server/Test.idl b/TAO/orbsvcs/tests/ImplRepo/kill_server/Test.idl
new file mode 100644
index 00000000000..feaa629b0fa
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/kill_server/Test.idl
@@ -0,0 +1,11 @@
+// $Id$
+
+interface Test
+{
+
+ // Return the number of the server after a delay
+ short get_server_num ();
+
+ void pause (in char poa_id);
+ void resume (in char poa_id);
+};
diff --git a/TAO/orbsvcs/tests/ImplRepo/kill_server/Test_i.cpp b/TAO/orbsvcs/tests/ImplRepo/kill_server/Test_i.cpp
new file mode 100644
index 00000000000..cd7df0953d1
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/kill_server/Test_i.cpp
@@ -0,0 +1,73 @@
+/* -*- C++ -*- $Id$ */
+
+#include "Test_i.h"
+#include "Terminator.h"
+#include "ace/OS_NS_unistd.h"
+
+Test_i::Test_i (CORBA::Short server_num,
+ Terminator &terminator,
+ PortableServer::POA_ptr pa,
+ PortableServer::POA_ptr pb)
+ : mgr_a (pa->the_POAManager ()),
+ mgr_b (pb->the_POAManager ()),
+ server_num_ (server_num),
+ terminator_ (terminator)
+{
+}
+
+Test_i::~Test_i ()
+{
+ ACE_Message_Block *mb = 0;
+ ACE_NEW (mb,
+ ACE_Message_Block(0,
+ ACE_Message_Block::MB_HANGUP));
+ terminator_.putq (mb);
+ terminator_.wait ();
+}
+
+CORBA::Short
+Test_i::get_server_num (void)
+{
+ return this->server_num_;
+}
+
+void
+Test_i::pause (CORBA::Char poa_id)
+{
+ if (poa_id == 'a')
+ {
+ this->reset (this->mgr_a, true);
+ }
+ else if (poa_id == 'b')
+ {
+ this->reset (this->mgr_b, true);
+ }
+}
+
+void
+Test_i::resume (CORBA::Char poa_id)
+{
+ if (poa_id == 'a')
+ {
+ this->reset (this->mgr_a, false);
+ }
+ else if (poa_id == 'b')
+ {
+ this->reset (this->mgr_b, false);
+ }
+}
+
+void
+Test_i::reset (PortableServer::POAManager_var &mgr, bool pause)
+{
+ if (pause)
+ {
+ mgr->hold_requests (false);
+ }
+ else
+ {
+ mgr->activate ();
+ }
+}
+
+
diff --git a/TAO/orbsvcs/tests/ImplRepo/kill_server/Test_i.h b/TAO/orbsvcs/tests/ImplRepo/kill_server/Test_i.h
new file mode 100644
index 00000000000..6053300275d
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/kill_server/Test_i.h
@@ -0,0 +1,41 @@
+/* -*- 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 Terminator;
+
+class Test_i : public virtual POA_Test
+{
+public:
+ //Constructor
+ Test_i (short server_num,
+ Terminator &terminator,
+ PortableServer::POA_ptr pa,
+ PortableServer::POA_ptr pb);
+
+ //Destructor
+ virtual ~Test_i ();
+
+ virtual CORBA::Short get_server_num (void);
+
+ virtual void pause (CORBA::Char poa_id);
+ virtual void resume (CORBA::Char poa_id);
+
+private:
+ void reset (PortableServer::POAManager_var &mgr, bool pause);
+
+ PortableServer::POAManager_var mgr_a;
+ PortableServer::POAManager_var mgr_b;
+
+ CORBA::Short server_num_;
+ Terminator& terminator_;
+};
+
+#endif /* TEST_I_H_ */
diff --git a/TAO/orbsvcs/tests/ImplRepo/kill_server/client.cpp b/TAO/orbsvcs/tests/ImplRepo/kill_server/client.cpp
new file mode 100644
index 00000000000..c0abbab52c8
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/kill_server/client.cpp
@@ -0,0 +1,79 @@
+// $Id$
+
+#include "TestC.h"
+#include <iostream>
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_unistd.h"
+
+char pause_poa = ' ';
+char resume_poa = ' ';
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("p:r:"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'p':
+ pause_poa = *get_opts.opt_arg ();
+ break;
+
+ case 'r':
+ resume_poa = *get_opts.opt_arg ();
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates successful parsing of the command line
+ return 0;
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ try {
+ // Initialize orb
+ CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
+
+ if (parse_args (argc, argv) != 0)
+ return 1;
+
+ CORBA::Object_var obj = orb->resolve_initial_references("Test");
+ ACE_ASSERT (!CORBA::is_nil(obj.in()));
+ Test_var test = Test::_narrow( obj.in() );
+ ACE_ASSERT (!CORBA::is_nil(test.in()));
+
+ if (pause_poa != ' ')
+ {
+ test->pause (pause_poa);
+ }
+ if (resume_poa != ' ')
+ {
+ test->resume (resume_poa);
+ }
+ if (pause_poa == ' ' && resume_poa == ' ')
+ {
+ CORBA::Short n = test->get_server_num ();
+ ACE_DEBUG ((LM_DEBUG,
+ "Client received reply from server %d\n",
+ n));
+ }
+
+ return 0;
+
+ }
+ catch(const CORBA::Exception& ex) {
+ ex._tao_print_exception ("client:");
+ }
+
+ return -1;
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/kill_server/kill_server.mpc b/TAO/orbsvcs/tests/ImplRepo/kill_server/kill_server.mpc
new file mode 100644
index 00000000000..5ac2135b6b5
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/kill_server/kill_server.mpc
@@ -0,0 +1,34 @@
+// $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 {
+ after += *idl
+ exename = server
+ IDL_Files {
+ }
+ Source_Files {
+ Test_i.cpp
+ server.cpp
+ Terminator.cpp
+ TestC.cpp
+ TestS.cpp
+ }
+}
+
+project(*client): taoclient, anytypecode, avoids_minimum_corba, threads {
+ after += *idl
+ exename = client
+ Source_Files {
+ client.cpp
+ TestC.cpp
+ }
+ IDL_Files {
+ }
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/kill_server/run_test.pl b/TAO/orbsvcs/tests/ImplRepo/kill_server/run_test.pl
new file mode 100755
index 00000000000..c8ebc632d3f
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/kill_server/run_test.pl
@@ -0,0 +1,338 @@
+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;
+$debug_level = '0';
+
+my $servers_count = 2;
+my $servers_kill_count = 1;
+my $signalnum = 3;
+
+if ($#ARGV >= 0) {
+ for (my $i = 0; $i <= $#ARGV; $i++) {
+ if ($ARGV[$i] eq '-debug') {
+ $debug_level = '10';
+ $i++;
+ }
+ elsif ($ARGV[$i] eq "-servers") {
+ $i++;
+ $servers_count = $ARGV[$i];
+ }
+ elsif ($ARGV[$i] eq "-servers_to_kill") {
+ $i++;
+ $servers_kill_count = $ARGV[$i];
+ }
+ elsif ($ARGV[$i] eq "-signal") {
+ $i++;
+ $signalnum = $ARGV[$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 $cli = PerlACE::TestTarget::create_target (++$tgt_num) || die "Create target $tgt_num failed\n";
+my @srv;
+for(my $i = 0; $i < $servers_count; $i++) {
+ push (@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";
+my $client_wait_time = 10;
+
+$imriorfile = "imr_locator.ior";
+$actiorfile = "imr_activator.ior";
+
+my $imr_imriorfile = $imr->LocalFile ($imriorfile);
+my $act_imriorfile = $act->LocalFile ($imriorfile);
+my $ti_imriorfile = $ti->LocalFile ($imriorfile);
+my $srv_imriorfile = $srv[0]->LocalFile ($imriorfile);
+my $act_actiorfile = $act->LocalFile ($actiorfile);
+
+$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");
+
+$CLI = $cli->CreateProcess ("client");
+@SRV;
+my @srv_server_cmd;
+for(my $i = 0; $i < $servers_count; $i++) {
+ push (@SRV, $srv[$i]->CreateProcess ("server"));
+ my $server_cmd = $SRV[$i]->Executable();
+ push (@srv_server_cmd, $imr->LocalFile ($server_cmd));
+}
+# Make sure the files are gone, so we can wait on them.
+$imr->DeleteFile ($imriorfile);
+$act->DeleteFile ($imriorfile);
+$ti->DeleteFile ($imriorfile);
+$srv[0]->DeleteFile ($imriorfile);
+$act->DeleteFile ($actiorfile);
+
+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);
+ $srv[0]->DeleteFile ($imriorfile);
+ $act->DeleteFile ($actiorfile);
+
+ $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 servers_setup ()
+{
+ $ACT->Arguments ("-d 0 -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;
+ }
+
+ ##### Add servers to activator #####
+ for(my $i = 0; $i < $servers_count; $i++) {
+ my $status_file_name = $objprefix . "_$i.status";
+ $srv[$i]->DeleteFile ($status_file_name);
+
+ $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
+ "add $objprefix" . '_' . $i . "_a -c \"".
+ $srv_server_cmd[i].
+ " -ORBUseIMR 1 -n $i ".
+ "-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;
+ }
+ }
+
+ for(my $i = 0; $i < $servers_count; $i++ ) {
+ # For some reason the servers take forever to spawn when using the activator
+ $client_wait_time *= $obj_count;
+
+ if ($status == 1) {
+ last;
+ }
+ }
+
+}
+
+sub make_server_requests()
+{
+ print "Making requests to servers\n";
+
+ ##### Run client against servers to active them #####
+ for(my $i = 0; $i < $servers_count; $i++ ) {
+ my $status_file_name = $objprefix . "_$i.status";
+ $CLI->Arguments ("-ORBInitRef Test=corbaloc::localhost:$port/$objprefix" . '_' . $i . "_a" );
+ $CLI_status = $CLI->SpawnWaitKill ($cli->ProcessStartWaitInterval());
+ if ($CLI_status != 0) {
+ print STDERR "ERROR: client returned $CLI_status\n";
+ $status = 1;
+ last;
+ }
+ }
+}
+
+sub shutdown_servers(@)
+{
+ my $start_index = shift;
+ my $end_index = shift;
+ my $signum = shift;
+ for(my $i = $start_index; $i < $end_index; $i++ ) {
+ my $status_file_name = $objprefix . "_$i.status";
+ # Shutting down any server object within the server will shutdown the whole server
+ $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile ".
+ "kill $objprefix" . '_' . $i . "_a -s $signum" );
+ $TI_status = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ if ($TI_status != 0) {
+ print STDERR "ERROR: tao_imr shutdown returned $TI_status\n";
+ $status = 1;
+ last;
+ }
+ $srv[$i]->DeleteFile ($status_file_name);
+ }
+}
+
+sub list_active_servers($)
+{
+ my $list_options = shift;
+ my $start_time = time();
+ $TI->Arguments ("-ORBInitRef ImplRepoService=file://$ti_imriorfile list $list_options");
+ # Redirect output so we can count number of lines in output
+ redirect_output();
+ $result = $TI->SpawnWaitKill ($ti->ProcessStartWaitInterval());
+ my $list_time = time() - $start_time;
+ restore_output();
+ 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;
+ }
+ open (FILE, $stderr_file) or die "Can't open $stderr_file: $!";
+ $active_servers = 0;
+ while (<FILE>) {
+ print STDERR $_;
+ $active_servers++;
+ }
+ close FILE;
+ print STDERR "List took $list_time seconds.\n";
+ return $active_servers;
+}
+
+sub servers_list_test
+{
+ print "Running scale test with $servers_count servers and $obj_count objects.\n";
+
+ my $result = 0;
+ my $start_time = time();
+ $IMR->Arguments ("-d $debug_level -ORBDebugLevel $debug_level -v 1000 -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[0]->PutFile ($imriorfile) == -1) {
+ print STDERR "ERROR: cannot set file <$srv_imriorfile>\n";
+ $IMR->Kill (); $IMR->TimedWait (1);
+ return 1;
+ }
+
+ servers_setup();
+
+ # Make sure servers are active whether activator is used or not by making
+ # CORBA requests.
+ make_server_requests();
+
+ print "\nList of active servers before killing server(s)\n";
+ $active_servers_before_kill = list_active_servers("-a");
+
+ # Kill servers and verify listing of active servers is correct.
+ print "\nKilling $servers_kill_count servers\n";
+
+ shutdown_servers (0, $servers_kill_count, $signalnum);
+ sleep (2);
+
+ print "\nList of active servers after killing a server\n";
+ $active_servers_after_kill = list_active_servers ("-a");
+ if ($active_servers_after_kill != $active_servers_before_kill - $servers_kill_count) {
+ print STDERR
+ "ERROR: Excepted list of active servers after killing ".
+ "a server to be " . ($active_servers_before_kill - $servers_kill_count) .
+ " but was $active_servers_after_kill\n";
+ $status = 1;
+ }
+
+ print "\nList of servers registered with the ImR after killing a server\n";
+ list_active_servers ("");
+
+ print "\n";
+ shutdown_servers ($servers_kill_count, $servers_count, 9);
+
+ 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 ".
+ "[-servers <num=$servers_count>] ".
+ "[-servers_to_kill <num=$servers_kill_count>]\n";
+}
+
+###############################################################################
+###############################################################################
+
+my $ret = servers_list_test();
+
+exit $ret;
diff --git a/TAO/orbsvcs/tests/ImplRepo/kill_server/server.cpp b/TAO/orbsvcs/tests/ImplRepo/kill_server/server.cpp
new file mode 100644
index 00000000000..dce997ea1a1
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/kill_server/server.cpp
@@ -0,0 +1,177 @@
+// $Id$
+
+// server.cpp
+// This version uses the Implementation Repository.
+
+#include "Test_i.h"
+#include "Terminator.h"
+
+#include "tao/IORTable/IORTable.h"
+#include "tao/PortableServer/Root_POA.h"
+#include "tao/ImR_Client/ImR_Client.h"
+
+#include "ace/Get_Opt.h"
+#include "ace/streams.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_var root_poa;
+PortableServer::POA_var poa_a;
+PortableServer::POA_var poa_b;
+
+void
+createPOAs(ACE_CString &base)
+{
+ 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();
+ ACE_CString poa_name = base + ACE_CString ("_a");
+ poa_a = root_poa->create_POA(poa_name.c_str(), mgr.in(), pols);
+ poa_name = base + ACE_CString ("_b");
+ poa_b = root_poa->create_POA(poa_name.c_str(), mgr.in(), pols);
+}
+
+void
+activatePOAs(void)
+{
+ PortableServer::POAManager_var mgr = root_poa->the_POAManager ();
+ mgr->activate ();
+ mgr = poa_a->the_POAManager ();
+ mgr->activate ();
+ mgr = poa_b->the_POAManager ();
+ mgr->activate ();
+}
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ try {
+ CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
+
+ int server_num = 0;
+
+ ACE_Get_Opt get_opts (argc, argv, ACE_TEXT ("n:?"));
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'n':
+ server_num = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ case '?':
+ ACE_DEBUG ((LM_DEBUG,
+ "usage: %s "
+ "-d <seconds to delay before initializing POA> "
+ "-n Number of the server\n",
+ argv[0]));
+ return 1;
+ break;
+ }
+
+ CORBA::Object_var obj = orb->resolve_initial_references ("RootPOA");
+ root_poa = PortableServer::POA::_narrow (obj.in ());
+ // TAO_Root_POA::imr_client_adapter_name ("Test_Imr_Adapter");
+
+ ACE_CString base = ACE_CString ("TestObject_") + toStr (server_num);
+ createPOAs (base);
+
+ Terminator terminator;
+ if (terminator.open (0) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("main Error opening terminator\n")),-1);
+
+ PortableServer::Servant_var<Test_i> test_servant =
+ new Test_i (server_num, terminator, root_poa.in (), root_poa.in ());
+
+ PortableServer::ObjectId_var object_id =
+ PortableServer::string_to_ObjectId (base.c_str());
+
+ poa_a->activate_object_with_id (object_id.in(), test_servant.in ());
+ obj = poa_a->id_to_reference (object_id.in());
+
+ Test_var tva = Test::_narrow (obj.in());
+
+ poa_b->activate_object_with_id (object_id.in(), test_servant.in ());
+ obj = poa_b->id_to_reference (object_id.in());
+
+ Test_var tvb = Test::_narrow (obj.in());
+
+ // object_id = root_poa->activate_object (test_servant.in());
+
+ //
+ // This server is now ready to run.
+ // This version does not create an IOR
+ // file as demonstrated in the
+ // Developer's Guide. It assumes that
+ // users create IORs for the client using
+ // the tao_imr utility.
+ //
+ //
+ // Stop discarding requests.
+ //
+ activatePOAs ();
+
+ //
+ // 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*> (poa_a.in ());
+ ACE_ASSERT (tpoa != 0);
+
+ 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(base.c_str (), test_ior.in ());
+
+ test_ior = orb->object_to_string (tva.in());
+ base += "_a";
+ ACE_DEBUG ((LM_DEBUG, "%s:\n%s\n", base.c_str(), test_ior.in()));
+ table->bind (base.c_str (), test_ior.in ());
+ base[base.length()-1] = 'b';
+ test_ior = orb->object_to_string (tvb.in());
+ ACE_DEBUG ((LM_DEBUG, "%s:\n%s\n", base.c_str(), test_ior.in()));
+ table->bind (base.c_str (), test_ior.in ());
+
+ ACE_DEBUG ((LM_DEBUG,
+ "Started Server %s \n",
+ base.c_str()));
+
+ {
+ ACE_CString status_file = base + ACE_CString(".status");
+ ofstream out(status_file.c_str ());
+ out << "started" << endl;
+ }
+
+ orb->run();
+ 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/tao/ImR_Client/ImplRepo.idl b/TAO/tao/ImR_Client/ImplRepo.idl
index ff3abd7c5ba..a79502a3c05 100644
--- a/TAO/tao/ImR_Client/ImplRepo.idl
+++ b/TAO/tao/ImR_Client/ImplRepo.idl
@@ -8,6 +8,7 @@
#define TAO_IMRCLIENT_IMPLREPO_PIDL
#include "ServerObject.idl"
+#include "tao/StringSeq.pidl"
module ImplementationRepository
{
@@ -25,6 +26,13 @@ module ImplementationRepository
/// Object not found in the Implementation Repository
exception NotFound {};
+ /// Operation cannot be completed due to Activator version
+ /// or other incompatibility
+ exception CannotComplete
+ {
+ string reason;
+ };
+
/// One environment variable/value pair.
struct EnvironmentVariable
{
@@ -184,6 +192,26 @@ module ImplementationRepository
/// activators and servers first.
oneway void shutdown(in boolean activators, in boolean servers);
};
+
+
+
+
+ /**
+ * @brief The Extended Implementation Repository Administration Interface
+ *
+ * This interface adds operations in a way that maintains compatibility
+ */
+ interface AdministrationExt : Administration
+ {
+ /// Identify a set of peer poas that exist in the same process.
+ void link_servers (in string server, in CORBA::StringSeq peers)
+ raises(NotFound);
+
+ /// Have the approprate activator send a signal to the named server process
+ void kill_server (in string server, in short signum)
+ raises(NotFound, CannotComplete);
+ };
+
};
#endif /* TAO_IMRCLIENT_IMPLREPO_PIDL */