diff options
author | Phil Mesnier <mesnier_p@ociweb.com> | 2013-12-04 17:15:34 +0000 |
---|---|---|
committer | Phil Mesnier <mesnier_p@ociweb.com> | 2013-12-04 17:15:34 +0000 |
commit | 323aff2a5b4a1d71f4cff6544f8fd270b07a5f56 (patch) | |
tree | 5502c5b92b41948b975da842dc0b9be4dbdb5c8b /TAO | |
parent | fa6fd7ade3195bd4213a27e360af7e6aaf9fea30 (diff) | |
download | ATCD-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')
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 */ |