summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/ImplRepo_Service
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/ImplRepo_Service')
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/.cvsignore3
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Activator_Info.cpp20
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Activator_Info.h36
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Activator_Loader.cpp109
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Activator_Loader.h52
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Activator_NT_Service.cpp115
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Activator_NT_Service.h65
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Activator_Options.cpp348
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Activator_Options.h105
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Adapter_Activator.cpp95
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Adapter_Activator.h59
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter.idl18
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter_i.cpp171
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter_i.h75
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Forwarder.cpp162
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Forwarder.h77
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/INS_Locator.cpp64
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/INS_Locator.h53
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR.xsd30
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Activator.cpp216
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Activator.idl18
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp395
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h128
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator.cpp201
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl22
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp1532
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h187
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImplRepo_Service.mpc142
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Iterator.cpp91
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Iterator.h55
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Loader.cpp105
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Loader.h50
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_NT_Service.cpp116
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_NT_Service.h62
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp505
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Options.h147
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp574
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h114
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp97
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h88
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Makefile.am391
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/README.txt590
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp66
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Server_Info.h77
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/activator_export.h54
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/activator_idl_export.h54
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/locator_export.h54
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/locator_idl_export.h54
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/repository.xml8
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/tao_imr.cpp15
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp1111
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/tao_imr_i.h322
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/utils.h98
53 files changed, 9396 insertions, 0 deletions
diff --git a/TAO/orbsvcs/ImplRepo_Service/.cvsignore b/TAO/orbsvcs/ImplRepo_Service/.cvsignore
new file mode 100644
index 00000000000..114bf08db80
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/.cvsignore
@@ -0,0 +1,3 @@
+ImR_Activator
+ImplRepo_Service
+tao_imr
diff --git a/TAO/orbsvcs/ImplRepo_Service/Activator_Info.cpp b/TAO/orbsvcs/ImplRepo_Service/Activator_Info.cpp
new file mode 100644
index 00000000000..7833dce79ca
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Activator_Info.cpp
@@ -0,0 +1,20 @@
+// $Id$
+#include "Activator_Info.h"
+
+Activator_Info::Activator_Info
+(const ACE_CString& aname,
+ CORBA::Long atoken,
+ const ACE_CString& aior,
+ ImplementationRepository::Activator_ptr act)
+ : name(aname)
+ , token(atoken)
+ , ior(aior)
+ , activator (ImplementationRepository::Activator::_duplicate (act))
+{
+}
+void
+Activator_Info::reset()
+{
+ ior = "";
+ activator = ImplementationRepository::Activator::_nil();
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Activator_Info.h b/TAO/orbsvcs/ImplRepo_Service/Activator_Info.h
new file mode 100644
index 00000000000..a054fa24cd9
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Activator_Info.h
@@ -0,0 +1,36 @@
+// $Id$
+#ifndef ACTIVATOR_INFO_H
+#define ACTIVATOR_INFO_H
+
+#include "ace/Bound_Ptr.h"
+#include "ace/SString.h"
+
+#include "ImR_ActivatorC.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+* @brief Information about IMR registered Activators.
+*/
+struct Activator_Info
+{
+ Activator_Info (const ACE_CString& aname,
+ CORBA::Long atoken,
+ const ACE_CString& aior,
+ ImplementationRepository::Activator_ptr act =
+ ImplementationRepository::Activator::_nil ());
+
+ /// Reset the connection portion
+ void reset();
+
+ ACE_CString name;
+ CORBA::Long token;
+ ACE_CString ior;
+ ImplementationRepository::Activator_var activator;
+};
+
+typedef ACE_Strong_Bound_Ptr<Activator_Info, ACE_Null_Mutex> Activator_Info_Ptr;
+
+#endif /* ACTIVATOR_INFO_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/Activator_Loader.cpp b/TAO/orbsvcs/ImplRepo_Service/Activator_Loader.cpp
new file mode 100644
index 00000000000..9f222a54739
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Activator_Loader.cpp
@@ -0,0 +1,109 @@
+// $Id$
+
+#include "Activator_Loader.h"
+#include "ace/Dynamic_Service.h"
+#include "ace/Task.h"
+
+class ImR_Activator_ORB_Runner : public ACE_Task_Base
+{
+ ImR_Activator_Loader& service_;
+public:
+ ImR_Activator_ORB_Runner (ImR_Activator_Loader& service)
+ : service_ (service)
+ {
+ }
+ virtual int svc ()
+ {
+ // Block until service_.fini() calls orb->destroy()
+ this->service_.run ();
+ return 0;
+ }
+};
+
+ImR_Activator_Loader::ImR_Activator_Loader (void)
+{
+}
+
+// For now, we will assume that it's sufficient to start
+// the service in its own thread. Later, if necessary, we
+// can add a command line option to allow the imr to use
+// the same orb as other tao services, however the imr
+// is currently written with the assumption that it's running
+// in its own orb.
+int
+ImR_Activator_Loader::init (int argc, ACE_TCHAR *argv[] ACE_ENV_ARG_DECL)
+{
+ ACE_TRY
+ {
+ int err = this->opts_.init (argc, argv);
+ if (err != 0)
+ return -1;
+
+ // Creates it's own internal orb, which we must run later
+ err = this->service_.init (this->opts_ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (err != 0)
+ return -1;
+
+ // Create a thread in which to run the service
+ ACE_ASSERT (this->runner_.get () == 0);
+ this->runner_.reset (new ImR_Activator_ORB_Runner (*this));
+ this->runner_->activate ();
+ }
+ ACE_CATCHANY
+ {
+ return -1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+int
+ImR_Activator_Loader::fini (void)
+{
+ ACE_ASSERT (this->runner_.get() != 0);
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ int ret = this->service_.fini (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->runner_->wait ();
+ this->runner_.reset (0);
+ return ret;
+ }
+ ACE_CATCHANY
+ {
+ return -1;
+ }
+ ACE_ENDTRY;
+}
+
+CORBA::Object_ptr
+ImR_Activator_Loader::create_object (CORBA::ORB_ptr,
+ int,
+ ACE_TCHAR **
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_THROW_RETURN(CORBA::NO_IMPLEMENT (), CORBA::Object::_nil ());
+}
+
+int
+ImR_Activator_Loader::run (void)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ return this->service_.run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR ((LM_ERROR, "Exception in ImR_Locator_ORB_Runner()\n"));
+ return -1;
+ }
+ ACE_ENDTRY;
+}
+
+ACE_FACTORY_DEFINE (Activator, ImR_Activator_Loader)
diff --git a/TAO/orbsvcs/ImplRepo_Service/Activator_Loader.h b/TAO/orbsvcs/ImplRepo_Service/Activator_Loader.h
new file mode 100644
index 00000000000..2871c38e56b
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Activator_Loader.h
@@ -0,0 +1,52 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#ifndef TAO_IMR_ACTIVATOR_LOADER_H
+#define TAO_IMR_ACTIVATOR_LOADER_H
+
+#include "ImR_Activator_i.h"
+#include "Activator_Options.h"
+
+#include "tao/Object_Loader.h"
+
+#include "ace/Auto_Ptr.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class ImR_Activator_ORB_Runner;
+
+class Activator_Export ImR_Activator_Loader : public TAO_Object_Loader
+{
+public:
+ ImR_Activator_Loader(void);
+
+ virtual int init (int argc, ACE_TCHAR *argv[] ACE_ENV_ARG_DECL);
+
+ virtual int fini (void);
+
+ virtual CORBA::Object_ptr create_object (CORBA::ORB_ptr orb,
+ int argc,
+ ACE_TCHAR *argv[]
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ // Unlike other service objects, we have our own orb.
+ int run(void);
+
+private:
+ ImR_Activator_i service_;
+ Activator_Options opts_;
+ ACE_Auto_Ptr<ImR_Activator_ORB_Runner> runner_;
+
+private:
+ // Disallow copying and assignment.
+ ImR_Activator_Loader (const ImR_Activator_Loader &);
+ ImR_Activator_Loader &operator = (const ImR_Activator_Loader &);
+};
+
+ACE_FACTORY_DECLARE (Activator, ImR_Activator_Loader)
+
+#endif
diff --git a/TAO/orbsvcs/ImplRepo_Service/Activator_NT_Service.cpp b/TAO/orbsvcs/ImplRepo_Service/Activator_NT_Service.cpp
new file mode 100644
index 00000000000..eac94f086bb
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Activator_NT_Service.cpp
@@ -0,0 +1,115 @@
+//=============================================================================
+/**
+ * @file Activator_NT_Service.cpp
+ *
+ * $Id$
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ * @author Jeff Parsons <parsons@cs.wustl.edu>
+ * @author John Tucker <jtucker@infoglide.com>
+ * @author Mike Vitalo <mvitalo@infoglide.com>
+ */
+//=============================================================================
+
+#include "Activator_NT_Service.h"
+
+#if defined (ACE_WIN32)
+
+#include "ImR_Activator_i.h"
+#include "Activator_Options.h"
+
+#include "tao/ORB_Core.h"
+
+#include "ace/Reactor.h"
+/**
+ * Handles the SERVICE_CONTROL_SHUTDOWN and SERVICE_CONTROL_STOP commands
+ * by shutting down the ORB. Otherwise ACE_NT_Service::handle_control
+ * handles the command.
+ */
+void
+Activator_NT_Service::handle_control (DWORD control_code)
+{
+ if (control_code == SERVICE_CONTROL_SHUTDOWN
+ || control_code == SERVICE_CONTROL_STOP)
+ {
+ report_status (SERVICE_STOP_PENDING);
+ TAO_ORB_Core_instance ()->reactor ()->end_reactor_event_loop ();
+ TAO_ORB_Core_instance ()->orb ()->shutdown (1);
+ }
+ else
+ {
+ ACE_NT_Service::handle_control (control_code);
+ }
+}
+
+
+/**
+ */
+int
+Activator_NT_Service::handle_exception (ACE_HANDLE)
+{
+ return 0;
+}
+
+
+/**
+ * We do almost the same thing as we do in run_standalone () except that
+ * we update the report_status after init.
+ */
+int
+Activator_NT_Service::svc (void)
+{
+ ImR_Activator_i server;
+ Activator_Options opts;
+
+ if (opts.init_from_registry() != 0)
+ {
+ report_status (SERVICE_STOPPED);
+ return -1;
+ }
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ int status = server.init (opts ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (status == -1)
+ {
+ report_status (SERVICE_STOPPED);
+ return -1;
+ }
+ else
+ {
+ report_status (SERVICE_RUNNING);
+ server.run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ status = server.fini (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ report_status (SERVICE_STOPPED);
+
+ }
+ if (status != -1)
+ return 0;
+ }
+ ACE_CATCH (CORBA::SystemException, sysex)
+ {
+ ACE_PRINT_EXCEPTION (sysex, IMR_ACTIVATOR_DISPLAY_NAME);
+ }
+ ACE_CATCH (CORBA::UserException, userex)
+ {
+ ACE_PRINT_EXCEPTION (userex, IMR_ACTIVATOR_DISPLAY_NAME);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, IMR_ACTIVATOR_DISPLAY_NAME);
+ }
+ ACE_ENDTRY;
+
+ report_status (SERVICE_STOPPED);
+ return -1;
+}
+
+#endif /* ACE_WIN32 */
diff --git a/TAO/orbsvcs/ImplRepo_Service/Activator_NT_Service.h b/TAO/orbsvcs/ImplRepo_Service/Activator_NT_Service.h
new file mode 100644
index 00000000000..bde40cf1cd9
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Activator_NT_Service.h
@@ -0,0 +1,65 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Activator_NT_Service.h
+ *
+ * $Id$
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ * @author Jeff Parsons <parsons@cs.wustl.edu>
+ * @author John Tucker <jtucker@infoglide.com>
+ * @author Mike Vitalo <mvitalo@infoglide.com>
+ */
+//=============================================================================
+
+#ifndef Activator_NT_Service_H
+#define Activator_NT_Service_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_WIN32)
+
+#include "ace/NT_Service.h"
+#include "ace/Singleton.h"
+#include "ace/Synch.h"
+#include "tao/orbconf.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+static const char * IMR_ACTIVATOR_SERVICE_NAME = "TAOImRActivator";
+static const char * IMR_ACTIVATOR_DISPLAY_NAME = "TAO Implementation Repository Activator";
+static const char * IMR_ACTIVATOR_DESCRIPTION = "Implementation Repository Activator service for TAO";
+
+/**
+ * @class Activator_NT_Service
+ *
+ * @brief Allows the Implementation Repository to act as a Windows NT Service.
+ */
+class Activator_NT_Service : public ACE_NT_Service
+{
+public:
+ typedef TAO_SYNCH_RECURSIVE_MUTEX MUTEX;
+
+ /// We override <handle_control> because it handles stop requests
+ /// privately.
+ virtual void handle_control (DWORD control_code);
+
+ /// We override <handle_exception> so a 'stop' control code can wake
+ /// the reactor off of its wait.
+ virtual int handle_exception (ACE_HANDLE h);
+
+ /// This is a virtual method inherited from ACE_NT_Service.
+ virtual int svc (void);
+private:
+ friend class ACE_Singleton<Activator_NT_Service, MUTEX>;
+};
+
+typedef ACE_Singleton<Activator_NT_Service, ACE_Mutex> SERVICE;
+
+#endif /* ACE_WIN32 */
+
+#endif /* Activator_NT_Service_H */
+
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/Activator_Options.cpp b/TAO/orbsvcs/ImplRepo_Service/Activator_Options.cpp
new file mode 100644
index 00000000000..072ca61ba38
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Activator_Options.cpp
@@ -0,0 +1,348 @@
+//=============================================================================
+/**
+ * @file Activator_Options.cpp
+ *
+ * $Id$
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ */
+//=============================================================================
+#include "Activator_Options.h"
+
+#include "ace/Arg_Shifter.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/Log_Msg.h"
+
+ACE_RCSID (ImplRepo_Service,
+ Activator_Options,
+ "$Id$")
+
+#if defined (ACE_WIN32)
+static const HKEY SERVICE_REG_ROOT = HKEY_LOCAL_MACHINE;
+// This string must agree with the one used in Activator_NT_Service.h
+static const ACE_TCHAR *SERVICE_REG_PATH =
+ ACE_TEXT ("SYSTEM\\CurrentControlSet\\Services\\TAOImRActivator\\Parameters");
+#endif /* ACE_WIN32 */
+
+Activator_Options::Activator_Options ()
+: debug_ (1)
+, service_ (false)
+, notify_imr_ (false)
+, service_command_(SC_NONE)
+{
+}
+
+int
+Activator_Options::parse_args (int &argc, char *argv[])
+{
+ ACE_Arg_Shifter shifter (argc, argv);
+
+ while (shifter.is_anything_left ())
+ {
+ if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-c")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR, "Error: -c option needs a command\n"));
+ this->print_usage ();
+ return -1;
+ }
+
+ if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("install")) == 0)
+ {
+ this->service_command_ = SC_INSTALL;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("remove")) == 0)
+ {
+ this->service_command_ = SC_REMOVE;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("install_no_imr")) == 0)
+ {
+ this->service_command_ = SC_INSTALL_NO_LOCATOR;
+ }
+ else
+ {
+ ACE_ERROR((LM_ERROR, "Error: Unknown service command : %s\n", shifter.get_current()));
+ this->print_usage ();
+ return -1;
+ }
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-d")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR, "Error: -d option needs a debuglevel\n"));
+ this->print_usage ();
+ return -1;
+ }
+
+ this->debug_ = ACE_OS::atoi (shifter.get_current ());
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-o")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR, "Error: -o option needs a filename\n"));
+ this->print_usage ();
+ return -1;
+ }
+ this->ior_output_file_ = shifter.get_current ();
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-s")) == 0)
+ {
+ this->service_ = true;
+ }
+ else if ((ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-?")) == 0)
+ || (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-h")) == 0))
+ {
+ this->print_usage ();
+ return 1;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-n")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR, "Error: -n option needs a name\n"));
+ this->print_usage ();
+ return -1;
+ }
+ this->name_ = shifter.get_current ();
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-l")) == 0)
+ {
+ this->notify_imr_ = true;
+ }
+ else
+ {
+ shifter.ignore_arg ();
+ continue;
+ }
+
+ shifter.consume_arg ();
+ }
+ return 0;
+}
+
+int
+Activator_Options::init (int argc, char *argv[])
+{
+ // Make an initial pass through and grab the arguments that we recognize.
+ // This may also run the commands to install or remove the nt service.
+ int result = this->parse_args (argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ for (int i = 0; i < argc; ++i)
+ {
+ this->cmdline_ += ACE_CString (argv[i]) + ACE_CString (" ");
+ }
+
+ return 0;
+}
+
+int
+Activator_Options::init_from_registry (void)
+{
+ this->load_registry_options();
+ return 0;
+}
+
+void
+Activator_Options::print_usage (void) const
+{
+ ACE_ERROR ((LM_ERROR,
+ "Usage:\n"
+ "\n"
+ "ImR_Activator [-c cmd] [-d 0|1|2] [-o file] [-l] [-n name]\n"
+ "\n"
+ " -c command Runs service commands \n"
+ " ('install' or 'remove' or 'install_no_imr')\n"
+ " -d level Sets the debug level\n"
+ " -o file Outputs the ImR's IOR to a file\n"
+ " -l Notify the ImR when a process exits\n"
+ " -n name Specify a name for the Activator\n")
+ );
+}
+
+int
+Activator_Options::save_registry_options()
+{
+#if defined (ACE_WIN32)
+ HKEY key = 0;
+ // Create or open the parameters key
+ LONG err = ACE_TEXT_RegCreateKeyEx (SERVICE_REG_ROOT,
+ SERVICE_REG_PATH,
+ 0,
+ "", // class
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &key,
+ NULL
+ );
+ if (err != ERROR_SUCCESS)
+ {
+ return -1;
+ }
+ err = ACE_TEXT_RegSetValueEx (key, "ORBInitOptions", 0, REG_SZ,
+ (LPBYTE) this->cmdline_.c_str (), this->cmdline_.length () + 1);
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ err = ACE_TEXT_RegSetValueEx (key, "IORFile", 0, REG_SZ,
+ (LPBYTE) this->ior_output_file_.c_str (), this->ior_output_file_.length () + 1);
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ err = ACE_TEXT_RegSetValueEx (key, "DebugLevel", 0, REG_DWORD,
+ (LPBYTE) &this->debug_ , sizeof (this->debug_));
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ err = ACE_TEXT_RegSetValueEx( key, "Name", 0, REG_SZ,
+ (LPBYTE) this->name_.c_str (), this->name_.length () + 1);
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ DWORD tmpint = this->notify_imr_;
+ err = ACE_TEXT_RegSetValueEx (key, "NotifyImR", 0, REG_DWORD,
+ (LPBYTE) &tmpint , sizeof (tmpint));
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ err = ::RegCloseKey (key);
+ ACE_ASSERT (err == ERROR_SUCCESS);
+#endif
+ return 0;
+}
+
+int
+Activator_Options::load_registry_options ()
+{
+#if defined (ACE_WIN32)
+ HKEY key = 0;
+ // Create or open the parameters key
+ LONG err = ACE_TEXT_RegOpenKeyEx (SERVICE_REG_ROOT,
+ SERVICE_REG_PATH,
+ 0,
+ KEY_READ,
+ &key
+ );
+ if (err != ERROR_SUCCESS)
+ {
+ // If there aren't any saved parameters, then that's ok.
+ return 0;
+ }
+ char tmpstr[4096];
+ DWORD sz = sizeof (tmpstr);
+ DWORD type = 0;
+ err = ACE_TEXT_RegQueryValueEx (key, "ORBInitOptions", 0, &type,
+ (LPBYTE) tmpstr, &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_SZ);
+ tmpstr[sz - 1] = '\0';
+ this->cmdline_ = tmpstr;
+ }
+
+ sz = sizeof(tmpstr);
+ err = ACE_TEXT_RegQueryValueEx (key, "IORFile", 0, &type,
+ (LPBYTE) tmpstr, &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_SZ);
+ tmpstr[sz - 1] = '\0';
+ this->ior_output_file_ = tmpstr;
+ }
+
+ sz = sizeof(debug_);
+ err = ACE_TEXT_RegQueryValueEx (key, "DebugLevel", 0, &type,
+ (LPBYTE) &this->debug_ , &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_DWORD);
+ }
+
+ sz = sizeof(tmpstr);
+ err = ACE_TEXT_RegQueryValueEx (key, "Name", 0, &type,
+ (LPBYTE) tmpstr, &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_SZ);
+ tmpstr[sz - 1] = '\0';
+ this->name_ = tmpstr;
+ }
+
+ DWORD tmpint = 0;
+ sz = sizeof(tmpint);
+ err = ACE_TEXT_RegQueryValueEx (key, "NotifyImR", 0, &type,
+ (LPBYTE) &tmpint , &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_DWORD);
+ }
+ this->notify_imr_ = tmpint != 0;
+
+ err = ::RegCloseKey (key);
+ ACE_ASSERT(err == ERROR_SUCCESS);
+#endif /* ACE_WIN32 */
+ return 0;
+}
+
+bool
+Activator_Options::service (void) const
+{
+ return this->service_;
+}
+
+bool
+Activator_Options::notify_imr (void) const
+{
+ return this->notify_imr_;
+}
+
+unsigned int
+Activator_Options::debug (void) const
+{
+ return this->debug_;
+}
+
+const ACE_CString&
+Activator_Options::ior_filename (void) const
+{
+ return this->ior_output_file_;
+}
+
+Activator_Options::SERVICE_COMMAND
+Activator_Options::service_command (void) const
+{
+ return this->service_command_;
+}
+
+const char*
+Activator_Options::cmdline (void) const
+{
+ return this->cmdline_.c_str ();
+}
+
+const ACE_CString&
+Activator_Options::name (void) const
+{
+ return this->name_;
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Activator_Options.h b/TAO/orbsvcs/ImplRepo_Service/Activator_Options.h
new file mode 100644
index 00000000000..45f351a0f44
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Activator_Options.h
@@ -0,0 +1,105 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Activator_Options.h
+ *
+ * $Id$
+ *
+ * @brief Definition of the Options class for the Implementation Repository.
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACTIVATOR_OPTIONS_H
+#define ACTIVATOR_OPTIONS_H
+
+#include "activator_export.h"
+
+#include "ace/SString.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class Options
+ *
+ * This is where all the settings for TAO's Implementation Repository are
+ * stored.
+ */
+class Activator_Export Activator_Options
+{
+public:
+
+ enum SERVICE_COMMAND {
+ SC_NONE,
+ SC_INSTALL,
+ SC_REMOVE,
+ SC_INSTALL_NO_LOCATOR
+ };
+
+ Activator_Options ();
+
+ /// Parse the command-line arguments and initialize the options.
+ int init (int argc, char *argv[]);
+ /// This version should only be used when run as an nt service.
+ int init_from_registry();
+
+ /// Service Mode
+ bool service (void) const;
+
+ /// Notify the ImR when server processes die.
+ /// Note : Currently this only works on Unix.
+ bool notify_imr (void) const;
+
+ /// Debug level for the Implementation Repository.
+ unsigned int debug (void) const;
+
+ /// Returns the file where the IOR should be stored.
+ const ACE_CString& ior_filename (void) const;
+
+ /// The nt service command to run (install/remove)
+ SERVICE_COMMAND service_command(void) const;
+
+ /// Save the command line arguments as registry settings. (Windows only)
+ int save_registry_options ();
+
+ const char* cmdline(void) const;
+
+ const ACE_CString& name(void) const;
+
+private:
+ /// Parses and pulls out arguments for the ImR
+ int parse_args (int &argc, char *argv[]);
+
+ /// Print the usage information.
+ void print_usage (void) const;
+
+ /// Loads options from the registry
+ int load_registry_options ();
+
+private:
+
+ /// Our extra command line arguments
+ ACE_CString cmdline_;
+
+ /// Debug level.
+ unsigned int debug_;
+
+ /// File where the IOR of the server object is stored.
+ ACE_CString ior_output_file_;
+
+ /// Should we run as a service?
+ bool service_;
+
+ bool notify_imr_;
+
+ /// SC_NONE, SC_INSTALL, SC_REMOVE, ...
+ SERVICE_COMMAND service_command_;
+
+ ACE_CString name_;
+};
+
+#endif
diff --git a/TAO/orbsvcs/ImplRepo_Service/Adapter_Activator.cpp b/TAO/orbsvcs/ImplRepo_Service/Adapter_Activator.cpp
new file mode 100644
index 00000000000..e68bdbcf4f9
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Adapter_Activator.cpp
@@ -0,0 +1,95 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+ * @file Adapter_Activator.cpp
+ *
+ * $Id$
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ */
+//=============================================================================
+
+#include "Adapter_Activator.h"
+
+#include "ace/Log_Msg.h"
+
+ImR_Adapter::ImR_Adapter (void)
+: servant_locator_ (0)
+{
+}
+
+void
+ImR_Adapter::init (PortableServer::ServantLocator_ptr servant)
+{
+ servant_locator_ = servant;
+}
+
+CORBA::Boolean
+ImR_Adapter::unknown_adapter (PortableServer::POA_ptr parent,
+ const char *name
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_ASSERT (! CORBA::is_nil(parent));
+ ACE_ASSERT (name != 0);
+ CORBA::PolicyList policies (2);
+ policies.length (2);
+
+ const char *exception_message = "Null Message";
+
+ ACE_TRY
+ {
+ // Servant Retention Policy
+ exception_message = "While PortableServer::POA::create_servant_retention_policy";
+ policies[0] =
+ parent->create_servant_retention_policy (PortableServer::NON_RETAIN ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Request Processing Policy
+ exception_message = "While PortableServer::POA::create_request_processing_policy";
+ policies[1] =
+ parent->create_request_processing_policy (PortableServer::USE_SERVANT_MANAGER ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ PortableServer::POAManager_var poa_manager =
+ parent->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ exception_message = "While create_POA";
+ PortableServer::POA_var child =
+ parent->create_POA (name,
+ poa_manager.in (),
+ policies
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ exception_message = "While unknown_adapter::policy->destroy";
+ for (CORBA::ULong i = 0; i < policies.length (); ++i)
+ {
+ CORBA::Policy_ptr policy = policies[i];
+ policy->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ exception_message = "While child->the_activator";
+ child->the_activator (this ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ exception_message = "While unknown_adapter, set_servant_manager";
+ child->set_servant_manager (this->servant_locator_ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_ERROR ((LM_ERROR,
+ "IMR_Adapter_Activator::unknown_adapter - %s\n",
+ exception_message));
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "System Exception");
+ return 0;
+ }
+ ACE_ENDTRY;
+
+ // Finally, now everything is fine
+ return 1;
+}
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/Adapter_Activator.h b/TAO/orbsvcs/ImplRepo_Service/Adapter_Activator.h
new file mode 100644
index 00000000000..d62d8f3cfcf
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Adapter_Activator.h
@@ -0,0 +1,59 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+ * @file Adapter_Activator.h
+ *
+ * $Id$
+ *
+ * @brief This class implements ImR's Adapter Activator.
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef IMR_ADAPTER_ACTIVATOR_H
+#define IMR_ADAPTER_ACTIVATOR_H
+
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/AdapterActivatorC.h"
+#include "tao/PortableServer/ServantLocatorC.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/LocalObject.h"
+
+
+/**
+ * @class ImR_Adapter_Activator
+ *
+ * @brief Implementation Repository Adapter Activator
+ *
+ * Part of the ServantLocator/AdapterActivator combination that is used to
+ * receive forwardable requests from clients. The Adapter Activator creates
+ * the POA structure that the request expects. For each POA created, the
+ * same ServantLocator will be registered in each one.
+ */
+class ImR_Adapter
+ : public PortableServer::AdapterActivator,
+ public CORBA::LocalObject
+{
+public:
+ ImR_Adapter();
+
+ /// Called when a POA needs to be created.
+ virtual CORBA::Boolean unknown_adapter (
+ PortableServer::POA_ptr parent,
+ const char *name
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ void init(PortableServer::ServantLocator_ptr servant);
+private:
+ /// The ServantLocator registered in each new POA.
+ PortableServer::ServantLocator_ptr servant_locator_;
+};
+
+#endif /* IMR_ADAPTER_ACTIVATOR_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter.idl b/TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter.idl
new file mode 100644
index 00000000000..92a908888d9
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter.idl
@@ -0,0 +1,18 @@
+// -*- IDL -*-
+
+// $Id$
+
+module ImplementationRepository
+{
+ struct StartupInfo {
+ string name;
+ string partial_ior;
+ string ior;
+ };
+
+ interface AsyncStartupWaiter
+ {
+ StartupInfo wait_for_startup(in string name);
+ };
+};
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter_i.cpp b/TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter_i.cpp
new file mode 100644
index 00000000000..2cebbc590bd
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter_i.cpp
@@ -0,0 +1,171 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#include "AsyncStartupWaiter_i.h"
+#include "ImR_Locator_i.h"
+
+using namespace ImplementationRepository;
+
+AsyncStartupWaiter_i::PendingData::PendingData (const char* p, const char* i)
+: partial_ior (p)
+, ior( i)
+{
+}
+
+AsyncStartupWaiter_i::PendingData::PendingData ()
+{
+}
+
+
+void AsyncStartupWaiter_i::debug (bool dbg)
+{
+ debug_ = dbg;
+}
+
+void AsyncStartupWaiter_i::wait_for_startup (AMH_AsyncStartupWaiterResponseHandler_ptr rh,
+ const char* name ACE_ENV_ARG_DECL_NOT_USED) ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ PendingListPtr plst;
+ pending_.find(name, plst);
+ if (! plst.null () && plst->size () > 0)
+ {
+ PendingList& tmp = *plst;
+ PendingData& pd = tmp[tmp.size () - 1];
+ tmp.pop_back ();
+
+ if (debug_)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Skipping wait due to queued startup info for <%s>.\n", name));
+
+ send_response (*rh, name, pd.partial_ior.c_str(), pd.ior.c_str());
+
+ }
+ else
+ {
+ RHListPtr lst;
+ waiting_.find (name, lst);
+ if (lst.null ())
+ {
+ lst = RHListPtr (new RHList);
+ int err = waiting_.bind (name, lst);
+ ACE_ASSERT (err == 0);
+ ACE_UNUSED_ARG (err);
+ }
+ lst->push_back (AMH_AsyncStartupWaiterResponseHandler::_duplicate (rh));
+ }
+}
+
+void
+AsyncStartupWaiter_i::send_response (ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler& rh,
+ const char* name, const char* partial_ior, const char* ior)
+{
+ StartupInfo_var si = new StartupInfo();
+ si->name = name;
+ si->partial_ior = partial_ior;
+ si->ior = ior;
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ rh.wait_for_startup (si.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ if (debug_)
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "AsyncStartupWaiter_i::send_response ()");
+ }
+ ACE_ENDTRY;
+}
+
+void
+AsyncStartupWaiter_i::unblock_one (const char* name, const char* partial_ior, const char* ior, bool queue) {
+ ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_var rh = get_one_waiter(name);
+ if (! CORBA::is_nil(rh.in ()))
+ {
+ send_response (*rh.in (), name, partial_ior, ior);
+ }
+ else if (queue)
+ {
+ if (debug_)
+ ACE_DEBUG((LM_DEBUG, "ImR: Queuing startup info.\n"));
+
+ PendingListPtr lst;
+ pending_.find (name, lst);
+ if (lst.null ())
+ {
+ lst = PendingListPtr (new PendingList);
+ int err = pending_.bind (name, lst);
+ ACE_ASSERT (err == 0);
+ ACE_UNUSED_ARG (err);
+ }
+ lst->push_back (PendingData (partial_ior, ior));
+ }
+}
+
+void
+AsyncStartupWaiter_i::unblock_all (const char* name) {
+ RHList tmp;
+
+ get_all_waiters (name, tmp);
+
+ // This startup info should be ignored when unblocking all, because we
+ // don't know the ior or partial_ior at this point.
+ StartupInfo_var si = new StartupInfo ();
+ si->name = name;
+
+ // Note : This method may be called when there are no waiters.
+
+ for (size_t i = 0; i < tmp.size(); ++i)
+ {
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_var& rh = tmp[i];
+
+ rh->wait_for_startup (si.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ if (debug_)
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "AsyncStartupWaiter_i::unblock_all ()");
+ }
+ ACE_ENDTRY;
+ }
+}
+
+ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_ptr
+AsyncStartupWaiter_i::get_one_waiter (const char* name)
+{
+ RHListPtr lst;
+ waiting_.find (name, lst);
+ if (! lst.null() && lst->size () > 0)
+ {
+ RHList& rhlst = *lst;
+ ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_var& tmp = rhlst[rhlst.size () - 1];
+ ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_ptr ret = tmp._retn ();
+ rhlst.pop_back ();
+ return ret;
+ }
+ return ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler::_nil ();
+}
+
+void
+AsyncStartupWaiter_i::get_all_waiters (const char* name, RHList& ret)
+{
+ RHListPtr lst;
+ waiting_.find (name, lst);
+ if (! lst.null ()) {
+ for (size_t i = 0; i < lst->size (); ++i)
+ {
+ RHList& tmp = *lst;
+ ret.push_back (tmp[i]);
+ // The ACE_Vector will not destruct the elements when cleared, so we must
+ // make sure to do so here.
+ tmp[i] = ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler::_nil ();
+ }
+ lst->clear ();
+ }
+}
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter_i.h b/TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter_i.h
new file mode 100644
index 00000000000..b4b527e1d40
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/AsyncStartupWaiter_i.h
@@ -0,0 +1,75 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#ifndef IMR_AsyncStartupWaiterI_H_
+#define IMR_AsyncStartupWaiterI_H_
+
+#include "locator_export.h"
+#include "AsyncStartupWaiterS.h"
+
+#include "ace/Vector_T.h"
+#include "ace/Hash_Map_Manager.h"
+#include "ace/Bound_Ptr.h"
+#include "ace/SString.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+
+class ImR_Locator_i;
+
+class Locator_Export AsyncStartupWaiter_i : public virtual POA_ImplementationRepository::AMH_AsyncStartupWaiter
+{
+ struct PendingData {
+ PendingData();
+ PendingData(const char* partial_ior, const char* ior);
+ ACE_CString partial_ior;
+ ACE_CString ior;
+ };
+ typedef ACE_Vector<PendingData> PendingList;
+ typedef ACE_Strong_Bound_Ptr<PendingList, ACE_Null_Mutex> PendingListPtr;
+ typedef ACE_Hash_Map_Manager_Ex<ACE_CString,
+ PendingListPtr,
+ ACE_Hash<ACE_CString>,
+ ACE_Equal_To<ACE_CString>,
+ ACE_Null_Mutex> PendingMap;
+
+ typedef ACE_Vector<ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_var> RHList;
+ typedef ACE_Strong_Bound_Ptr<RHList, ACE_Null_Mutex> RHListPtr;
+ typedef ACE_Hash_Map_Manager_Ex<ACE_CString,
+ RHListPtr,
+ ACE_Hash<ACE_CString>,
+ ACE_Equal_To<ACE_CString>,
+ ACE_Null_Mutex> WaitingMap;
+
+public:
+
+ void wait_for_startup (
+ ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_ptr rh,
+ const char* name ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ void unblock_one(const char* name, const char* partial_ior, const char* ior, bool queue);
+ void unblock_all(const char* name);
+
+ void debug(bool dbg);
+
+private:
+
+ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_ptr
+ get_one_waiter(const char* name);
+
+void get_all_waiters(const char* name, RHList& ret);
+
+void send_response(ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler& rh,
+ const char* name, const char* partial_ior, const char* ior);
+private:
+ WaitingMap waiting_;
+ PendingMap pending_;
+ bool debug_;
+};
+
+#endif /* AsyncStartupWaiterI_H_ */
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/Forwarder.cpp b/TAO/orbsvcs/ImplRepo_Service/Forwarder.cpp
new file mode 100644
index 00000000000..7337af511e9
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Forwarder.cpp
@@ -0,0 +1,162 @@
+//=============================================================================
+/**
+* @file Forwarder.cpp
+*
+* $Id$
+*
+* @brief Definition of ImR_Forwarder
+*
+* @author Darrell Brunsch <brunsch@cs.wustl.edu>
+* @author Priyanka Gontla <pgontla@doc.ece.uci.edu>
+*/
+//=============================================================================
+
+#include "Forwarder.h"
+#include "ImR_Locator_i.h"
+
+#include "tao/ORB.h"
+#include "tao/Object_KeyC.h"
+#include "tao/ORB_Constants.h"
+
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/POA_Current_Impl.h"
+#include "tao/PortableServer/POA_Current.h"
+
+/**
+* This constructor takes in orb and ImR_Locator_i pointers to store for later
+* use. It also grabs a reference to the POACurrent object for use in
+* preinvoke.
+*/
+ImR_Forwarder::ImR_Forwarder (ImR_Locator_i& imr_impl)
+ : locator_ (imr_impl)
+{
+}
+
+void
+ImR_Forwarder::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL)
+{
+ ACE_ASSERT (! CORBA::is_nil(orb));
+ this->orb_ = orb;
+ ACE_TRY_NEW_ENV
+ {
+ CORBA::Object_var tmp =
+ orb->resolve_initial_references ("POACurrent" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->poa_current_var_ =
+ PortableServer::Current::_narrow (tmp.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR_Forwarder::init() Exception ignored.\n"));
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+ ACE_ASSERT (!CORBA::is_nil (this->poa_current_var_.in ()));
+}
+
+/**
+* We figure out the intended recipient from the POA name. After activating
+* the server, we throw a forwarding exception to the correct server.
+*
+* The big complicated thing here is that we have to create the forwarding
+* ior based on what we already have. So we combine the endpoint received
+* from activate_server_i and append the objectid from the request to it.
+*/
+PortableServer::Servant
+ImR_Forwarder::preinvoke (const PortableServer::ObjectId &,
+ PortableServer::POA_ptr poa,
+ const char *,
+ PortableServer::ServantLocator::Cookie &
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException, PortableServer::ForwardRequest))
+{
+ ACE_ASSERT (! CORBA::is_nil(poa));
+ CORBA::Object_var forward_obj;
+
+ ACE_TRY
+ {
+ CORBA::String_var server_name = poa->the_name();
+
+ if (locator_.debug() > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Activating server <%s>.\n", server_name.in()));
+
+ // The activator stores a partial ior with each server. We can
+ // just tack on the current ObjectKey to get a valid ior for
+ // the desired server.
+ CORBA::String_var pior = locator_.activate_server_by_name (server_name.in (), false ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_CString ior = pior.in ();
+
+ // Check that the returned ior is the expected partial ior with
+ // missing ObjectKey.
+ if (ior.find ("corbaloc:") != 0 || ior[ior.length () - 1] != '/')
+ {
+ ACE_ERROR ((LM_ERROR, "ImR_Forwarder::preinvoke () Invalid corbaloc ior.\n\t<%s>\n", ior.c_str()));
+ ACE_TRY_THROW (CORBA::OBJECT_NOT_EXIST (
+ CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0),
+ CORBA::COMPLETED_NO));
+ }
+
+ CORBA::String_var key_str;
+ // Unlike POA Current, this implementation cannot be cached.
+ TAO::Portable_Server::POA_Current* tao_current =
+ dynamic_cast <TAO::Portable_Server::POA_Current*> (this->poa_current_var_.in ());
+
+ ACE_ASSERT(tao_current != 0);
+ TAO::Portable_Server::POA_Current_Impl* impl = tao_current->implementation ();
+ TAO::ObjectKey::encode_sequence_to_string (key_str.out (), impl->object_key ());
+
+ ior += key_str.in();
+
+ if (locator_.debug() > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Forwarding invocation on <%s> to <%s>\n", server_name.in(), ior.c_str()));
+
+ forward_obj =
+ this->orb_->string_to_object (ior.c_str () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (ImplementationRepository::CannotActivate, ex)
+ {
+ ACE_TRY_THROW (CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0),
+ CORBA::COMPLETED_NO));
+ }
+ ACE_CATCH (ImplementationRepository::NotFound, ex)
+ {
+ ACE_TRY_THROW (CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0),
+ CORBA::COMPLETED_NO));
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Forwarder");
+ ACE_TRY_THROW (CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0),
+ CORBA::COMPLETED_NO));
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (0);
+
+ if (!CORBA::is_nil (forward_obj.in ()))
+ ACE_THROW_RETURN (PortableServer::ForwardRequest (forward_obj.in ()), 0);
+
+ ACE_ERROR ((LM_ERROR, "Error: Forward_to reference is nil.\n"));
+ ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (
+ CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0),
+ CORBA::COMPLETED_NO), 0);
+}
+
+void
+ImR_Forwarder::postinvoke (const PortableServer::ObjectId &,
+ PortableServer::POA_ptr,
+ const char *,
+ PortableServer::ServantLocator::Cookie,
+ PortableServer::Servant
+ ACE_ENV_ARG_DECL_NOT_USED
+ ) ACE_THROW_SPEC ((CORBA::SystemException))
+{
+}
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/Forwarder.h b/TAO/orbsvcs/ImplRepo_Service/Forwarder.h
new file mode 100644
index 00000000000..31bf107b602
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Forwarder.h
@@ -0,0 +1,77 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+ * @file Forwarder.h
+ *
+ * $Id$
+ *
+ * @brief This class implements ImR's forwarding ServantLocator
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ * @author Priyanka Gontla <pgontla@doc.ece.uci.edu>
+ */
+//=============================================================================
+
+#ifndef IMR_FORWARDER_H
+#define IMR_FORWARDER_H
+
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/ServantLocatorC.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/LocalObject.h"
+
+
+class ImR_Locator_i;
+
+/**
+ * @class ImR_Forwarder:
+ *
+ * @brief Implementation Repository Forwarder
+ *
+ * This class provides a ServantLocator implementation that
+ * is used to handle arbitrary calls and forward them to the
+ * correct place.
+ */
+class ImR_Forwarder
+ : public PortableServer::ServantLocator,
+ public CORBA::LocalObject
+{
+public:
+ ImR_Forwarder (ImR_Locator_i& imr_impl);
+
+ /// Called before the invocation begins.
+ virtual PortableServer::Servant preinvoke (
+ const PortableServer::ObjectId &oid,
+ PortableServer::POA_ptr poa,
+ const char * operation,
+ PortableServer::ServantLocator::Cookie &cookie
+ ACE_ENV_ARG_DECL
+ ) ACE_THROW_SPEC ((CORBA::SystemException, PortableServer::ForwardRequest));
+
+ virtual void postinvoke (
+ const PortableServer::ObjectId & oid,
+ PortableServer::POA_ptr adapter,
+ const char * operation,
+ PortableServer::ServantLocator::Cookie the_cookie,
+ PortableServer::Servant the_servant
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ ) ACE_THROW_SPEC ((CORBA::SystemException));
+
+ void init(CORBA::ORB_ptr orb ACE_ENV_ARG_DECL);
+
+private:
+ /// Where we find out where to forward to.
+ ImR_Locator_i& locator_;
+
+ /// POA reference.
+ PortableServer::Current_var poa_current_var_;
+
+ /// Variable to save the ORB reference passed to the constr.
+ CORBA::ORB_ptr orb_;
+};
+
+#endif /* IMR_FORWARDER_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/INS_Locator.cpp b/TAO/orbsvcs/ImplRepo_Service/INS_Locator.cpp
new file mode 100644
index 00000000000..3057a8d6622
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/INS_Locator.cpp
@@ -0,0 +1,64 @@
+//=============================================================================
+/**
+* @file INS_Locator.cpp
+*
+* $Id$
+*
+* @brief Implementation of the ImR's INS Locator class
+*
+* @author Darrell Brunsch <brunsch@cs.wustl.edu>
+*/
+//=============================================================================
+
+#include "INS_Locator.h"
+#include "ImR_Locator_i.h"
+#include "tao/ORB_Constants.h"
+
+INS_Locator::INS_Locator (ImR_Locator_i& loc)
+: imr_locator_ (loc)
+{
+}
+
+char *
+INS_Locator::locate (const char* object_key ACE_ENV_ARG_DECL)
+ACE_THROW_SPEC ((CORBA::SystemException, IORTable::NotFound))
+{
+ ACE_ASSERT (object_key != 0);
+ ACE_TRY
+ {
+ ACE_CString key (object_key);
+ ssize_t poaidx = key.find ('/');
+ if (poaidx >= 0)
+ {
+ key = key.substring (0, poaidx);
+ }
+
+ if (imr_locator_.debug () > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Activating server <%s>.\n", key.c_str ()));
+
+ CORBA::String_var located =
+ this->imr_locator_.activate_server_by_object (key.c_str () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_CString tmp = located.in ();
+ tmp += object_key;
+
+ if (imr_locator_.debug () > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Forwarding invocation on <%s> to <%s>\n", key.c_str (), tmp.c_str()));
+
+ return CORBA::string_dup (tmp.c_str ());
+ }
+ ACE_CATCH (ImplementationRepository::CannotActivate, ex)
+ {
+ ACE_TRY_THROW (CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0),
+ CORBA::COMPLETED_NO));
+ }
+ ACE_CATCH (ImplementationRepository::NotFound, ex)
+ {
+ ACE_TRY_THROW (CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0),
+ CORBA::COMPLETED_NO));
+ }
+ ACE_ENDTRY;
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/INS_Locator.h b/TAO/orbsvcs/ImplRepo_Service/INS_Locator.h
new file mode 100644
index 00000000000..88fca61b5ba
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/INS_Locator.h
@@ -0,0 +1,53 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+ * @file INS_Locator.h
+ *
+ * $Id$
+ *
+ * @brief This class implements the ImR's INS Locator class
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef IMR_INS_LOCATOR_H
+#define IMR_INS_LOCATOR_H
+#include /**/ "ace/pre.h"
+
+#include "tao/IORTable/IORTable.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/LocalObject.h"
+
+
+class ImR_Locator_i;
+
+/**
+ * @class INS_Locator
+ *
+ * @brief Implementation Repository INS Locator class
+ *
+ * This class provides a callback for the IORTable to call when it needs
+ * to dynamically receive a IOR to forward in response to an INS request.
+ */
+class INS_Locator
+ : public virtual IORTable::Locator,
+ public virtual CORBA::LocalObject
+{
+public:
+ INS_Locator (ImR_Locator_i& loc);
+
+ /// Locate the appropriate IOR.
+ char* locate (const char *object_key ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException, IORTable::NotFound));
+
+private:
+ ImR_Locator_i& imr_locator_;
+};
+
+#include /**/ "ace/post.h"
+#endif
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR.xsd b/TAO/orbsvcs/ImplRepo_Service/ImR.xsd
new file mode 100644
index 00000000000..013bd6dd849
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR.xsd
@@ -0,0 +1,30 @@
+<?xml version="1.0" ?>
+<xs:schema id="ImplementationRepository" targetNamespace="http://www.theaceorb.com/ImplementationRepository.xsd" xmlns:mstns="http://www.theaceorb.com/ImplementationRepository.xsd"
+ xmlns="http://www.theaceorb.com/ImplementationRepository.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
+ attributeFormDefault="qualified" elementFormDefault="qualified">
+ <xs:element name="ImplementationRepository" msdata:IsDataSet="true" msdata:EnforceConstraints="False">
+ <xs:complexType>
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="Servers">
+ <xs:complexType>
+ <xs:attribute name="name" form="unqualified" type="xs:string" />
+ <xs:attribute name="activator" form="unqualified" type="xs:string" />
+ <xs:attribute name="command_line" form="unqualified" type="xs:string" />
+ <xs:attribute name="working_dir" form="unqualified" type="xs:string" />
+ <xs:attribute name="activation_mode" form="unqualified" type="xs:string" />
+ <xs:attribute name="start_limit" form="unqualified" type="xs:string" />
+ <xs:attribute name="partial_ior" form="unqualified" type="xs:string" />
+ <xs:attribute name="ior" form="unqualified" type="xs:string" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="Activators">
+ <xs:complexType>
+ <xs:attribute name="name" form="unqualified" type="xs:string" />
+ <xs:attribute name="token" form="unqualified" type="xs:string" />
+ <xs:attribute name="ior" form="unqualified" type="xs:string" />
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+ </xs:complexType>
+ </xs:element>
+</xs:schema> \ No newline at end of file
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator.cpp
new file mode 100644
index 00000000000..34da1320caf
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator.cpp
@@ -0,0 +1,216 @@
+/* -*- C++ -*- */
+// $Id$
+
+#include "Activator_Options.h"
+#include "ImR_Activator_i.h"
+#include "Activator_NT_Service.h"
+
+#include "orbsvcs/Shutdown_Utilities.h"
+
+class ImR_Activator_Shutdown : public Shutdown_Functor
+{
+public:
+ ImR_Activator_Shutdown (ImR_Activator_i& act);
+
+ void operator() (int which_signal);
+private:
+ ImR_Activator_i& act_;
+};
+
+ImR_Activator_Shutdown::ImR_Activator_Shutdown (ImR_Activator_i &act)
+ : act_(act)
+{
+}
+
+void
+ImR_Activator_Shutdown::operator() (int /*which_signal*/)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->act_.shutdown (true ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR Activator: ");
+ }
+ ACE_ENDTRY;
+}
+
+int
+run_standalone (Activator_Options& opts)
+{
+ ImR_Activator_i server;
+
+ ImR_Activator_Shutdown killer (server);
+ Service_Shutdown kill_contractor (killer);
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ int status = server.init (opts ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (status == -1)
+ {
+ return 1;
+ }
+ else
+ {
+ // Run the server if it is initialized correctly.
+ server.run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // End the server after its work is done.
+ status = server.fini (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (status == -1)
+ return 1;
+ }
+ return 0;
+ }
+ ACE_CATCH (CORBA::SystemException, sysex)
+ {
+ ACE_PRINT_EXCEPTION (sysex, "System Exception");
+ }
+ ACE_CATCH (CORBA::UserException, userex)
+ {
+ ACE_PRINT_EXCEPTION (userex, "User Exception");
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Unknown Exception");
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
+
+#if defined (ACE_WIN32)
+ACE_NT_SERVICE_DEFINE (service, Activator_NT_Service, IMR_ACTIVATOR_SERVICE_NAME);
+#endif /* ACE_WIN32 */
+
+int
+run_service (void)
+{
+#if defined (ACE_WIN32)
+ SERVICE::instance()->name (IMR_ACTIVATOR_SERVICE_NAME, IMR_ACTIVATOR_DISPLAY_NAME);
+ ACE_NT_SERVICE_RUN (service, SERVICE::instance (), ret);
+
+ if (ret == 0)
+ ACE_ERROR ((LM_ERROR, "%p\n", "Couldn't start service"));
+
+ return ret;
+#else /* ACE_WIN32 */
+ return 1;
+#endif /* ACE_WIN32 */
+}
+
+/**
+ * Executes the various commands that are useful for a NT service. Right
+ * now these include 'install' and 'remove'. Others, such as 'start' and
+ * 'stop' can be added, but the 'net' program in Windows already handles
+ * these commands.
+ */
+static int
+run_service_command (Activator_Options& opts)
+{
+ if (opts.service_command () == Activator_Options::SC_NONE)
+ return 0;
+
+#if defined (ACE_WIN32)
+ SERVICE::instance()->name (IMR_ACTIVATOR_SERVICE_NAME, IMR_ACTIVATOR_DISPLAY_NAME);
+
+ if (opts.service_command () == Activator_Options::SC_INSTALL ||
+ opts.service_command () == Activator_Options::SC_INSTALL_NO_LOCATOR)
+ {
+ const DWORD MAX_PATH_LENGTH = 4096;
+ char pathname[MAX_PATH_LENGTH];
+
+ DWORD length = ACE_TEXT_GetModuleFileName(NULL, pathname, MAX_PATH_LENGTH);
+ if (length == 0 || length >= MAX_PATH_LENGTH - sizeof(" -s"))
+ {
+ ACE_ERROR ((LM_ERROR, "Error: Could not get module file name\n"));
+ return -1;
+ }
+
+ // Append the command used for running the implrepo as a service
+ ACE_OS::strcat (pathname, ACE_TEXT (" -s"));
+ int ret = -1;
+ if (opts.service_command () == Activator_Options::SC_INSTALL)
+ {
+ const char* DEPENDS_ON = "TAOImR"; // Must match Locator_NT_Service.h
+
+ ret = SERVICE::instance ()->insert (SERVICE_DEMAND_START,
+ SERVICE_ERROR_NORMAL,
+ pathname,
+ 0, // group
+ 0, // tag
+ DEPENDS_ON
+ );
+ }
+ else
+ {
+ ret = SERVICE::instance ()->insert (SERVICE_DEMAND_START,
+ SERVICE_ERROR_NORMAL,
+ pathname);
+ }
+ if (ret != -1)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR Activator: Service installed.\n"));
+ opts.save_registry_options ();
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR, "Error: Failed to install service.\n"));
+ }
+ if (ret == 0)
+ return 1;
+ }
+ else if (opts.service_command () == Activator_Options::SC_REMOVE)
+ {
+ int ret = SERVICE::instance ()->remove ();
+ ACE_DEBUG ((LM_DEBUG, "ImR Activator: Service removed.\n"));
+ if (ret == 0)
+ return 1; // If successfull, then we don't want to continue.
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR, "Error: Unknown service command :%d \n",
+ opts.service_command ()));
+ return -1;
+ }
+
+ return -1;
+
+#else /* ACE_WIN32 */
+ ACE_ERROR ((LM_ERROR, "NT Service not supported on this platform"));
+ return -1;
+#endif /* ACE_WIN32 */
+}
+
+int
+main (int argc, char *argv[])
+{
+ Activator_Options opts;
+
+ int result = opts.init (argc, argv);
+ if (result < 0)
+ return 1; // Error
+ else if (result > 0)
+ return 0; // No error, but we should exit anyway.
+
+ result = run_service_command (opts);
+ if (result < 0)
+ return 1; // Error
+ else if (result > 0)
+ return 0; // No error, but we should exit anyway.
+
+ if (opts.service ())
+ return run_service ();
+
+ return run_standalone (opts);
+}
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator.idl b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator.idl
new file mode 100644
index 00000000000..aa0fecbd401
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator.idl
@@ -0,0 +1,18 @@
+// -*- IDL -*-
+
+// $Id$
+
+#include "tao/ImR_Client/ImplRepo.pidl"
+
+module ImplementationRepository
+{
+ interface Activator
+ {
+ // Tells the activator to launch a server with the given information.
+ void start_server(in string name, in string cmdline,
+ in string dir, in EnvironmentList env) raises(CannotActivate);
+
+ oneway void shutdown();
+ };
+};
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
new file mode 100644
index 00000000000..7017ec1827d
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
@@ -0,0 +1,395 @@
+// $Id$
+
+#include "ImR_Activator_i.h"
+
+#include "Activator_Options.h"
+
+#include "tao/ORB_Core.h"
+
+#include "ace/Reactor.h"
+#include "ace/ARGV.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/os_include/os_netdb.h"
+
+static ACE_CString getHostName ()
+{
+ char host_name[MAXHOSTNAMELEN];
+ ACE_OS::hostname (host_name, MAXHOSTNAMELEN);
+ return ACE_CString (host_name);
+}
+
+ImR_Activator_i::ImR_Activator_i (void)
+: registration_token_(0)
+, debug_(0)
+, notify_imr_ (false)
+, name_ (getHostName ())
+{
+}
+
+static PortableServer::POA_ptr
+createPersistentPOA (PortableServer::POA_ptr root_poa, const char* poa_name ACE_ENV_ARG_DECL)
+{
+ PortableServer::LifespanPolicy_var life =
+ root_poa->create_lifespan_policy (PortableServer::PERSISTENT ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ PortableServer::IdAssignmentPolicy_var assign =
+ root_poa->create_id_assignment_policy (PortableServer::USER_ID ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ CORBA::PolicyList pols;
+ pols.length (2);
+ pols[0] = PortableServer::LifespanPolicy::_duplicate (life.in ());
+ pols[1] = PortableServer::IdAssignmentPolicy::_duplicate (assign.in ());
+
+ PortableServer::POAManager_var mgr = root_poa->the_POAManager ();
+ PortableServer::POA_var poa =
+ root_poa->create_POA(poa_name, mgr.in (), pols ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN(PortableServer::POA::_nil ());
+
+ life->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+ assign->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ return poa._retn ();
+}
+
+// It's ok if we can't register with the ImR. It just
+// means we won't be able to notify it of any events
+// (Currently, just that we're shutting down.)
+void
+ImR_Activator_i::register_with_imr (ImplementationRepository::Activator_ptr activator)
+{
+ ACE_TRY_NEW_ENV
+ {
+ if (this->debug_ > 1)
+ ACE_DEBUG( (LM_DEBUG, "ImR Activator: Contacting ImplRepoService...\n"));
+
+ // First, resolve the ImR, without this we can go no further
+ CORBA::Object_var obj =
+ orb_->resolve_initial_references ("ImplRepoService" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->process_mgr_.open (ACE_Process_Manager::DEFAULT_SIZE,
+ this->orb_->orb_core ()->reactor ());
+
+ locator_ = ImplementationRepository::Locator::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (!CORBA::is_nil (locator_.in ()))
+ {
+ this->registration_token_ =
+ locator_->register_activator (name_.c_str (), activator ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (debug_ > 0)
+ ACE_DEBUG((LM_DEBUG, "ImR Activator: Registered with ImR.\n"));
+
+ return;
+ }
+ }
+ ACE_CATCHANY
+ {
+ if (debug_ > 1)
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR Activator: Can't register with ImR.");
+ }
+ ACE_ENDTRY;
+
+ if (debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR Activator: Not registered with ImR.\n"));
+}
+
+int
+ImR_Activator_i::init_with_orb (CORBA::ORB_ptr orb, const Activator_Options& opts ACE_ENV_ARG_DECL)
+{
+ ACE_ASSERT(! CORBA::is_nil (orb));
+ orb_ = CORBA::ORB::_duplicate (orb);
+ debug_ = opts.debug ();
+ notify_imr_ = opts.notify_imr ();
+ if (opts.name ().length () > 0)
+ {
+ name_ = opts.name();
+ }
+
+ ACE_TRY
+ {
+ CORBA::Object_var obj = orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ ACE_ASSERT (! CORBA::is_nil (obj.in ()));
+ this->root_poa_ = PortableServer::POA::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ ACE_ASSERT (! CORBA::is_nil(this->root_poa_.in ()));
+
+ // The activator must use a persistent POA so that it can be started before the
+ // locator in some scenarios, such as when the locator persists its database, and
+ // wants to reconnect to running activators to auto_start some servers.
+ this->imr_poa_ = createPersistentPOA (this->root_poa_.in (),
+ "ImR_Activator" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ ACE_ASSERT (! CORBA::is_nil(this->imr_poa_.in ()));
+
+ // Activate ourself
+ PortableServer::ObjectId_var id = PortableServer::string_to_ObjectId ("ImR_Activator");
+ this->imr_poa_->activate_object_with_id (id.in (), this ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ obj = this->imr_poa_->id_to_reference (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ ImplementationRepository::Activator_var activator =
+ ImplementationRepository::Activator::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ ACE_ASSERT(! CORBA::is_nil (activator.in ()));
+
+ CORBA::String_var ior = this->orb_->object_to_string (activator.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (this->debug_ > 0)
+ ACE_DEBUG((LM_DEBUG, "ImR Activator: Starting %s\n", name_.c_str ()));
+
+ // initialize our process manager.
+ // This requires a reactor that has signal handling.
+ ACE_Reactor *reactor = ACE_Reactor::instance ();
+ if (reactor != 0)
+ {
+ if (this->process_mgr_.open (ACE_Process_Manager::DEFAULT_SIZE, reactor) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "The ACE_Process_Manager didnt get initialized\n"), -1);
+ }
+ }
+
+ this->register_with_imr (activator.in ()); // no throw
+
+ PortableServer::POAManager_var poaman =
+ this->root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ poaman->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (this->debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR Activator: The Activator IOR is: <%s>\n", ior.in ()));
+ }
+
+ // The last thing we do is write out the ior so that a test program can assume
+ // that the activator is ready to go as soon as the ior is written.
+ if (opts.ior_filename ().length () > 0)
+ {
+ FILE* fp = ACE_OS::fopen (opts.ior_filename ().c_str (), "w");
+ if (fp == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ImR Activator: Could not open file: %s\n", opts.ior_filename ().c_str ()), -1);
+ }
+ ACE_OS::fprintf (fp, "%s", ior.in ());
+ ACE_OS::fclose (fp);
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR_Activator_i::init_with_orb");
+ ACE_RE_THROW;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (-1);
+ return 0;
+}
+
+int
+ImR_Activator_i::init (Activator_Options& opts ACE_ENV_ARG_DECL)
+{
+ ACE_CString cmdline = opts.cmdline();
+ // Must use IOR style objrefs, because URLs sometimes get mangled when passed
+ // to ACE_Process::spawn().
+ cmdline += "-ORBUseImR 0 -ORBObjRefStyle IOR ";
+ ACE_ARGV av (cmdline.c_str ());
+ int argc = av.argc ();
+
+ CORBA::ORB_var orb =
+ CORBA::ORB_init (argc, av.argv (), "TAO_ImR_Activator" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN(-1);
+
+ int ret = this->init_with_orb(orb.in (), opts ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN(-1);
+
+ return ret;
+}
+
+int
+ImR_Activator_i::fini (ACE_ENV_SINGLE_ARG_DECL)
+{
+ ACE_TRY_EX (try_block_1)
+ {
+ if (debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR Activator: Shutting down...\n"));
+
+ this->process_mgr_.close ();
+
+ this->root_poa_->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK_EX (try_block_1);
+
+ if (! CORBA::is_nil (this->locator_.in ()) && this->registration_token_ != 0)
+ {
+ this->locator_->unregister_activator (name_.c_str(),
+ this->registration_token_ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK_EX (try_block_1);
+ }
+ }
+ ACE_CATCH(CORBA::COMM_FAILURE, ex)
+ {
+ if (debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR Activator: Unable to unregister from ImR.\n"));
+ }
+ ACE_CATCH(CORBA::TRANSIENT, ex)
+ {
+ if (debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR Activator: Unable to unregister from ImR.\n"));
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR Activator: fini");
+ ACE_RE_THROW_EX (try_block_1);
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (-1);
+
+ ACE_TRY_EX (try_block_2)
+ {
+ this->orb_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK_EX (try_block_2);
+
+ if (debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR Activator: Shut down successfully.\n"));
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR Activator: fini 2");
+ ACE_RE_THROW_EX (try_block_2);
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (-1);
+ return 0;
+}
+
+int
+ImR_Activator_i::run (ACE_ENV_SINGLE_ARG_DECL)
+{
+ this->orb_->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ return 0;
+}
+
+void
+ImR_Activator_i::shutdown (ACE_ENV_SINGLE_ARG_DECL)
+ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ shutdown (false ACE_ENV_ARG_PARAMETER);
+}
+
+void
+ImR_Activator_i::shutdown (bool wait_for_completion ACE_ENV_ARG_DECL)
+{
+ this->orb_->shutdown (wait_for_completion ACE_ENV_ARG_PARAMETER);
+}
+
+void
+ImR_Activator_i::start_server(const char* name,
+ const char* cmdline,
+ const char* dir,
+ const ImplementationRepository::EnvironmentList & env ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::CannotActivate))
+{
+ if (debug_ > 1)
+ ACE_DEBUG((LM_DEBUG, "ImR Activator: Starting server <%s>...\n", name));
+ if (debug_ > 1)
+ ACE_DEBUG((LM_DEBUG, "\tcommand line : <%s>\n\tdirectory : <%s>\n", cmdline, dir));
+
+ ACE_Process_Options proc_opts;
+ proc_opts.command_line (cmdline);
+ proc_opts.working_directory (dir);
+ // Win32 does not support the CLOSE_ON_EXEC semantics for sockets
+ // the way unix does, so in order to avoid having the child process
+ // hold the listen socket open, we force the child to inherit no
+ // handles. This includes stdin, stdout, logs, etc.
+ proc_opts.handle_inheritence (0);
+
+ proc_opts.setenv ("TAO_USE_IMR", "1");
+ if (!CORBA::is_nil (this->locator_.in ()))
+ {
+ CORBA::String_var ior = orb_->object_to_string (locator_.in ());
+ proc_opts.setenv ("ImplRepoServiceIOR", ior.in());
+ }
+
+ for (CORBA::ULong i = 0; i < env.length (); ++i)
+ {
+ proc_opts.setenv (env[i].name.in (), env[i].value.in ());
+ }
+
+ int pid = this->process_mgr_.spawn (proc_opts);
+ if (pid == ACE_INVALID_PID)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "ImR Activator: Cannot start server <%s> using <%s>\n", name, cmdline));
+
+ ACE_THROW(ImplementationRepository::CannotActivate(CORBA::string_dup ("Process Creation Failed")));
+ return;
+ }
+ else
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "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);
+ }
+ }
+
+ if (debug_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR Activator: Successfully started <%s>. \n", name));
+ }
+}
+
+int
+ImR_Activator_i::handle_exit (ACE_Process * process)
+{
+ // We use the process_manager so that we're notified when
+ // any of our launched processes die. We notify the locator
+ // when this happens.
+
+ if (debug_ > 0)
+ {
+ ACE_DEBUG
+ ((LM_DEBUG,
+ ACE_TEXT ("Process %d exited with exit code %d\n"),
+ process->getpid (), process->return_value ()));
+ }
+
+ ACE_CString name;
+ if (this->process_map_.find (process->getpid (), name) == 0)
+ {
+ this->process_map_.unbind (process->getpid ());
+
+ if (!CORBA::is_nil (this->locator_.in ()))
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ImR Activator: Notifying ImR that %s has exited.\n"),
+ name.c_str()));
+ }
+ this->locator_->notify_child_death (name.c_str());
+ }
+ }
+
+ return 0;
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h
new file mode 100644
index 00000000000..7b62dc525cf
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h
@@ -0,0 +1,128 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+* @file ImR_Activator_i.h
+*
+* $Id$
+*
+* @author Priyanka Gontla <gontla_p@ociweb.com>
+* @author Darrell Brunsch <brunsch@cs.wustl.edu>
+*/
+//=============================================================================
+
+#ifndef IMR_ACTIVATOR_I_H
+#define IMR_ACTIVATOR_I_H
+
+#include "activator_export.h"
+
+#include "ImR_ActivatorS.h"
+#include "ImR_LocatorC.h"
+
+#include "ace/Process_Manager.h"
+#include "ace/Hash_Map_Manager.h"
+#include "ace/Null_Mutex.h"
+#include "ace/SString.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class Activator_Options;
+
+// ace/Functor.h doesn't provide functors for every built in integer type.
+// Depending on the platform and what pid_t maps to, the functors may be missing.
+struct ACE_Hash_pid_t
+{
+ unsigned long operator () (pid_t t) const
+ {
+ return t;
+ }
+};
+
+struct ACE_Equal_To_pid_t
+{
+ int operator () (const pid_t lhs, const pid_t rhs) const
+ {
+ return lhs == rhs;
+ }
+};
+
+
+/**
+* @class ImR_Activator_i
+*
+* @brief IMR Activator Interface.
+*
+* This class provides the interface for the various activities
+* that can be done by the ImR_Activator.
+*
+*/
+class Activator_Export ImR_Activator_i : public POA_ImplementationRepository::Activator,
+ public ACE_Event_Handler
+{
+public:
+ ImR_Activator_i (void);
+
+ void start_server (
+ const char* name,
+ const char* cmdline,
+ const char* dir,
+ const ImplementationRepository::EnvironmentList & env ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::CannotActivate));
+
+ void shutdown(ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ /// Initialize the Server state - parsing arguments and waiting.
+ int init (Activator_Options& opts ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+
+ /// Cleans up any state created by init*.
+ int fini (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+
+ /// Runs the orb.
+ int run (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);
+
+ /// Shutdown the orb.
+ void shutdown (bool wait_for_completion ACE_ENV_ARG_DECL);
+
+private:
+
+ int init_with_orb (CORBA::ORB_ptr orb, const Activator_Options& opts ACE_ENV_ARG_DECL_WITH_DEFAULTS);
+
+ void register_with_imr(ImplementationRepository::Activator_ptr activator);
+
+ // Handles the death of the child processes of the ImR_Activator.
+ // Informs the ImR_Locator too.
+ int handle_exit (ACE_Process * process);
+
+private:
+
+ typedef ACE_Hash_Map_Manager_Ex<pid_t,
+ ACE_CString,
+ ACE_Hash_pid_t,
+ ACE_Equal_To_pid_t,
+ ACE_Null_Mutex> ProcessMap;
+
+ ACE_Process_Manager process_mgr_;
+
+ PortableServer::POA_var root_poa_;
+ PortableServer::POA_var imr_poa_;
+
+ ImplementationRepository::Locator_var locator_;
+
+ /// We're given a token when registering with the locator, which
+ /// we must use when unregistering.
+ CORBA::Long registration_token_;
+
+ CORBA::ORB_var orb_;
+
+ unsigned int debug_;
+
+ bool notify_imr_;
+
+ ACE_CString name_;
+
+ ProcessMap process_map_;
+};
+
+#endif /* IMR_ACTIVATOR_I_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.cpp
new file mode 100644
index 00000000000..12be58dd8cd
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.cpp
@@ -0,0 +1,201 @@
+// $Id$
+
+#include "ImR_Locator_i.h"
+#include "Locator_NT_Service.h"
+#include "Locator_Options.h"
+#include "orbsvcs/Shutdown_Utilities.h"
+
+class ImR_Locator_Shutdown : public Shutdown_Functor
+{
+public:
+ ImR_Locator_Shutdown (ImR_Locator_i& imr);
+
+ void operator() (int which_signal);
+private:
+ ImR_Locator_i& imr_;
+};
+
+ImR_Locator_Shutdown::ImR_Locator_Shutdown (ImR_Locator_i &imr)
+ : imr_(imr)
+{
+}
+
+void
+ImR_Locator_Shutdown::operator () (int /*which_signal*/)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->imr_.shutdown (true ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR: ");
+ }
+ ACE_ENDTRY;
+}
+
+int
+run_standalone (Options& opts)
+{
+ ImR_Locator_i server;
+
+ ImR_Locator_Shutdown killer (server);
+ Service_Shutdown kill_contractor(killer);
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ int status = server.init (opts ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (status == -1)
+ {
+ return 1;
+ }
+ else
+ {
+ // Run the server if it is initialized correctly.
+ server.run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // End the server after its work is done.
+ status = server.fini (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (status == -1)
+ return 1;
+ }
+ return 0;
+ }
+ ACE_CATCH (CORBA::SystemException, sysex)
+ {
+ ACE_PRINT_EXCEPTION (sysex, "System Exception");
+ }
+ ACE_CATCH (CORBA::UserException, userex)
+ {
+ ACE_PRINT_EXCEPTION (userex, "User Exception");
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Unknown Exception");
+ }
+ ACE_ENDTRY;
+
+ return 1;
+}
+
+#if defined (ACE_WIN32)
+ACE_NT_SERVICE_DEFINE (service, Locator_NT_Service, IMR_LOCATOR_SERVICE_NAME);
+#endif /* ACE_WIN32 */
+
+int
+run_service (void)
+{
+#if defined (ACE_WIN32)
+
+ SERVICE::instance ()->name (IMR_LOCATOR_SERVICE_NAME, IMR_LOCATOR_DISPLAY_NAME);
+
+ ACE_NT_SERVICE_RUN (service, SERVICE::instance (), ret);
+
+ if (ret == 0)
+ ACE_ERROR ((LM_ERROR, "%p\n", "Couldn't start service"));
+
+ return ret;
+#else /* ACE_WIN32 */
+ return 1;
+#endif /* ACE_WIN32 */
+}
+
+/**
+ * Executes the various commands that are useful for a NT service. Right
+ * now these include 'install' and 'remove'. Others, such as 'start' and
+ * 'stop' can be added, but the 'net' program in Windows already handles
+ * these commands.
+ */
+static int
+run_service_command (Options& opts)
+{
+ if (opts.service_command () == Options::SC_NONE)
+ return 0;
+
+#if defined (ACE_WIN32)
+ SERVICE::instance()->name (IMR_LOCATOR_SERVICE_NAME, IMR_LOCATOR_DISPLAY_NAME);
+
+ if (opts.service_command () == Options::SC_INSTALL)
+ {
+ const DWORD MAX_PATH_LENGTH = 4096;
+ char pathname[MAX_PATH_LENGTH];
+
+ DWORD length = ACE_TEXT_GetModuleFileName (NULL, pathname, MAX_PATH_LENGTH);
+ if (length == 0 || length >= MAX_PATH_LENGTH - sizeof(" -s"))
+ {
+ ACE_ERROR ((LM_ERROR, "Error: Could not get module file name\n"));
+ return -1;
+ }
+
+ // Append the command used for running the implrepo as a service
+ ACE_OS::strcat (pathname, ACE_TEXT (" -s"));
+
+ int ret = SERVICE::instance ()->insert (SERVICE_DEMAND_START,
+ SERVICE_ERROR_NORMAL,
+ pathname);
+ if (ret != -1)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: Service installed.\n"));
+ opts.save_registry_options ();
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR, "Error: Failed to install service. error:%d\n", errno));
+ }
+ if (ret == 0)
+ return 1;
+ }
+ else if (opts.service_command () == Options::SC_REMOVE)
+ {
+ int ret = SERVICE::instance ()->remove ();
+ ACE_DEBUG ((LM_DEBUG, "ImR: Service removed.\n"));
+ if (ret == 0)
+ return 1; // If successfull, then we don't want to continue.
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR, "Error: Unknown service command :%d \n",
+ opts.service_command ()));
+ return -1;
+ }
+
+ return -1;
+
+#else /* ACE_WIN32 */
+ ACE_ERROR ((LM_ERROR, "NT Service not supported on this platform"));
+ return -1;
+#endif /* ACE_WIN32 */
+}
+
+int
+main (int argc, char *argv[])
+{
+ Options opts;
+
+ int result = opts.init (argc, argv);
+ if (result < 0)
+ return 1; // Error
+ else if (result > 0)
+ return 0; // No error, but we should exit anyway.
+
+ result = run_service_command(opts);
+ if (result < 0)
+ return 1; // Error
+ else if (result > 0)
+ return 0; // No error, but we should exit anyway.
+
+ if (opts.service ())
+ {
+ return run_service ();
+ }
+
+ return run_standalone (opts);
+}
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl
new file mode 100644
index 00000000000..acae98bb07f
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator.idl
@@ -0,0 +1,22 @@
+// -*- IDL -*-
+
+// $Id$
+
+#include "ImR_Activator.idl"
+
+module ImplementationRepository
+{
+ interface Locator : Administration
+ {
+ // returns a token that can be used (along with activator name) to unregister the activator.
+ long register_activator (in string name, in Activator act);
+
+ // You must pass in the token returned from register_activator.
+ void unregister_activator (in string name, in long token);
+
+ // The ImR_Activator calls this method to notify death of child
+ // process that it had started.
+ void notify_child_death (in string name);
+ };
+};
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
new file mode 100644
index 00000000000..95684378c77
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
@@ -0,0 +1,1532 @@
+// $Id$
+
+#include "ImR_Locator_i.h"
+#include "utils.h"
+#include "Iterator.h"
+#include "INS_Locator.h"
+
+#include "orbsvcs/Time_Utilities.h"
+
+#include "tao/IORTable/IORTable.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/ORB_Core.h"
+#include "tao/default_ports.h"
+#include "tao/Messaging/Messaging.h"
+#include "tao/AnyTypeCode/Any.h"
+
+#include "ace/ARGV.h"
+#include "ace/OS_NS_sys_time.h"
+#include "ace/Vector_T.h"
+
+static const int DEFAULT_START_LIMIT = 1;
+
+static const int PING_RETRY_SCHEDULE[] = {0, 10, 100, 500, 1000, 1000, 1000, 1000, 5000, 5000};
+
+static const ACE_Time_Value DEFAULT_SERVER_TIMEOUT (0, 10 * 1000); // 10ms
+// We want to give shutdown a little more time to work, so that we
+// can guarantee to the tao_imr utility that it has shutdown. The tao_imr
+// utility prints a different message depending on whether shutdown succeeds
+// or times out.
+static const ACE_Time_Value DEFAULT_SHUTDOWN_TIMEOUT (0, 5000 * 1000);
+
+static PortableServer::POA_ptr
+createPersistentPOA (PortableServer::POA_ptr root_poa, const char* poa_name ACE_ENV_ARG_DECL) {
+
+ PortableServer::LifespanPolicy_var life =
+ root_poa->create_lifespan_policy (PortableServer::PERSISTENT ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ PortableServer::IdAssignmentPolicy_var assign =
+ root_poa->create_id_assignment_policy (PortableServer::USER_ID ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ CORBA::PolicyList pols;
+ pols.length (2);
+ pols[0] = PortableServer::LifespanPolicy::_duplicate (life.in ());
+ pols[1] = PortableServer::IdAssignmentPolicy::_duplicate (assign.in ());
+
+ PortableServer::POAManager_var mgr = root_poa->the_POAManager ();
+ PortableServer::POA_var poa =
+ root_poa->create_POA (poa_name, mgr.in (), pols ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ life->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+ assign->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (PortableServer::POA::_nil ());
+
+ return poa._retn ();
+}
+
+ImR_Locator_i::ImR_Locator_i (void)
+ : forwarder_ (*this)
+ , ins_locator_ (0)
+ , debug_ (0)
+ , read_only_ (false)
+{
+ // Visual C++ 6.0 is not smart enough to do a direct assignment
+ // while allocating the INS_Locator. So, we have to do it in
+ // two steps.
+ INS_Locator* locator;
+ ACE_NEW (locator,
+ INS_Locator (*this));
+ ins_locator_ = locator;
+}
+
+ImR_Locator_i::~ImR_Locator_i (void)
+{
+ // For some reason g++ 4.0 needs this out-of-line destructor instead
+ // of the default one generated by the compiler. Without this
+ // destructor, we get a number of "undefined reference" link errors
+ // related to the virtual tables of the INS_Locator, ImR_Adapter and
+ // ImR_Forwarder members in this class.
+}
+
+int
+ImR_Locator_i::init_with_orb (CORBA::ORB_ptr orb, Options& opts ACE_ENV_ARG_DECL)
+{
+ orb_ = CORBA::ORB::_duplicate (orb);
+ debug_ = opts.debug ();
+ read_only_ = opts.readonly ();
+ startup_timeout_ = opts.startup_timeout ();
+ ping_interval_ = opts.ping_interval ();
+
+ CORBA::Object_var obj =
+ this->orb_->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ this->root_poa_ = PortableServer::POA::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ ACE_ASSERT (! CORBA::is_nil (this->root_poa_.in ()));
+
+ this->forwarder_.init (orb ACE_ENV_ARG_PARAMETER);
+ this->adapter_.init (& this->forwarder_);
+
+ // Register the Adapter_Activator reference to be the RootPOA's
+ // Adapter Activator.
+ root_poa_->the_activator (&this->adapter_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Use a persistent POA so that any IOR
+ this->imr_poa_ = createPersistentPOA (this->root_poa_.in (),
+ "ImplRepo_Service" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ ACE_ASSERT (! CORBA::is_nil (this->imr_poa_.in ()));
+
+ waiter_svt_.debug (debug_ > 1);
+ PortableServer::ObjectId_var id = PortableServer::string_to_ObjectId ("ImR_AsyncStartupWaiter");
+ this->imr_poa_->activate_object_with_id (id.in (), &waiter_svt_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ obj = this->imr_poa_->id_to_reference (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ if (startup_timeout_ > ACE_Time_Value::zero)
+ {
+ obj = set_timeout_policy (obj.in (), startup_timeout_);
+ }
+ waiter_ = ImplementationRepository::AsyncStartupWaiter::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ id = PortableServer::string_to_ObjectId ("ImplRepo_Service");
+ this->imr_poa_->activate_object_with_id (id.in (), this ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ obj = this->imr_poa_->id_to_reference (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ CORBA::String_var ior = this->orb_->object_to_string (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Register the ImR for use with INS
+ obj = orb->resolve_initial_references ("IORTable" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ IORTable::Table_var ior_table = IORTable::Table::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ ACE_ASSERT (! CORBA::is_nil (ior_table.in ()));
+ ior_table->bind ("ImplRepoService", ior.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ ior_table->bind ("ImR", ior.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ ior_table->set_locator (this->ins_locator_.in () ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // Set up multicast support (if enabled)
+ if (opts.multicast ())
+ {
+ ACE_Reactor* reactor = orb->orb_core ()->reactor ();
+ if (this->setup_multicast (reactor, ior.in ()) != 0)
+ return -1;
+ }
+
+ // Initialize the persistent storage. This will load any values that
+ // may have been persisted before.
+ // The init can return 1 if there is no persistent file yet. In
+ // that case, we need not do anything for now.
+ int init_result =
+ this->repository_.init (opts);
+ if (init_result == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR, "Repository failed to initialize\n"), -1);
+ }
+
+ // Activate the two poa managers
+ PortableServer::POAManager_var poaman =
+ this->root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ poaman->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ poaman = this->imr_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ poaman->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ // We write the ior file last so that the tests can know we are ready.
+ if (opts.ior_filename ().length () > 0)
+ {
+ FILE* fp = ACE_OS::fopen (opts.ior_filename ().c_str (), "w");
+ if (fp == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ImR: Could not open file: %s\n", opts.ior_filename ().c_str ()), -1);
+ }
+ ACE_OS::fprintf (fp, "%s", ior.in ());
+ ACE_OS::fclose (fp);
+ }
+
+ return 0;
+}
+
+int
+ImR_Locator_i::init (Options& opts ACE_ENV_ARG_DECL)
+{
+ ACE_CString cmdline = opts.cmdline ();
+ cmdline += " -orbcollocation no -orbuseimr 0";
+ ACE_ARGV av (cmdline.c_str ());
+ int argc = av.argc ();
+ char** argv = av.argv ();
+
+ CORBA::ORB_var orb = CORBA::ORB_init (argc, argv, "TAO_ImR_Locator" ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ int err = this->init_with_orb (orb.in (), opts ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ return err;
+}
+
+int
+ImR_Locator_i::run (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (debug_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Implementation Repository: Running\n"
+ "\tPing Interval : %dms\n"
+ "\tStartup Timeout : %ds\n"
+ "\tPersistence : %s\n"
+ "\tMulticast : %s\n"
+ "\tDebug : %d\n"
+ "\tLocked : %s\n\n",
+ ping_interval_.msec (),
+ startup_timeout_.sec (),
+ repository_.repo_mode (),
+ ior_multicast_.reactor () != 0 ? "Enabled" : "Disabled",
+ debug (),
+ read_only_ ? "True" : "False"));
+ }
+ this->auto_start_servers (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ this->orb_->run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ return 0;
+}
+
+void
+ImR_Locator_i::shutdown (CORBA::Boolean activators, CORBA::Boolean servers ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (servers != 0 && this->repository_.servers ().current_size () > 0)
+ {
+ // Note : shutdown is oneway, so we can't throw
+ ACE_ERROR ((LM_ERROR, "ImR: Shutdown of all servers not implemented.\n"));
+ }
+ if (activators != 0 && this->repository_.activators ().current_size () > 0)
+ {
+ ACE_Vector<ImplementationRepository::Activator_var> acts;
+ Locator_Repository::AIMap::ENTRY* entry = 0;
+ Locator_Repository::AIMap::ITERATOR it (this->repository_.activators ());
+ for (;it.next (entry) != 0; it.advance ())
+ {
+ Activator_Info_Ptr info = entry->int_id_;
+ ACE_ASSERT (! info.null ());
+ connect_activator (*info);
+ if (! CORBA::is_nil (info->activator.in ()))
+ acts.push_back (info->activator);
+ }
+
+ int shutdown_errs = 0;
+
+ for (size_t i = 0; i < acts.size (); ++i)
+ {
+ ACE_TRY
+ {
+ acts[i]->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ acts[i] = ImplementationRepository::Activator::_nil ();
+ }
+ ACE_CATCHANY
+ {
+ ++shutdown_errs;
+ if (debug_ > 1)
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR: shutdown activator");
+ }
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+ }
+ if (debug_ > 0 && shutdown_errs > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: Some activators could not be shut down.\n"));
+ }
+ }
+ // Technically, we should wait for all the activators to unregister, but
+ // ,for now at least, it doesn't seem worth it.
+ shutdown (false ACE_ENV_ARG_PARAMETER);
+}
+
+void
+ImR_Locator_i::shutdown (bool wait_for_completion ACE_ENV_ARG_DECL)
+{
+ this->orb_->shutdown (wait_for_completion ACE_ENV_ARG_PARAMETER);
+}
+
+int
+ImR_Locator_i::fini (ACE_ENV_SINGLE_ARG_DECL)
+{
+ ACE_TRY
+ {
+ if (debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Shutting down...\n"));
+
+ teardown_multicast ();
+
+ this->root_poa_->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->orb_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Shut down successfully.\n"));
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR_Locator_i::fini");
+ ACE_RE_THROW;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (-1);
+ return 0;
+}
+
+void
+ImR_Locator_i::teardown_multicast ()
+{
+ ACE_Reactor* r = ior_multicast_.reactor ();
+ if (r != 0) {
+ r->remove_handler (&ior_multicast_, ACE_Event_Handler::READ_MASK);
+ ior_multicast_.reactor (0);
+ }
+}
+
+int
+ImR_Locator_i::setup_multicast (ACE_Reactor* reactor, const char* ior)
+{
+ ACE_ASSERT (reactor != 0);
+ ACE_ASSERT (ior != 0);
+#if defined (ACE_HAS_IP_MULTICAST)
+
+ TAO_ORB_Core* core = TAO_ORB_Core_instance ();
+ // See if the -ORBMulticastDiscoveryEndpoint option was specified.
+ ACE_CString mde (core->orb_params ()->mcast_discovery_endpoint ());
+
+ if (mde.length () != 0)
+ {
+ if (this->ior_multicast_.init (ior,
+ mde.c_str (), TAO_SERVICEID_IMPLREPOSERVICE) == -1)
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ // Port can be specified as param, env var, or default
+ CORBA::UShort port =
+ core->orb_params ()->service_port (TAO::MCAST_IMPLREPOSERVICE);
+ if (port == 0)
+ {
+ // Check environment var. for multicast port.
+ const char* port_number = ACE_OS::getenv ("ImplRepoServicePort");
+
+ if (port_number != 0)
+ port = static_cast<CORBA::UShort> (ACE_OS::atoi (port_number));
+ }
+ if (port == 0)
+ port = TAO_DEFAULT_IMPLREPO_SERVER_REQUEST_PORT;
+
+ if (this->ior_multicast_.init (ior, port,
+ ACE_DEFAULT_MULTICAST_ADDR, TAO_SERVICEID_IMPLREPOSERVICE) == -1)
+ {
+ return -1;
+ }
+ }
+
+ // Register event handler for the ior multicast.
+ if (reactor->register_handler (&this->ior_multicast_,
+ ACE_Event_Handler::READ_MASK) == -1)
+ {
+ if (debug_ >= 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: cannot register Event handler\n"));
+ return -1;
+ }
+#else /* ACE_HAS_IP_MULTICAST*/
+ ACE_UNUSED_ARG (reactor);
+ ACE_UNUSED_ARG (ior);
+#endif /* ACE_HAS_IP_MULTICAST*/
+ return 0;
+}
+
+CORBA::Long
+ImR_Locator_i::register_activator (const char* aname,
+ ImplementationRepository::Activator_ptr activator
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_ASSERT (aname != 0);
+ ACE_ASSERT (! CORBA::is_nil (activator));
+
+ // Before we can register the activator, we need to ensure that any existing
+ // registration is purged.
+ this->unregister_activator_i (aname);
+ ACE_CHECK_RETURN (0);
+
+ CORBA::String_var ior =
+ this->orb_->object_to_string (activator ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ CORBA::Long token = ACE_OS::gettimeofday ().msec ();
+
+ int err = this->repository_.add_activator (aname, token, ior.in (), activator);
+ ACE_ASSERT (err == 0);
+ ACE_UNUSED_ARG (err);
+
+ if (this->debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Activator registered for %s.\n", aname));
+
+ return token;
+}
+
+void
+ImR_Locator_i::unregister_activator (const char* aname,
+ CORBA::Long token
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_ASSERT (aname != 0);
+ Activator_Info_Ptr info = this->get_activator (aname);
+
+ if (! info.null ())
+ {
+ if (info->token != token && this->debug_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: Ignoring unregister activator:%s. Wrong token.\n", aname));
+ return;
+ }
+
+ this->unregister_activator_i (aname);
+ ACE_CHECK;
+
+ if (this->debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Activator %s unregistered.\n", aname));
+ }
+ else
+ {
+ if (this->debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Ignoring unregister activator:%s. Unknown activator.\n", aname));
+ }
+}
+
+void
+ImR_Locator_i::unregister_activator_i (const char* aname)
+{
+ ACE_ASSERT (aname != 0);
+ int err = this->repository_.remove_activator (aname);
+ ACE_UNUSED_ARG (err);
+}
+
+void
+ImR_Locator_i::notify_child_death (const char* name ACE_ENV_ARG_DECL_NOT_USED)
+ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_ASSERT (name != 0);
+
+ if (this->debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Server has died <%s>.\n", name));
+
+ Server_Info_Ptr info = this->repository_.get_server (name);
+ if (! info.null ())
+ {
+ info->ior = "";
+ info->partial_ior = "";
+
+ int err = this->repository_.update_server (*info);
+ ACE_ASSERT (err == 0);
+ ACE_UNUSED_ARG (err);
+ }
+ else
+ {
+ if (this->debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: Failed to find server in repository.\n"));
+ }
+}
+
+void
+ImR_Locator_i::activate_server (const char* server ACE_ENV_ARG_DECL)
+ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate))
+{
+ if (debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Manually activating server <%s>\n", server));
+
+ // This is the version called by tao_imr to activate the server, manually
+ // starting it if necessary.
+ activate_server_by_name (server, true ACE_ENV_ARG_PARAMETER);
+}
+
+char*
+ImR_Locator_i::activate_server_by_name (const char* name, bool manual_start ACE_ENV_ARG_DECL)
+ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate))
+{
+ // Activate the server, starting it if necessary. Don't start MANUAL
+ // servers unless manual_start=true
+ ACE_ASSERT (name != 0);
+
+ Server_Info_Ptr info = this->repository_.get_server (name);
+ if (info.null ())
+ {
+ ACE_ERROR ((LM_ERROR, "ImR: Cannot find info for server <%s>\n", name));
+ ACE_THROW_RETURN (ImplementationRepository::NotFound (), 0);
+ }
+
+ return activate_server_i (*info, manual_start ACE_ENV_ARG_PARAMETER);
+}
+
+char*
+ImR_Locator_i::activate_server_by_object (const char* object_name ACE_ENV_ARG_DECL)
+ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate))
+{
+ ACE_ASSERT (object_name != 0);
+
+ // We assume that the first part of the object name is the server name.
+ // So a name of foo/bar means that the server name is foo.
+ ACE_CString server_name (object_name);
+ ACE_CString::size_type pos = server_name.find ('/');
+ if (pos != ACE_CString::npos)
+ server_name = server_name.substr (pos + 1);
+
+ return activate_server_by_name (server_name.c_str (), false ACE_ENV_ARG_PARAMETER);
+}
+
+char*
+ImR_Locator_i::activate_server_i (Server_Info& info, bool manual_start ACE_ENV_ARG_DECL)
+ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate))
+{
+ if (info.activation_mode == ImplementationRepository::PER_CLIENT)
+ {
+ return activate_perclient_server_i (info, manual_start ACE_ENV_ARG_PARAMETER);
+ }
+
+ while (true)
+ {
+ if (is_alive (info))
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: Successfully activated <%s> at \n\t%s\n",
+ info.name.c_str (), info.partial_ior.c_str ()));
+ }
+ info.start_count = 0;
+
+ waiter_svt_.unblock_all (info.name.c_str ());
+
+ return CORBA::string_dup (info.partial_ior.c_str ());
+ }
+
+ info.reset ();
+
+ if (! info.starting && info.start_count >= info.start_limit)
+ {
+ if (this->debug_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: Cannot Activate <%s>.\n", info.name.c_str ()));
+ }
+
+ waiter_svt_.unblock_all (info.name.c_str ());
+
+ ACE_THROW_RETURN (ImplementationRepository::CannotActivate
+ (CORBA::string_dup ("Cannot start server.")), 0);
+ }
+
+ // Note : We already updated info with StartupInfo in server_is_running ()
+ ImplementationRepository::StartupInfo_var si =
+ start_server (info, manual_start ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+ }
+}
+
+char*
+ImR_Locator_i::activate_perclient_server_i (Server_Info info, bool manual_start ACE_ENV_ARG_DECL)
+ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate))
+{
+ do
+ {
+ ImplementationRepository::StartupInfo* psi =
+ start_server (info, manual_start ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
+ if (psi != 0)
+ {
+ ImplementationRepository::StartupInfo_var si = psi;
+ ACE_ASSERT (info.name == si->name.in ());
+ info.partial_ior = si->partial_ior.in ();
+ info.ior = si->ior.in ();
+
+ if (is_alive (info))
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: Successfully activated <%s> at \n\t%s\n",
+ info.name.c_str (), info.partial_ior.c_str ()));
+ }
+ return CORBA::string_dup (info.partial_ior.c_str ());
+ }
+ info.reset ();
+ }
+ } while (info.start_count < info.start_limit);
+
+ if (this->debug_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: Cannot Activate <%s>.\n", info.name.c_str ()));
+ }
+ ACE_THROW_RETURN (ImplementationRepository::CannotActivate
+ (CORBA::string_dup ("Cannot start server.")), 0);
+}
+
+ImplementationRepository::StartupInfo*
+ImR_Locator_i::start_server (Server_Info& info, bool manual_start ACE_ENV_ARG_DECL)
+ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate))
+{
+ if (info.activation_mode == ImplementationRepository::MANUAL && ! manual_start)
+ {
+ if (debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Cannot start server <%s>. ActivationMode=MANUAL\n", info.name.c_str ()));
+ ACE_THROW_RETURN (ImplementationRepository::CannotActivate
+ (CORBA::string_dup ("Cannot implicitly activate MANUAL server.")), 0);
+ }
+ if (info.cmdline.length () == 0)
+ {
+ if (debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Cannot start server <%s>."
+ " No command line.\n", info.name.c_str ()));
+ ACE_THROW_RETURN (ImplementationRepository::CannotActivate
+ (CORBA::string_dup ("No command line registered for server.")), 0);
+ }
+
+ Activator_Info_Ptr ainfo = get_activator (info.activator);
+
+ if (ainfo.null () || CORBA::is_nil (ainfo->activator.in ()))
+ {
+ if (debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Cannot start server <%s>. "
+ "Activator <%s> not found.\n", info.name.c_str (), info.activator.c_str ()));
+ ACE_THROW_RETURN (ImplementationRepository::CannotActivate
+ (CORBA::string_dup ("No activator registered for server.")), 0);
+ }
+
+ ACE_TRY
+ {
+ ++ info.waiting_clients;
+
+ if (info.waiting_clients <= 1 || info.activation_mode == ImplementationRepository::PER_CLIENT)
+ {
+ info.starting = true;
+ ++info.start_count;
+ ACE_ASSERT (info.start_count <= info.start_limit);
+ if (this->debug_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: Starting server <%s>. Attempt %d/%d.\n",
+ info.name.c_str (), info.start_count, info.start_limit));
+ }
+ ainfo->activator->start_server (
+ info.name.c_str (),
+ info.cmdline.c_str (),
+ info.dir.c_str (),
+ info.env_vars
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ if (info.partial_ior.length () == 0)
+ {
+ if (this->debug_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: Waiting for <%s> to start...\n", info.name.c_str ()));
+ }
+
+ ImplementationRepository::StartupInfo_var si =
+ waiter_->wait_for_startup (info.name.c_str () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ -- info.waiting_clients;
+ info.starting = false;
+
+ return si._retn ();
+ }
+ else // The server_is_running () came in before the wait_for_startup ()
+ {
+ if (this->debug_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: <%s> Skipping wait. Already started.\n", info.name.c_str ()));
+ }
+ -- info.waiting_clients;
+ info.starting = false;
+ }
+ }
+ ACE_CATCH (CORBA::TIMEOUT, ex)
+ {
+ -- info.waiting_clients;
+ info.starting = false;
+ // We may have connected successfully, because the timeout could occur before
+ // the AsyncStartupWaiter manages to return. In fact, when the ImR is very busy
+ // this is the most likely code path.
+ if (info.partial_ior.length () == 0)
+ {
+ if (debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR : Timeout waiting for <%s> to start.\n", info.name.c_str ()));
+ info.reset ();
+ }
+ }
+ ACE_CATCH (ImplementationRepository::CannotActivate, ex)
+ {
+ -- info.waiting_clients;
+ info.starting = false;
+ info.reset ();
+ if (debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Activator cannot start <%s>.\n", info.name.c_str ()));
+ }
+ ACE_CATCHANY
+ {
+ -- info.waiting_clients;
+ info.starting = false;
+ if (debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Unexpected exception while starting <%s>.\n", info.name.c_str ()));
+ if (debug_ > 1)
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "");
+ ainfo->reset ();
+ info.reset ();
+ }
+ ACE_ENDTRY;
+ return 0; // This is not a corba call, so a zero should be ok
+}
+
+CORBA::Object_ptr
+ImR_Locator_i::set_timeout_policy (CORBA::Object_ptr obj, const ACE_Time_Value& to)
+{
+ CORBA::Object_var ret (CORBA::Object::_duplicate (obj));
+
+ ACE_TRY_NEW_ENV
+ {
+ TimeBase::TimeT timeout;
+ ORBSVCS_Time::Time_Value_to_TimeT (timeout, to);
+ CORBA::Any tmp;
+ tmp <<= timeout;
+
+ CORBA::PolicyList policies (1);
+ policies.length (1);
+ policies[0] = orb_->create_policy (Messaging::RELATIVE_RT_TIMEOUT_POLICY_TYPE, tmp ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ret = obj->_set_policy_overrides (policies, CORBA::ADD_OVERRIDE ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ policies[0]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (ret.in ()))
+ {
+ if (this->debug_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: Unable to set timeout policy.\n"));
+ }
+ ret = CORBA::Object::_duplicate (obj);
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR_Locator_i::set_timeout_policy ()");
+ }
+ ACE_ENDTRY;
+
+ return ret._retn ();
+}
+
+void
+ImR_Locator_i::add_or_update_server (const char* server,
+ const ImplementationRepository::StartupOptions &options
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound))
+{
+ ACE_ASSERT (server != 0);
+
+ if (this->read_only_)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: Cannot add/update server <%s> due to locked database.\n", server));
+ ACE_THROW (CORBA::NO_PERMISSION (
+ CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0),
+ CORBA::COMPLETED_NO));
+ }
+
+ if (debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Add/Update server <%s>.\n", server));
+
+ int limit = options.start_limit;
+ if (limit < 0)
+ {
+ limit = -limit;
+ }
+ else if (limit == 0)
+ {
+ limit = 1;
+ }
+
+ Server_Info_Ptr info = this->repository_.get_server (server);
+ if (info.null ())
+ {
+ if (this->debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Adding server <%s>.\n", server));
+
+ this->repository_.add_server (server,
+ options.activator.in (),
+ options.command_line.in (),
+ options.environment,
+ options.working_directory.in (),
+ options.activation,
+ limit);
+ }
+ else
+ {
+ if (this->debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Updating server <%s>.\n", server));
+
+ info->activator = options.activator.in ();
+ info->cmdline = options.command_line.in ();
+ info->env_vars = options.environment;
+ info->dir = options.working_directory.in ();
+ info->activation_mode = options.activation;
+ info->start_limit = limit;
+ info->start_count = 0;
+ int err = this->repository_.update_server (*info);
+ ACE_ASSERT (err == 0);
+ ACE_UNUSED_ARG (err);
+ }
+
+ if (this->debug_ > 1)
+ {
+ // Note : The info var may be null, so we use options.
+ ACE_DEBUG ((LM_DEBUG, "ImR: Server: %s\n"
+ "\tActivator: %s\n"
+ "\tCommand Line: %s\n"
+ "\tWorking Directory: %s\n"
+ "\tActivation: %s\n"
+ "\tStart Limit: %d\n"
+ "\n",
+ server,
+ options.activator.in (),
+ options.command_line.in (),
+ options.working_directory.in (),
+ ImR_Utils::activationModeToString (options.activation).c_str (),
+ limit
+ ));
+
+ for (CORBA::ULong i = 0; i < options.environment.length (); ++i)
+ ACE_DEBUG ((LM_DEBUG, "Environment variable %s=%s\n",
+ options.environment[i].name.in (),
+ options.environment[i].value.in ()));
+ }
+}
+
+void
+ImR_Locator_i::remove_server (const char* name ACE_ENV_ARG_DECL)
+ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::NotFound))
+{
+ ACE_ASSERT (name != 0);
+ if (this->read_only_)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "ImR: Can't remove server <%s> due to locked database.\n", name));
+ ACE_THROW (CORBA::NO_PERMISSION (
+ CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0),
+ CORBA::COMPLETED_NO));
+ }
+
+ // Note : This will be safe, because any Server_Info_Ptr objects will still
+ // be valid, and the actual Server_Info will be destroyed when the last
+ // one goes out of scope.
+
+ Server_Info_Ptr info = this->repository_.get_server (name);
+ if (! info.null ())
+ {
+ if (this->repository_.remove_server (name) == 0)
+ {
+ if (this->debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Removing Server <%s>...\n", name));
+
+ PortableServer::POA_var poa = findPOA (name);
+ ACE_CHECK;
+ if (! CORBA::is_nil (poa.in ()))
+ {
+ bool etherealize = true;
+ bool wait = false;
+ poa->destroy (etherealize, wait ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ if (this->debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Removed Server <%s>.\n", name));
+ }
+ }
+ else
+ {
+ ACE_ERROR ((LM_ERROR,
+ "ImR: Can't remove unknown server <%s>.\n", name));
+ ACE_THROW (ImplementationRepository::NotFound ());
+ }
+}
+
+PortableServer::POA_ptr
+ImR_Locator_i::findPOA (const char* name)
+{
+ ACE_TRY_NEW_ENV
+ {
+ bool activate_it = false;
+ return root_poa_->find_POA (name, activate_it ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {// Ignore
+ }
+ ACE_ENDTRY;
+ return PortableServer::POA::_nil ();
+}
+
+void
+ImR_Locator_i::shutdown_server (const char* server ACE_ENV_ARG_DECL)
+ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::NotFound))
+{
+ ACE_ASSERT (server != 0);
+
+ if (this->debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Shutting down server <%s>.\n", server));
+
+ Server_Info_Ptr info = this->repository_.get_server (server);
+ if (info.null ())
+ {
+ ACE_ERROR ((LM_ERROR,
+ "ImR: shutdown_server () Cannot find info for server <%s>\n", server));
+ ACE_THROW (ImplementationRepository::NotFound ());
+ }
+
+ connect_server (*info);
+
+ if (CORBA::is_nil (info->server.in ()))
+ {
+ ACE_ERROR ((LM_ERROR,
+ "ImR: shutdown_server () Cannot connect to server <%s>\n", server));
+ ACE_THROW (ImplementationRepository::NotFound ());
+ }
+
+ ACE_TRY_NEW_ENV
+ {
+ CORBA::Object_var obj = set_timeout_policy (info->server.in (), DEFAULT_SHUTDOWN_TIMEOUT);
+ ImplementationRepository::ServerObject_var server =
+ ImplementationRepository::ServerObject::_unchecked_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ server->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (CORBA::TIMEOUT, ex)
+ {
+ info->reset ();
+ int err = this->repository_.update_server (*info);
+ ACE_ASSERT (err == 0);
+ ACE_UNUSED_ARG (err);
+ // Note : This is a good thing. It means we didn't waste our time waiting for
+ // the server to finish shutting down.
+ if (this->debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: Timeout while waiting for <%s> shutdown.\n", server));
+ }
+ ACE_RE_THROW;
+ }
+ ACE_CATCHANY
+ {
+ if (this->debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: Exception ignored while shutting down <%s>\n", server));
+ }
+ }
+ ACE_ENDTRY;
+
+ // Note : In most cases this has already been done in the server_is_shutting_down ()
+ // operation, but it doesn't hurt to update it again.
+ info->reset ();
+
+ int err = this->repository_.update_server (*info);
+ ACE_ASSERT (err == 0);
+ ACE_UNUSED_ARG (err);
+}
+
+void
+ImR_Locator_i::server_is_running (const char* name,
+ const char* partial_ior,
+ ImplementationRepository::ServerObject_ptr server
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound))
+{
+ ACE_ASSERT (name != 0);
+ ACE_ASSERT (partial_ior != 0);
+ ACE_ASSERT (! CORBA::is_nil (server));
+
+ if (this->debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Server %s is running at %s.\n", name, partial_ior));
+
+ CORBA::String_var ior = orb_->object_to_string (server ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ if (this->debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Server %s callback at %s.\n", name, ior.in ()));
+
+ Server_Info_Ptr info = this->repository_.get_server (name);
+ if (info.null ())
+ {
+ if (this->debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Auto adding NORMAL server <%s>.\n", name));
+
+ ImplementationRepository::EnvironmentList env (0);
+ this->repository_.add_server (name,
+ "", // no activator
+ "", // no cmdline
+ ImplementationRepository::EnvironmentList (),
+ "", // no working dir
+ ImplementationRepository::NORMAL,
+ DEFAULT_START_LIMIT,
+ partial_ior,
+ ior.in (),
+ ImplementationRepository::ServerObject::_nil () // Will connect at first access
+ );
+ }
+ else
+ {
+ if (info->activation_mode != ImplementationRepository::PER_CLIENT) {
+ info->ior = ior.in ();
+ info->partial_ior = partial_ior;
+ info->server = ImplementationRepository::ServerObject::_nil (); // Will connect at first access
+
+ int err = this->repository_.update_server (*info);
+ ACE_ASSERT (err == 0);
+ ACE_UNUSED_ARG (err);
+
+ waiter_svt_.unblock_one (name, partial_ior, ior.in (), false);
+ } else {
+ // Note : There's no need to unblock all the waiting request until
+ // we know the final status of the server.
+ waiter_svt_.unblock_one (name, partial_ior, ior.in (), true);
+ }
+ }
+}
+
+void
+ImR_Locator_i::server_is_shutting_down (const char* server ACE_ENV_ARG_DECL_NOT_USED)
+ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::NotFound))
+{
+ ACE_ASSERT (server != 0);
+ Server_Info_Ptr info = this->repository_.get_server (server);
+ if (info.null ())
+ {
+ if (this->debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR_Locator_i::server_is_shutting_down: Unknown server:%s\n", server));
+ }
+ return;
+ }
+
+ if (this->debug_ > 0)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Server <%s> is shutting down.\n", server));
+
+ info->reset ();
+
+ int err = this->repository_.update_server (*info);
+ ACE_ASSERT (err == 0);
+ ACE_UNUSED_ARG (err);
+}
+
+void
+ImR_Locator_i::find (const char* server,
+ ImplementationRepository::ServerInformation_out imr_info
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_ASSERT (server != 0);
+ ACE_NEW_THROW_EX (imr_info, ImplementationRepository::ServerInformation, CORBA::NO_MEMORY ());
+
+ Server_Info_Ptr info = this->repository_.get_server (server);
+ if (! info.null ())
+ {
+ imr_info = info->createImRServerInfo (ACE_ENV_SINGLE_ARG_PARAMETER);
+
+ if (this->debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Found server %s.\n", server));
+ }
+ else
+ {
+ if (debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Cannot find server <%s>\n", server));
+ }
+}
+
+void
+ImR_Locator_i::list (CORBA::ULong how_many,
+ ImplementationRepository::ServerInformationList_out server_list,
+ ImplementationRepository::ServerInformationIterator_out server_iterator
+ ACE_ENV_ARG_DECL
+ ) ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ if (this->debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: List servers.\n"));
+
+ // Initialize the out variables, so if we return early, they will
+ // not be dangling.
+ server_iterator = ImplementationRepository::ServerInformationIterator::_nil ();
+ ACE_NEW_THROW_EX (server_list,
+ ImplementationRepository::ServerInformationList (0), CORBA::NO_MEMORY ());
+
+ Locator_Repository::SIMap::ENTRY* entry = 0;
+ Locator_Repository::SIMap::ITERATOR it (this->repository_.servers ());
+
+ // Number of servers that will go into the server_list.
+ CORBA::ULong n = this->repository_.servers ().current_size ();
+ if (how_many > 0 && n > how_many)
+ {
+ n = how_many;
+ }
+
+ server_list->length (n);
+
+ if (this->debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR_Locator_i::list: Filling ServerList with %d servers\n", n));
+
+ for (CORBA::ULong i = 0; i < n; i++)
+ {
+ it.next (entry);
+ it.advance ();
+ ACE_ASSERT (entry != 0);
+
+ Server_Info_Ptr info = entry->int_id_;
+
+ ImplementationRepository::ServerInformation_var imr_info = info->createImRServerInfo (ACE_ENV_SINGLE_ARG_PARAMETER);
+ server_list[i] = *imr_info;
+ }
+
+ if (this->repository_.servers ().current_size () > n)
+ {
+ if (this->debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR_Locator_i::list: Creating ServerInformation Iterator\n"));
+
+ ImR_Iterator* imr_iter;
+
+ ACE_NEW_THROW_EX (imr_iter,
+ ImR_Iterator (n, this->repository_, this->imr_poa_.in ()),
+ CORBA::NO_MEMORY ());
+
+ PortableServer::ServantBase_var tmp (imr_iter);
+
+ ACE_TRY
+ {
+ PortableServer::ObjectId_var id =
+ this->imr_poa_->activate_object (imr_iter ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ CORBA::Object_var obj = this->imr_poa_->id_to_reference (id.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ server_iterator = ImplementationRepository::
+ ServerInformationIterator::_unchecked_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_RE_THROW;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+ }
+}
+
+Activator_Info_Ptr
+ImR_Locator_i::get_activator (const ACE_CString& aname)
+{
+ Activator_Info_Ptr info = this->repository_.get_activator (aname);
+ if (! info.null ())
+ {
+ this->connect_activator (*info);
+ }
+ return info;
+}
+
+void
+ImR_Locator_i::connect_activator (Activator_Info& info)
+{
+ if (! CORBA::is_nil (info.activator.in ()) || info.ior.length () == 0)
+ return;
+
+ ACE_TRY_NEW_ENV
+ {
+ CORBA::Object_var obj =
+ this->orb_->string_to_object (info.ior.c_str ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (obj.in ()))
+ {
+ info.reset ();
+ return;
+ }
+
+ if (startup_timeout_ > ACE_Time_Value::zero)
+ {
+ obj = set_timeout_policy (obj.in (), startup_timeout_);
+ }
+
+ info.activator =
+ ImplementationRepository::Activator::_unchecked_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (info.activator.in ()))
+ {
+ info.reset ();
+ return;
+ }
+
+ if (debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Connected to activator <%s>\n", info.name.c_str ()));
+ }
+ ACE_CATCHANY
+ {
+ info.reset ();
+ }
+ ACE_ENDTRY;
+}
+
+void
+ImR_Locator_i::auto_start_servers (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (this->repository_.servers ().current_size () == 0)
+ return;
+
+ Locator_Repository::SIMap::ENTRY* server_entry;
+ Locator_Repository::SIMap::ITERATOR server_iter (this->repository_.servers ());
+
+ // For each of the entries in the Locator_Repository, get the startup
+ // information and activate the servers, if they are not already
+ // running.
+ for (;server_iter.next (server_entry) != 0; server_iter.advance ())
+ {
+ Server_Info_Ptr info = server_entry->int_id_;
+ ACE_ASSERT (! info.null ());
+
+ ACE_TRY
+ {
+ if (info->activation_mode == ImplementationRepository::AUTO_START
+ && info->cmdline.length () > 0)
+ {
+ this->activate_server_i (*info, true ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCHANY
+ {
+ if (this->debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: AUTO_START Could not activate <%s>\n",
+ server_entry->ext_id_.c_str ()));
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "AUTO_START");
+ }
+ // Ignore exceptions
+ }
+ ACE_ENDTRY;
+ ACE_CHECK;
+ }
+}
+
+void
+ImR_Locator_i::connect_server (Server_Info& info)
+{
+ if (! CORBA::is_nil (info.server.in ()))
+ {
+ return; // already connected
+ }
+
+ if (info.ior.length () == 0)
+ {
+ info.reset ();
+ return; // can't connect
+ }
+
+ ACE_TRY_NEW_ENV
+ {
+ CORBA::Object_var obj = orb_->string_to_object (info.ior.c_str () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (obj.in ()))
+ {
+ info.reset ();
+ return;
+ }
+
+ obj = set_timeout_policy (obj.in (), DEFAULT_SERVER_TIMEOUT);
+
+ info.server =
+ ImplementationRepository::ServerObject::_unchecked_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (info.server.in ()))
+ {
+ info.reset ();
+ return;
+ }
+
+ if (debug_ > 1)
+ ACE_DEBUG ((LM_DEBUG, "ImR: Connected to server <%s>\n", info.name.c_str ()));
+ }
+ ACE_CATCHANY
+ {
+ info.reset ();
+ }
+ ACE_ENDTRY;
+}
+
+bool
+ImR_Locator_i::is_alive (Server_Info& info)
+{
+ const size_t table_size = sizeof (PING_RETRY_SCHEDULE) /
+ sizeof (*PING_RETRY_SCHEDULE);
+
+ for (size_t i = 0; i < table_size; ++i)
+ {
+ int status = this->is_alive_i (info);
+ if (status == 0)
+ return false;
+ if (status == 1)
+ return true;
+
+ // This is evil, but there's not much else we can do for now. We
+ // should never reach this code once the ImR Servers are fixed
+ // so that they don't lie about server_is_running. Currently,
+ // they send this notification during poa creation. We have to
+ // run the orb, because the very thing that may be slowing the
+ // aliveness of the servers is the fact that they're trying to
+ // register more objects with us. In practical testing, we
+ // never retried the ping more than once, because the second
+ // ping always timed out, even if the servers poa manager had
+ // not been activated. The only way we saw multiple retries was
+ // if we ran the orb on the server before the poa manager was
+ // activated. For this reason, the first retry is immediate,
+ // and the orb->run () call is not required. The call will
+ // likely timeout, and is_alive will return true.
+ if (PING_RETRY_SCHEDULE[i] > 0)
+ {
+ ACE_Time_Value tv (0, PING_RETRY_SCHEDULE[i] * 1000);
+ this->orb_->run (tv);
+ }
+ }
+ if (debug_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: <%s> Ping retry count exceeded. alive=maybe.\n", info.name.c_str ()));
+ }
+ // We return true here, because the server *might* be alive, it's just not starting in a timely
+ // manner. We can't return false, because then we'll just try to start another instance, and the
+ // same thing will likely happen.
+ info.last_ping = ACE_OS::gettimeofday ();
+ return true;
+}
+
+int
+ImR_Locator_i::is_alive_i (Server_Info& info)
+{
+ // This is used by the ACE_TRY below when exceptions are turned off.
+ ACE_DECLARE_NEW_CORBA_ENV;
+
+ if (info.ior.length () == 0 || info.partial_ior.length () == 0)
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: <%s> not running. alive=false.\n", info.name.c_str ()));
+ }
+ info.last_ping = ACE_Time_Value::zero;
+ return 0;
+ }
+
+ if (ping_interval_ == ACE_Time_Value::zero)
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: <%s> Ping verification disabled. alive=true.\n", info.name.c_str ()));
+ }
+ return 1;
+ }
+
+ if ((ACE_OS::gettimeofday () - info.last_ping) < ping_interval_)
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: <%s> within ping interval. alive=true.\n", info.name.c_str ()));
+ }
+ return 1;
+ }
+
+ // If we don't have enough information to start the server if it isn't already
+ // then we might as well assume it is running. That way the client can get the
+ // status directly from the server.
+ if (info.cmdline.length () == 0 || ! repository_.has_activator (info.activator))
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: Ping verification skipped. <%s> not startable.\n", info.name.c_str ()));
+ }
+ return 1;
+ }
+
+ connect_server (info);
+
+ if (CORBA::is_nil (info.server.in ()))
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: <%s> Could not connect. alive=false.\n", info.name.c_str ()));
+ }
+ return 0;
+ }
+
+ ACE_TRY
+ {
+ // Make a copy, in case the info is updated during the ping.
+ ImplementationRepository::ServerObject_var server = info.server;
+
+ // This will timeout if it takes too long
+ server->ping (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: <%s> Ping successful. alive=true\n", info.name.c_str ()));
+ }
+ info.last_ping = ACE_OS::gettimeofday ();
+ }
+ ACE_CATCH (CORBA::TRANSIENT, ex)
+ {
+ const CORBA::ULong BITS_5_THRU_12_MASK = 0x00000f80;
+ switch (ex.minor () & BITS_5_THRU_12_MASK)
+ {
+ case TAO_INVOCATION_SEND_REQUEST_MINOR_CODE:
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: <%s> Local TRANSIENT. alive=false.\n", info.name.c_str ()));
+ }
+ }
+ info.last_ping = ACE_Time_Value::zero;
+ return 0;
+ case TAO_POA_DISCARDING:
+ case TAO_POA_HOLDING:
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: <%s> Remote TRANSIENT. alive=maybe.\n", info.name.c_str ()));
+ }
+ }
+ return -1; // We keep trying to ping, because returning 1 now, would just lead
+ // to clients getting the same exception. If we can't ping after several
+ // attempts, then we'll give up and return 1, letting the client worry about it.
+ default:
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: <%s> TRANSIENT exception. alive=false.\n", info.name.c_str ()));
+ }
+ info.last_ping = ACE_Time_Value::zero;
+ }
+ return 0;
+ }
+ }
+ ACE_CATCH (CORBA::TIMEOUT, ex)
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "ImR: <%s> Ping timed out. alive=true.\n", info.name.c_str ()));
+ }
+ return 1; // This is "alive" as far as we're concerned. Presumably the client
+ // will have a less stringent timeout policy, or will want to know
+ // about the timeout. In any case, we're only guaranteeing that the
+ // server is alive, not that it's responsive.
+ }
+ ACE_CATCHANY
+ {
+ if (debug_ > 1)
+ {
+ ACE_DEBUG ((LM_DEBUG, "ImR: <%s> Unexpected Ping exception. alive=false\n", info.name.c_str ()));
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "\n");
+ }
+ info.last_ping = ACE_Time_Value::zero;
+ return false;
+ }
+ ACE_ENDTRY;
+ return 1;
+}
+
+int
+ImR_Locator_i::debug () const
+{
+ return debug_;
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h
new file mode 100644
index 00000000000..7dd3033bcbc
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h
@@ -0,0 +1,187 @@
+// $Id$
+
+#ifndef IMR_LOCATOR_I_H
+#define IMR_LOCATOR_I_H
+#include /**/ "ace/pre.h"
+
+#include "locator_export.h"
+
+#include "Adapter_Activator.h"
+#include "Forwarder.h"
+#include "Locator_Options.h"
+#include "Locator_Repository.h"
+#include "AsyncStartupWaiter_i.h"
+#include "tao/IORTable/IORTable.h"
+
+#include "orbsvcs/IOR_Multicast.h"
+
+#include "ImR_LocatorS.h"
+#include "AsyncStartupWaiterS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+class ACE_Reactor;
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+class INS_Locator;
+
+// Gets a request from a client and depending on the POA name,
+// requests an activator to take care of activating the
+// corresponding server and raises a forward exception to the
+// client pointing to the correct server.
+class Locator_Export ImR_Locator_i
+ : public virtual POA_ImplementationRepository::Locator
+{
+public:
+ ImR_Locator_i();
+
+ ~ImR_Locator_i (void);
+
+ /// Initialize the service, creating its own orb, poa, etc.
+ int init (Options& opts ACE_ENV_ARG_DECL);
+
+ /// Same as above, but use the given orb
+ int init_with_orb (CORBA::ORB_ptr orb, Options& opts ACE_ENV_ARG_DECL);
+
+ /// Cleans up any state created by init*.
+ int fini (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Run using the orb reference created during init()
+ int run (ACE_ENV_SINGLE_ARG_DECL);
+
+ /// Shutdown the orb.
+ void shutdown (bool wait_for_completion ACE_ENV_ARG_DECL);
+
+ int debug() const;
+ // Note : See the IDL for descriptions of the operations.
+
+ // Activator->Locator
+
+ virtual CORBA::Long register_activator (const char* name,
+ ImplementationRepository::Activator_ptr admin
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual void unregister_activator (const char* name,
+ CORBA::Long token ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual void notify_child_death (const char* name ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ // tao_imr->Locator
+
+ virtual void activate_server (const char * name
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate));
+ virtual void add_or_update_server (const char * name,
+ const ImplementationRepository::StartupOptions &options ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::NotFound));
+ virtual void remove_server (const char * name ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::NotFound));
+ virtual void shutdown_server (const char * name ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::NotFound));
+ virtual void find (const char * name,
+ ImplementationRepository::ServerInformation_out info ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual void list (
+ CORBA::ULong how_many,
+ ImplementationRepository::ServerInformationList_out server_list,
+ ImplementationRepository::ServerInformationIterator_out server_iterator ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+ virtual void shutdown(CORBA::Boolean activators, CORBA::Boolean servers ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ // Server->Locator
+
+ virtual void server_is_running (const char* name,
+ const char* partial_ior,
+ ImplementationRepository::ServerObject_ptr server_object
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::NotFound));
+ virtual void server_is_shutting_down (const char * name ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::NotFound));
+
+ // Used by the INS_Locator to start a sever given an object name
+ char* activate_server_by_object (const char* object_name ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate));
+
+ char* activate_server_by_name (const char * name, bool manual_start ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate));
+
+private:
+
+ char* activate_server_i (Server_Info& info, bool manual_start ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate));
+
+ char* activate_perclient_server_i (Server_Info info, bool manual_start ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate));
+
+ ImplementationRepository::StartupInfo*
+ start_server(Server_Info& info, bool manual_start ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ ImplementationRepository::NotFound,
+ ImplementationRepository::CannotActivate));
+
+ bool is_alive(Server_Info& info);
+ int is_alive_i(Server_Info& info);
+
+ // Set up the multicast related if 'm' is passed on the command
+ // line.
+ int setup_multicast (ACE_Reactor *reactor, const char *ior);
+ void teardown_multicast();
+
+ void unregister_activator_i(const char* activator);
+
+ Activator_Info_Ptr get_activator (const ACE_CString& name);
+ void connect_activator (Activator_Info& info);
+
+ void auto_start_servers(ACE_ENV_SINGLE_ARG_DECL);
+
+ CORBA::Object_ptr set_timeout_policy(CORBA::Object_ptr obj, const ACE_Time_Value& to);
+
+ void connect_server(Server_Info& info);
+
+ PortableServer::POA_ptr findPOA(const char* name);
+private:
+
+ // The class that handles the forwarding.
+ ImR_Forwarder forwarder_;
+
+ // Used for the forwarding of any type of POA.
+ ImR_Adapter adapter_;
+
+ /// The locator interface for the IORTable
+ IORTable::Locator_var ins_locator_;
+
+ CORBA::ORB_var orb_;
+ PortableServer::POA_var root_poa_;
+ PortableServer::POA_var imr_poa_;
+
+ int debug_;
+
+ TAO_IOR_Multicast ior_multicast_;
+
+ Locator_Repository repository_;
+
+ AsyncStartupWaiter_i waiter_svt_;
+ ImplementationRepository::AsyncStartupWaiter_var waiter_;
+
+ bool read_only_;
+ ACE_Time_Value startup_timeout_;
+ ACE_Time_Value ping_interval_;
+};
+
+#include /**/ "ace/post.h"
+#endif /* IMR_LOCATOR_I_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImplRepo_Service.mpc b/TAO/orbsvcs/ImplRepo_Service/ImplRepo_Service.mpc
new file mode 100644
index 00000000000..24d5c6e2a0c
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/ImplRepo_Service.mpc
@@ -0,0 +1,142 @@
+// $Id$
+
+project(ImR_Activator_IDL) : orbsvcslib, conv_lib, portableserver, imr_client, tao_versioning_idl_defaults {
+ sharedname = TAO_ImR_Activator_IDL
+ dynamicflags = ACTIVATOR_IDL_BUILD_DLL
+ idlflags += -Wb,export_macro=ActivatorIDL_Export -Wb,export_include=activator_idl_export.h
+ idl_files {
+ ImR_Activator.idl
+ }
+ source_files {
+ ImR_ActivatorS.cpp
+ ImR_ActivatorC.cpp
+ }
+ header_files {
+ activator_idl_export.h
+ }
+}
+
+project(ImR_Locator_IDL) : orbsvcslib, conv_lib, valuetype, portableserver, imr_client, messaging, tao_versioning_idl_defaults {
+ sharedname = TAO_ImR_Locator_IDL
+ after += ImR_Activator_IDL
+ libs += TAO_ImR_Activator_IDL
+ // Dont try to build this project if ImR_Activator_IDL is not built
+ requires += corba_messaging
+
+ dynamicflags = LOCATOR_IDL_BUILD_DLL
+ idlflags += -Wb,export_macro=LocatorIDL_Export -Wb,export_include=locator_idl_export.h
+ idl_files {
+ ImR_Locator.idl
+ }
+
+ idl_files {
+ idlflags += -GH
+ AsyncStartupWaiter.idl
+ }
+
+ source_files {
+ ImR_LocatorS.cpp
+ ImR_LocatorC.cpp
+ AsyncStartupWaiterS.cpp
+ AsyncStartupWaiterC.cpp
+ }
+ header_files {
+ locator_idl_export.h
+ }
+}
+
+project(ImR_Activator) : orbsvcslib, conv_lib, acexml, minimum_corba, valuetype, portableserver, imr_client, messaging, pi, codecfactory {
+ sharedname = TAO_ImR_Activator
+ dynamicflags = ACTIVATOR_BUILD_DLL
+ after += ImR_Activator_IDL ImR_Locator_IDL
+ libs += TAO_ImR_Activator_IDL TAO_ImR_Locator_IDL
+ // Dont try to build this project if ImR_Activator_IDL is not built
+ requires += corba_messaging
+
+ Source_Files {
+ ImR_Activator_i.cpp
+ Activator_Options.cpp
+ Activator_Loader.cpp
+ }
+ header_files {
+ activator_export.h
+ }
+ idl_files {
+ }
+}
+
+project(ImR_Locator) : orbsvcslib, conv_lib, minimum_corba, iortable, portableserver, messaging, svc_utils, acexml, imr_client {
+ sharedname = TAO_ImR_Locator
+ dynamicflags = LOCATOR_BUILD_DLL
+ after += ImR_Locator_IDL ImR_Activator_IDL
+ libs += TAO_ImR_Locator_IDL TAO_ImR_Activator_IDL
+ Source_Files {
+ Activator_Info.cpp
+ Adapter_Activator.cpp
+ Forwarder.cpp
+ ImR_Locator_i.cpp
+ AsyncStartupWaiter_i.cpp
+ INS_Locator.cpp
+ Locator_XMLHandler.cpp
+ Locator_Loader.cpp
+ Locator_Options.cpp
+ Iterator.cpp
+ Server_Info.cpp
+ Locator_Repository.cpp
+ }
+ header_files {
+ utils.h
+ locator_export.h
+ }
+ idl_files {
+ }
+}
+
+project(ImR_Locator_Service) : orbsvcsexe, install_bin, minimum_corba, iortable, messaging, acexml ,svc_utils, pi_server, imr_client {
+ exename = ImplRepo_Service
+ after += ImR_Locator ImR_Activator_IDL ImR_Locator_IDL
+ libs += TAO_ImR_Locator TAO_ImR_Activator_IDL TAO_ImR_Locator_IDL
+
+ // Static Debug builds on Windows will not link properly due
+ // to a linker bug. It complains that the ACEXML library duplicates
+ // a couple of template instantiations from the TAO_ImR_Locator library.
+ // The FORCE:MULTIPLE option works around that bug. Unfortunately,
+ // there is no way to narrow the options down to only static debug builds.
+ // Incremental linking has also been turned off since it is
+ // incompatible with this option, producing warnings at link time.
+ specific(em3, nmake, vc6, vc71) {
+ link_options += /FORCE:MULTIPLE /INCREMENTAL:NO
+ }
+
+ Source_Files {
+ ImR_Locator.cpp
+ Locator_NT_Service.cpp
+ }
+ idl_files {
+ }
+}
+
+
+project(ImR_Activator_Service) : orbsvcsexe, install_bin, acexml, minimum_corba, messaging, svc_utils, imr_client {
+ exename = ImR_Activator
+ after += ImR_Activator ImR_Activator_IDL ImR_Locator_IDL
+ libs += TAO_ImR_Activator TAO_ImR_Activator_IDL TAO_ImR_Locator_IDL
+ Source_Files {
+ ImR_Activator.cpp
+ Activator_NT_Service.cpp
+ }
+ idl_files {
+ }
+}
+
+
+project(tao_imr) : orbsvcsexe, install_bin, minimum_corba, portableserver, imr_client {
+ exename = tao_imr
+ install = $(ACE_ROOT)/bin
+ Source_Files {
+ tao_imr.cpp
+ tao_imr_i.cpp
+ }
+ idl_files {
+ }
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Iterator.cpp b/TAO/orbsvcs/ImplRepo_Service/Iterator.cpp
new file mode 100644
index 00000000000..1ed369991c2
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Iterator.cpp
@@ -0,0 +1,91 @@
+//=============================================================================
+/**
+ * @file Iterator.cpp
+ *
+ * $Id$
+ *
+ * @brief This file declares ImR's iterator.
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ */
+//=============================================================================
+
+#include "Iterator.h"
+
+ImR_Iterator::ImR_Iterator (CORBA::ULong n, Locator_Repository& repo, PortableServer::POA_ptr poa)
+ : repo_(repo)
+ , count_(n)
+ , poa_(poa)
+{
+}
+
+
+CORBA::Boolean
+ImR_Iterator::next_n (CORBA::ULong how_many,
+ ImplementationRepository::ServerInformationList_out server_list
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_NEW_THROW_EX (server_list,
+ ImplementationRepository::ServerInformationList(0), CORBA::NO_MEMORY());
+
+ Locator_Repository::SIMap::ENTRY* entry = 0;
+ Locator_Repository::SIMap::ITERATOR it (this->repo_.servers ());
+
+ // Number of servers that will go into the server_list.
+ CORBA::ULong n = this->repo_.servers().current_size();
+ if (n <= this->count_)
+ {
+ return 0; // We already finished.
+ }
+ else
+ {
+ n -= this->count_;
+ }
+
+ if (how_many > 0 && n > how_many)
+ {
+ n = how_many;
+ }
+
+ server_list->length (n);
+
+ CORBA::ULong i = 0;
+ for (; i < this->count_; ++i)
+ {
+ it.advance ();
+ }
+
+ for (i = 0; i < n; ++i)
+ {
+ it.next (entry);
+ it.advance ();
+ ACE_ASSERT(entry != 0);
+
+ Server_Info_Ptr info = entry->int_id_;
+
+ server_list[i].server = info->name.c_str ();
+ server_list[i].startup.command_line = info->cmdline.c_str ();
+ server_list[i].startup.environment = info->env_vars;
+ server_list[i].startup.working_directory = info->dir.c_str ();
+ server_list[i].startup.activation = info->activation_mode;
+ server_list[i].startup.activator = info->activator.c_str ();
+ server_list[i].startup.start_limit = info->start_limit;
+ server_list[i].partial_ior = info->partial_ior.c_str ();
+ }
+
+ this->count_ += n;
+
+ return 1;
+}
+
+
+void
+ImR_Iterator::destroy (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ PortableServer::ObjectId_var oid = poa_->servant_to_id (this ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ poa_->deactivate_object (oid.in() ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Iterator.h b/TAO/orbsvcs/ImplRepo_Service/Iterator.h
new file mode 100644
index 00000000000..d592146fbb7
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Iterator.h
@@ -0,0 +1,55 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+ * @file Iterator.h
+ *
+ * $Id$
+ *
+ * @brief This file declares ImR's iterator.
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef IMR_ITERATOR_H
+#define IMR_ITERATOR_H
+
+#include "Locator_Repository.h"
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/ImR_Client/ImplRepoS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class ImR_Iterator
+ *
+ * @brief The Iterator for servers in the ImR.
+ *
+ */
+class ImR_Iterator
+ : public POA_ImplementationRepository::ServerInformationIterator
+{
+public:
+ ImR_Iterator (CORBA::ULong n, Locator_Repository& repo, PortableServer::POA_ptr poa);
+
+ /// Returns the next list of up to <how_many> servers. If empty, will return
+ /// false.
+ virtual CORBA::Boolean next_n (
+ CORBA::ULong how_many,
+ ImplementationRepository::ServerInformationList_out server_list
+ ACE_ENV_ARG_DECL_WITH_DEFAULTS
+ )
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ virtual void destroy (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+private:
+ Locator_Repository& repo_;
+ CORBA::ULong count_;
+ PortableServer::POA_ptr poa_;
+};
+
+#endif /* IMR_ITERATOR_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Loader.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_Loader.cpp
new file mode 100644
index 00000000000..be8dd5e0e1f
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Loader.cpp
@@ -0,0 +1,105 @@
+// $Id$
+
+#include "Locator_Loader.h"
+#include "ace/Dynamic_Service.h"
+#include "ace/Task.h"
+
+class ImR_Locator_ORB_Runner : public ACE_Task_Base
+{
+public:
+ ImR_Locator_ORB_Runner (ImR_Locator_Loader& service)
+ : service_ (service)
+ {
+ }
+ virtual int svc ()
+ {
+ // Block until service_.fini () calls orb->destroy ()
+ this->service_.run ();
+ return 0;
+ }
+private:
+ ImR_Locator_Loader& service_;
+};
+
+ImR_Locator_Loader::ImR_Locator_Loader()
+{
+}
+
+int
+ImR_Locator_Loader::init (int argc, ACE_TCHAR *argv[])
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ int err = this->opts_.init (argc, argv);
+ if (err != 0)
+ return -1;
+
+ err = this->service_.init (this->opts_ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ if (err != 0)
+ return -1;
+
+ // Create a thread in which to run the service
+ ACE_ASSERT(this->runner_.get () == 0);
+ this->runner_.reset(new ImR_Locator_ORB_Runner (*this));
+ this->runner_->activate ();
+ }
+ ACE_CATCHANY
+ {
+ return -1;
+ }
+ ACE_ENDTRY;
+ return 0;
+}
+
+int
+ImR_Locator_Loader::fini (void)
+{
+ ACE_ASSERT(this->runner_.get () != 0);
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ int ret = this->service_.fini (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->runner_->wait ();
+ this->runner_.reset (0);
+ return ret;
+ }
+ ACE_CATCHANY
+ {
+ }
+ ACE_ENDTRY;
+ return -1;
+}
+
+CORBA::Object_ptr
+ImR_Locator_Loader::create_object (CORBA::ORB_ptr,
+ int,
+ ACE_TCHAR**
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ ACE_THROW_RETURN (CORBA::NO_IMPLEMENT(), CORBA::Object::_nil ());
+}
+
+int
+ImR_Locator_Loader::run(void)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ return this->service_.run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHALL
+ {
+ ACE_ERROR((LM_ERROR, "Exception in ImR_Locator_ORB_Runner ()\n"));
+ return -1;
+ }
+ ACE_ENDTRY;
+}
+
+
+ACE_FACTORY_DEFINE (Locator, ImR_Locator_Loader)
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Loader.h b/TAO/orbsvcs/ImplRepo_Service/Locator_Loader.h
new file mode 100644
index 00000000000..ca90c61c6fb
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Loader.h
@@ -0,0 +1,50 @@
+// -*- C++ -*-
+//
+// $Id$
+
+#ifndef TAO_IMR_LOCATOR_LOADER_H
+#define TAO_IMR_LOCATOR_LOADER_H
+
+#include "ImR_Locator_i.h"
+
+#include "tao/Object_Loader.h"
+
+#include "ace/Auto_Ptr.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class ImR_Locator_ORB_Runner;
+
+class Locator_Export ImR_Locator_Loader : public TAO_Object_Loader
+{
+public:
+ ImR_Locator_Loader();
+
+ virtual int init (int argc, ACE_TCHAR *argv[]);
+
+ virtual int fini (void);
+
+ virtual CORBA::Object_ptr create_object (CORBA::ORB_ptr orb,
+ int argc,
+ ACE_TCHAR *argv[]
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException));
+
+ // Unlike other service objects, we have our own orb.
+ int run(void);
+
+private:
+ ImR_Locator_i service_;
+ Options opts_;
+ ACE_Auto_Ptr<ImR_Locator_ORB_Runner> runner_;
+private:
+ // Disallow copying and assignment.
+ ImR_Locator_Loader (const ImR_Locator_Loader &);
+ ImR_Locator_Loader &operator = (const ImR_Locator_Loader &);
+};
+
+ACE_FACTORY_DECLARE (Locator, ImR_Locator_Loader)
+
+#endif
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_NT_Service.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_NT_Service.cpp
new file mode 100644
index 00000000000..e13a4f8080f
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_NT_Service.cpp
@@ -0,0 +1,116 @@
+//=============================================================================
+/**
+ * @file Locator_NT_Service.cpp
+ *
+ * $Id$
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ * @author Jeff Parsons <parsons@cs.wustl.edu>
+ * @author John Tucker <jtucker@infoglide.com>
+ * @author Mike Vitalo <mvitalo@infoglide.com>
+ */
+//=============================================================================
+
+#include "Locator_NT_Service.h"
+
+#if defined (ACE_WIN32)
+
+#include "ImR_Locator_i.h"
+#include "Locator_Options.h"
+
+#include "tao/ORB_Core.h"
+#include "tao/corba.h"
+#include "ace/Reactor.h"
+
+/**
+ * Handles the SERVICE_CONTROL_SHUTDOWN and SERVICE_CONTROL_STOP commands
+ * by shutting down the ORB. Otherwise ACE_NT_Service::handle_control
+ * handles the command.
+ */
+void
+Locator_NT_Service::handle_control (DWORD control_code)
+{
+ if (control_code == SERVICE_CONTROL_SHUTDOWN
+ || control_code == SERVICE_CONTROL_STOP)
+ {
+ report_status (SERVICE_STOP_PENDING);
+ TAO_ORB_Core_instance ()->reactor ()->end_reactor_event_loop ();
+ TAO_ORB_Core_instance ()->orb ()->shutdown (1);
+ }
+ else
+ {
+ ACE_NT_Service::handle_control (control_code);
+ }
+}
+
+
+/**
+ */
+int
+Locator_NT_Service::handle_exception (ACE_HANDLE)
+{
+ return 0;
+}
+
+
+/**
+ * We do almost the same thing as we do in run_standalone ()
+ */
+int
+Locator_NT_Service::svc (void)
+{
+ ImR_Locator_i server;
+ Options opts;
+
+ if (opts.init_from_registry () != 0)
+ {
+ report_status (SERVICE_STOPPED);
+ return -1;
+ }
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ int status = server.init (opts ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (status == -1)
+ {
+ report_status (SERVICE_STOPPED);
+ return -1;
+ }
+ else
+ {
+ report_status (SERVICE_RUNNING);
+ server.run (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ status = server.fini (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ report_status (SERVICE_STOPPED);
+
+ }
+ if (status != -1)
+ return 0;
+ }
+ ACE_CATCH (CORBA::SystemException, sysex)
+ {
+ ACE_PRINT_EXCEPTION (sysex, IMR_LOCATOR_DISPLAY_NAME);
+ }
+ ACE_CATCH (CORBA::UserException, userex)
+ {
+ ACE_PRINT_EXCEPTION (userex, IMR_LOCATOR_DISPLAY_NAME);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, IMR_LOCATOR_DISPLAY_NAME);
+ }
+ ACE_ENDTRY;
+
+ report_status (SERVICE_STOPPED);
+
+ return -1;
+}
+
+#endif /* ACE_WIN32 */
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_NT_Service.h b/TAO/orbsvcs/ImplRepo_Service/Locator_NT_Service.h
new file mode 100644
index 00000000000..c2199926f63
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_NT_Service.h
@@ -0,0 +1,62 @@
+/* -*- C++ -*- */
+//=============================================================================
+/**
+ * @file Locator_NT_Service.h
+ *
+ * $Id$
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ * @author Jeff Parsons <parsons@cs.wustl.edu>
+ * @author John Tucker <jtucker@infoglide.com>
+ * @author Mike Vitalo <mvitalo@infoglide.com>
+ */
+//=============================================================================
+
+#ifndef Locator_NT_Service_H
+#define Locator_NT_Service_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_WIN32)
+
+#include "ace/NT_Service.h"
+#include "ace/Singleton.h"
+#include "ace/Synch.h"
+#include "tao/orbconf.h"
+
+static const char * IMR_LOCATOR_SERVICE_NAME = "TAOImR";
+static const char * IMR_LOCATOR_DISPLAY_NAME = "TAO Implementation Repository";
+static const char * IMR_LOCATOR_DESCRIPTION = "Implementation Repository Locator service for TAO";
+
+/**
+ * @class Locator_NT_Service
+ *
+ * @brief Allows the Implementation Repository to act as a Windows NT Service.
+ */
+class Locator_NT_Service : public ACE_NT_Service
+{
+public:
+ typedef TAO_SYNCH_RECURSIVE_MUTEX MUTEX;
+
+ /// We override <handle_control> because it handles stop requests
+ /// privately.
+ virtual void handle_control (DWORD control_code);
+
+ /// We override <handle_exception> so a 'stop' control code can wake
+ /// the reactor off of its wait.
+ virtual int handle_exception (ACE_HANDLE h);
+
+ /// This is a virtual method inherited from ACE_NT_Service.
+ virtual int svc (void);
+
+private:
+ friend class ACE_Singleton<Locator_NT_Service, MUTEX>;
+};
+
+typedef ACE_Singleton<Locator_NT_Service, ACE_Mutex> SERVICE;
+
+#endif /* ACE_WIN32 */
+
+#endif /* Locator_NT_Service_H */
+
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp
new file mode 100644
index 00000000000..810649d2bb5
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp
@@ -0,0 +1,505 @@
+//=============================================================================
+/**
+ * @file Locator_Options.cpp
+ *
+ * $Id$
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ */
+//=============================================================================
+
+#include "Locator_Options.h"
+#include "ace/Arg_Shifter.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_strings.h"
+
+ACE_RCSID (ImplRepo_Service,
+ Options,
+ "$Id$")
+
+
+#if defined (ACE_WIN32)
+static const HKEY SERVICE_REG_ROOT = HKEY_LOCAL_MACHINE;
+// This string must agree with the one used in Locator_NT_Service.h
+static const ACE_TCHAR *SERVICE_REG_PATH =
+ ACE_TEXT ("SYSTEM\\CurrentControlSet\\Services\\TAOImR\\Parameters");
+#endif /* ACE_WIN32 */
+
+static const int DEFAULT_PING_INTERVAL = 10; // seconds
+static const int DEFAULT_START_TIMEOUT = 60; // seconds
+
+Options::Options ()
+: repo_mode_ (REPO_NONE)
+, erase_repo_ (false)
+, debug_ (1)
+, multicast_ (false)
+, service_ (false)
+, ping_interval_(DEFAULT_PING_INTERVAL)
+, startup_timeout_(DEFAULT_START_TIMEOUT)
+, readonly_ (false)
+, service_command_(SC_NONE)
+{
+}
+
+int
+Options::parse_args (int &argc, char *argv[])
+{
+ ACE_Arg_Shifter shifter (argc, argv);
+
+ while (shifter.is_anything_left ())
+ {
+ if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-c")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR, "Error: -c option needs a command\n"));
+ this->print_usage ();
+ return -1;
+ }
+
+ if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("install")) == 0)
+ {
+ this->service_command_ = SC_INSTALL;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("remove")) == 0)
+ {
+ this->service_command_ = SC_REMOVE;
+ }
+ else
+ {
+ ACE_ERROR((LM_ERROR, "Error: Unknown service command : %s\n", shifter.get_current()));
+ this->print_usage ();
+ return -1;
+ }
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-d")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR, "Error: -d option needs a debuglevel\n"));
+ this->print_usage ();
+ return -1;
+ }
+
+ this->debug_ = ACE_OS::atoi (shifter.get_current ());
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-m")) == 0)
+ {
+ this->multicast_ = true;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-o")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR, "Error: -o option needs a filename\n"));
+ this->print_usage ();
+ return -1;
+ }
+ this->ior_output_file_ = shifter.get_current();
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-s")) == 0)
+ {
+ // Run as a service
+ this->service_ = true;
+ }
+ else if ((ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-?")) == 0)
+ || (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-h")) == 0))
+ {
+ this->print_usage ();
+ return 1;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-l")) == 0)
+ {
+ this->readonly_ = true;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-p")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR, "Error: -p option needs a filename\n"));
+ this->print_usage ();
+ return -1;
+ }
+
+ this->persist_file_name_ = shifter.get_current ();
+ this->repo_mode_ = REPO_HEAP_FILE;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-r")) == 0)
+ {
+ this->repo_mode_ = REPO_REGISTRY;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-x")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR, "Error: -x option needs a filename\n"));
+ this->print_usage ();
+ return -1;
+ }
+
+ this->persist_file_name_ = shifter.get_current ();
+ this->repo_mode_ = REPO_XML_FILE;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-e")) == 0)
+ {
+ this->erase_repo_ = true;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-t")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR, "Error: -t option needs a value\n"));
+ this->print_usage ();
+ return -1;
+ }
+ this->startup_timeout_ =
+ ACE_Time_Value (ACE_OS::atoi (shifter.get_current ()));
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-v")) == 0)
+ {
+ shifter.consume_arg ();
+
+ if (!shifter.is_anything_left () || shifter.get_current ()[0] == '-')
+ {
+ ACE_ERROR ((LM_ERROR, "Error: -v option needs a value\n"));
+ this->print_usage ();
+ return -1;
+ }
+ this->ping_interval_ =
+ ACE_Time_Value (0, 1000 * ACE_OS::atoi (shifter.get_current ()));
+ }
+ else
+ {
+ shifter.ignore_arg ();
+ continue;
+ }
+
+ shifter.consume_arg ();
+ }
+
+ return 0;
+}
+
+int
+Options::init (int argc, char *argv[])
+{
+ // Make an initial pass through and grab the arguments that we recognize.
+ // This may also run the commands to install or remove the nt service.
+ int result = this->parse_args (argc, argv);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ for (int i = 0; i < argc; ++i)
+ {
+ this->cmdline_ += ACE_CString (argv[i]) + ACE_CString (" ");
+ }
+ return 0;
+}
+
+int
+Options::init_from_registry (void)
+{
+ this->load_registry_options ();
+ return 0;
+}
+
+
+void
+Options::print_usage (void) const
+{
+ ACE_ERROR ((LM_ERROR,
+ "Usage:\n"
+ "\n"
+ "ImR_Locator [-c cmd] [-d 0|1|2] [-m] [-o file]\n"
+ " [-r|-p file|-x file] [-s] [-t secs] [-v secs]\n"
+ " -c command Runs nt service commands ('install' or 'remove')\n"
+ " -d level Sets the debug level (default 1)\n"
+ " -l Lock the database\n"
+ " -m Turn on multicast\n"
+ " -o file Outputs the ImR's IOR to a file\n"
+ " -p file Use file for storing/loading settings\n"
+ " -x file Use XML file for storing/loading setting\n"
+ " -r Use the registry for storing/loading settings\n"
+ " -t secs Server startup timeout.(Default=60s)\n"
+ " -v msecs Server verification interval.(Default=10s)\n"
+ ));
+}
+
+int
+Options::save_registry_options ()
+{
+#if defined (ACE_WIN32)
+ HKEY key = 0;
+ // Create or open the parameters key
+ LONG err = ACE_TEXT_RegCreateKeyEx (SERVICE_REG_ROOT,
+ SERVICE_REG_PATH,
+ 0,
+ "", // class
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &key,
+ NULL
+ );
+ if (err != ERROR_SUCCESS)
+ {
+ return -1;
+ }
+ err = ACE_TEXT_RegSetValueEx (key, "ORBInitOptions", 0, REG_SZ,
+ (LPBYTE) this->cmdline_.c_str (), this->cmdline_.length () + 1);
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ err = ACE_TEXT_RegSetValueEx (key, "IORFile", 0, REG_SZ,
+ (LPBYTE) ior_output_file_.c_str (), ior_output_file_.length () + 1);
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ err = ACE_TEXT_RegSetValueEx (key, "DebugLevel", 0, REG_DWORD,
+ (LPBYTE) &debug_ , sizeof (debug_));
+ ACE_ASSERT(err == ERROR_SUCCESS);
+
+ err = ACE_TEXT_RegSetValueEx (key, "PersistFile", 0, REG_SZ,
+ (LPBYTE) this->persist_file_name_.c_str (), this->persist_file_name_.length () + 1);
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ DWORD tmp = this->ping_interval_.msec ();
+ err = ACE_TEXT_RegSetValueEx (key, "PingInterval", 0, REG_DWORD,
+ (LPBYTE) &tmp, sizeof (DWORD));
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ tmp = this->readonly_ ? 1 : 0;
+ err = ACE_TEXT_RegSetValueEx (key, "Lock", 0, REG_DWORD,
+ (LPBYTE) &tmp, sizeof (DWORD));
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ tmp = this->repo_mode_;
+ err = ACE_TEXT_RegSetValueEx (key, "PersistType", 0, REG_DWORD,
+ (LPBYTE) &tmp, sizeof (DWORD));
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ tmp = this->startup_timeout_.sec();
+ err = ACE_TEXT_RegSetValueEx (key, "Timeout", 0, REG_DWORD,
+ (LPBYTE) &tmp, sizeof (DWORD));
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ tmp = multicast_ ? 1 : 0;
+ err = ACE_TEXT_RegSetValueEx (key, "Multicast", 0, REG_DWORD,
+ (LPBYTE) &tmp, sizeof (DWORD));
+ ACE_ASSERT (err == ERROR_SUCCESS);
+
+ err = ::RegCloseKey (key);
+ ACE_ASSERT (err == ERROR_SUCCESS);
+#endif
+ return 0;
+}
+
+int
+Options::load_registry_options ()
+{
+#if defined (ACE_WIN32)
+ HKEY key = 0;
+ // Create or open the parameters key
+ LONG err = ACE_TEXT_RegOpenKeyEx (SERVICE_REG_ROOT,
+ SERVICE_REG_PATH,
+ 0,
+ KEY_READ,
+ &key
+ );
+ if (err != ERROR_SUCCESS)
+ {
+ // If there aren't any saved parameters, then that's ok.
+ return 0;
+ }
+ ACE_TCHAR tmpstr[4096];
+ DWORD sz = sizeof (tmpstr);
+ DWORD type = 0;
+ err = ACE_TEXT_RegQueryValueEx (key, "ORBInitOptions", 0, &type,
+ (LPBYTE) tmpstr, &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_SZ);
+ tmpstr[sz - 1] = '\0';
+ this->cmdline_ = tmpstr;
+ }
+
+ sz = sizeof(tmpstr);
+ err = ACE_TEXT_RegQueryValueEx (key, "IORFile", 0, &type,
+ (LPBYTE) tmpstr, &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_SZ);
+ tmpstr[sz - 1] = '\0';
+ this->ior_output_file_ = tmpstr;
+ }
+
+ sz = sizeof(debug_);
+ err = ACE_TEXT_RegQueryValueEx (key, "DebugLevel", 0, &type,
+ (LPBYTE) &this->debug_ , &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_DWORD);
+ }
+
+ DWORD tmp = 0;
+ sz = sizeof(tmp);
+ err = ACE_TEXT_RegQueryValueEx (key, "PingInterval", 0, &type,
+ (LPBYTE) &tmp, &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_DWORD);
+ ping_interval_.msec (tmp);
+ }
+
+ tmp = 0;
+ sz = sizeof(tmp);
+ err = ACE_TEXT_RegQueryValueEx (key, "Lock", 0, &type,
+ (LPBYTE) &tmp, &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_DWORD);
+ readonly_ = tmp != 0;
+ }
+
+ sz = sizeof(this->repo_mode_);
+ err = ACE_TEXT_RegQueryValueEx (key, "PersistType", 0, &type,
+ (LPBYTE) &this->repo_mode_, &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_DWORD);
+ }
+
+ tmp = 0;
+ sz = sizeof(tmp);
+ err = ACE_TEXT_RegQueryValueEx (key, "Timeout", 0, &type,
+ (LPBYTE) &tmp, &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_DWORD);
+ this->startup_timeout_.sec (tmp);
+ }
+
+ tmp = 0;
+ sz = sizeof(tmp);
+ err = ACE_TEXT_RegQueryValueEx (key, "Multicast", 0, &type,
+ (LPBYTE) &tmp, &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_DWORD);
+ this->multicast_ = tmp != 0;
+ }
+
+ sz = sizeof(tmpstr);
+ err = ACE_TEXT_RegQueryValueEx (key, "PersistFile", 0, &type,
+ (LPBYTE) tmpstr, &sz);
+ if (err == ERROR_SUCCESS)
+ {
+ ACE_ASSERT (type == REG_SZ);
+ tmpstr[sz - 1] = '\0';
+ this->persist_file_name_ = tmpstr;
+ }
+
+ err = ::RegCloseKey (key);
+ ACE_ASSERT (err == ERROR_SUCCESS);
+#endif
+ return 0;
+}
+
+bool
+Options::service (void) const
+{
+ return this->service_;
+}
+
+unsigned int
+Options::debug (void) const
+{
+ return this->debug_;
+}
+
+const ACE_CString&
+Options::ior_filename (void) const
+{
+ return this->ior_output_file_;
+}
+
+bool
+Options::multicast (void) const
+{
+ return this->multicast_;
+}
+
+Options::SERVICE_COMMAND
+Options::service_command(void) const
+{
+ return this->service_command_;
+}
+
+const char*
+Options::cmdline(void) const {
+ return this->cmdline_.c_str ();
+}
+
+const ACE_CString&
+Options::persist_file_name(void) const {
+ return this->persist_file_name_;
+}
+
+ACE_Time_Value
+Options::startup_timeout (void) const
+{
+ return this->startup_timeout_;
+}
+
+ACE_Time_Value
+Options::ping_interval (void) const
+{
+ return this->ping_interval_;
+}
+
+Options::RepoMode
+Options::repository_mode (void) const
+{
+ return this->repo_mode_;
+}
+
+bool
+Options::repository_erase (void) const
+{
+ return this->erase_repo_;
+}
+
+bool
+Options::readonly (void) const
+{
+ return this->readonly_;
+}
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Options.h b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.h
new file mode 100644
index 00000000000..4d7019bccf3
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.h
@@ -0,0 +1,147 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Locator_Options.h
+ *
+ * $Id$
+ *
+ * @brief Definition of the Options class for the Implementation Repository.
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef LOCATOR_OPTIONS_H
+#define LOCATOR_OPTIONS_H
+
+#include "locator_export.h"
+
+#include "ace/SString.h"
+#include "ace/Time_Value.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class Options
+ *
+ * @brief Maintains the global options.
+ *
+ * This is where the settings for TAO's Implementation Repository are stored.
+ */
+class Locator_Export Options
+{
+public:
+
+ enum SERVICE_COMMAND {
+ SC_NONE,
+ SC_INSTALL,
+ SC_REMOVE
+ };
+
+ enum RepoMode {
+ REPO_NONE,
+ REPO_XML_FILE,
+ REPO_HEAP_FILE,
+ REPO_REGISTRY
+ };
+
+ Options ();
+
+ /// Parse the command-line arguments and initialize the options.
+ int init (int argc, char *argv[]);
+ /// This version should only be used when run as an nt service.
+ int init_from_registry();
+
+ /// Service Mode
+ bool service (void) const;
+
+ /// Debug level for the Implementation Repository.
+ unsigned int debug (void) const;
+
+ /// Returns the file where the IOR should be stored.
+ const ACE_TString& ior_filename (void) const;
+
+ /// Will we listen for multicast location requests?
+ bool multicast (void) const;
+
+ /// The nt service command to run (install/remove)
+ SERVICE_COMMAND service_command(void) const;
+
+ int save_registry_options();
+
+ const char* cmdline(void) const;
+
+ /// File that contains the activator related information
+ /// that the persistent locator has to save.
+ const ACE_TString& persist_file_name(void) const;
+
+ /// Do we allow modifications to the servers?
+ bool readonly (void) const;
+
+ RepoMode repository_mode (void) const;
+
+ /// Do we wish to clear out the repository
+ bool repository_erase (void) const;
+
+ /// Returns the timeout value for program starting.
+ ACE_Time_Value startup_timeout (void) const;
+
+ /// If the server hasn't been verified for a while, then we'll
+ /// ping it. Note : No timers are currently used. We simply ping()
+ /// during indirect invocations, if this interval has elapsed.
+ ACE_Time_Value ping_interval (void) const;
+
+private:
+ /// Parses and pulls out arguments for the ImR
+ int parse_args (int &argc, char *argv[]);
+
+ /// Print the usage information.
+ void print_usage (void) const;
+
+ /// Run a service command.
+ int run_service_command (const ACE_TString& cmdline);
+
+ int load_registry_options();
+private:
+
+ // xml, heap, or registry
+ RepoMode repo_mode_;
+
+ // do we clear out the repository on load
+ bool erase_repo_;
+
+ /// Debug level.
+ unsigned int debug_;
+
+ /// File where the IOR of the server object is stored.
+ ACE_TString ior_output_file_;
+
+ /// Will we listen for multicast location requests?
+ bool multicast_;
+
+ /// Are we running as a service?
+ bool service_;
+
+ /// The amount of time between successive "are you started yet?" pings.
+ ACE_Time_Value ping_interval_;
+
+ /// The amount of time to wait for a server to response after starting it.
+ ACE_Time_Value startup_timeout_;
+
+ /// Can the server_repository be modified?
+ bool readonly_;
+
+ /// SC_NONE, SC_INSTALL, SC_REMOVE, ...
+ SERVICE_COMMAND service_command_;
+
+ /// Our extra command line arguments
+ ACE_CString cmdline_;
+
+ /// The persistent XML file name.
+ ACE_TString persist_file_name_;
+};
+
+#endif
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp
new file mode 100644
index 00000000000..ed44f22f9ad
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp
@@ -0,0 +1,574 @@
+#include "Locator_Repository.h"
+#include "Locator_XMLHandler.h"
+#include "utils.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_ctype.h"
+#include "ace/OS_NS_unistd.h"
+
+#include "ACEXML/parser/parser/Parser.h"
+#include "ACEXML/common/FileCharStream.h"
+#include "ACEXML/common/XML_Util.h"
+
+ACE_RCSID (ImplRepo_Service, Locator_Repository, "$Id$")
+
+static const char* STARTUP_COMMAND = "StartupCommand";
+static const char* WORKING_DIR = "WorkingDir";
+static const char* ENVIRONMENT = "Environment";
+static const char* ACTIVATION = "Activation";
+static const char* PARTIAL_IOR = "Location";
+static const char* IOR = "IOR";
+static const char* START_LIMIT = "StartLimit";
+static const char* ACTIVATOR = "Activator";
+static const char* SERVERS_ROOT_KEY = "Servers";
+static const char* ACTIVATORS_ROOT_KEY = "Activators";
+static const char* TOKEN = "Token";
+
+#if defined (ACE_WIN32)
+static const char* WIN32_REG_KEY = "Software\\TAO\\ImplementationRepository";
+#endif
+
+static ACE_CString lcase (const ACE_CString& s)
+{
+ ACE_CString ret(s);
+ for (size_t i = 0; i < ret.length (); ++i)
+ {
+ ret[i] = static_cast<char>(ACE_OS::ace_tolower (s[i]));
+ }
+ return ret;
+}
+
+static void loadActivatorsAsBinary (ACE_Configuration& config, Locator_Repository::AIMap& map)
+{
+ ACE_Configuration_Section_Key root;
+ int err = config.open_section (config.root_section (), ACTIVATORS_ROOT_KEY, 0, root);
+ if (err == 0)
+ {
+ int index = 0;
+ ACE_CString name;
+ while (config.enumerate_sections (root, index, name) == 0)
+ {
+ ACE_CString ior;
+ u_int token;
+
+ ACE_Configuration_Section_Key key;
+
+ // Can't fail, because we're enumerating
+ config.open_section (root, name.c_str(), 0, key);
+
+ config.get_string_value (key, IOR, ior);
+ config.get_integer_value (key, TOKEN, token);
+
+ Activator_Info_Ptr info (new Activator_Info (name, token, ior));
+ map.bind (lcase (name), info);
+ index++;
+ }
+ }
+}
+
+static void loadServersAsBinary(ACE_Configuration& config, Locator_Repository::SIMap& map)
+{
+ ACE_Configuration_Section_Key root;
+ int err = config.open_section (config.root_section (), SERVERS_ROOT_KEY, 0, root);
+ if (err == 0)
+ {
+ int index = 0;
+ ACE_CString name;
+ while (config.enumerate_sections (root, index, name) == 0)
+ {
+ ACE_CString cmdline, dir, envstr, partial_ior, ior, aname;
+ u_int amodeint = ImplementationRepository::MANUAL;
+ u_int start_limit;
+
+ ACE_Configuration_Section_Key key;
+
+ // Can't fail, because we're enumerating
+ config.open_section (root, name.c_str (), 0, key);
+
+ // Ignore any missing values. Server name is enough on its own.
+ config.get_string_value (key, ACTIVATOR, aname);
+ config.get_string_value (key, STARTUP_COMMAND, cmdline);
+ config.get_string_value (key, WORKING_DIR, dir);
+ config.get_string_value (key, ENVIRONMENT, envstr);
+ config.get_integer_value(key, ACTIVATION, amodeint);
+ config.get_string_value (key, PARTIAL_IOR, partial_ior);
+ config.get_string_value (key, IOR, ior);
+ config.get_integer_value(key, START_LIMIT, start_limit);
+
+ ImplementationRepository::ActivationMode amode =
+ static_cast <ImplementationRepository::ActivationMode> (amodeint);
+
+ ImplementationRepository::EnvironmentList env_vars =
+ ImR_Utils::parseEnvList (envstr);
+
+ Server_Info_Ptr info (new Server_Info(name, aname, cmdline,
+ env_vars, dir, amode, start_limit, partial_ior, ior));
+ map.bind (name, info);
+ index++;
+ }
+ }
+}
+
+static void loadAsBinary (ACE_Configuration& config, Locator_Repository& repo)
+{
+ loadServersAsBinary (config, repo.servers ());
+ loadActivatorsAsBinary (config, repo.activators ());
+}
+
+// Note : There is no saveAsBinary(), because the ACE_Configuration class
+// supports saving of individual entries.
+
+static void convertEnvList (const Locator_XMLHandler::EnvList& in, ImplementationRepository::EnvironmentList& out)
+{
+ CORBA::ULong sz = in.size ();
+ out.length (sz);
+ for (CORBA::ULong i = 0; i < sz; ++i)
+ {
+ out[i].name = in[i].name.c_str ();
+ out[i].value = in[i].value.c_str ();
+ }
+}
+
+class Server_Repo_XML_Callback : public Locator_XMLHandler::Callback
+{
+public:
+ Server_Repo_XML_Callback(Locator_Repository& repo)
+ : repo_ (repo)
+ {
+ }
+ virtual void next_server (const ACE_CString& name,
+ const ACE_CString& aname, const ACE_CString& cmdline,
+ const Locator_XMLHandler::EnvList& envlst, const ACE_CString& dir,
+ const ACE_CString& amodestr, int start_limit,
+ const ACE_CString& partial_ior, const ACE_CString& ior)
+ {
+ ImplementationRepository::ActivationMode amode =
+ ImR_Utils::parseActivationMode (amodestr);
+
+ ImplementationRepository::EnvironmentList env_vars;
+ convertEnvList (envlst, env_vars);
+
+ int limit = start_limit < 1 ? 1 : start_limit;
+
+ Server_Info_Ptr si (new Server_Info (name, aname, cmdline,
+ env_vars, dir, amode, limit, partial_ior, ior));
+
+ this->repo_.servers ().bind (name, si);
+ }
+ virtual void next_activator (const ACE_CString& aname,
+ long token,
+ const ACE_CString& ior)
+ {
+ Activator_Info_Ptr si (new Activator_Info (aname, token, ior));
+ this->repo_.activators ().bind (lcase (aname), si);
+ }
+private:
+ Locator_Repository& repo_;
+};
+
+static int loadAsXML (const ACE_CString& fname, Locator_Repository& repo)
+{
+ ACEXML_FileCharStream* fstm = new ACEXML_FileCharStream; // xml input source will take ownership
+
+ if (fstm->open (fname.c_str()) != 0)
+ {
+ // This is not a real error. The xml file may not exist yet.
+ delete fstm;
+ return 0;
+ }
+
+ Server_Repo_XML_Callback cb (repo);
+
+ Locator_XMLHandler handler (cb);
+
+ ACEXML_Parser parser;
+
+ // InputSource takes ownership
+ ACEXML_InputSource input (fstm);
+
+ parser.setContentHandler (&handler);
+ parser.setDTDHandler (&handler);
+ parser.setErrorHandler (&handler);
+ parser.setEntityResolver (&handler);
+
+ ACEXML_TRY_NEW_ENV
+ {
+ parser.parse (&input ACEXML_ENV_ARG_PARAMETER);
+ ACEXML_TRY_CHECK;
+ }
+ ACEXML_CATCH (ACEXML_Exception, ex)
+ {
+ ACE_ERROR ((LM_ERROR, "Error during load of ImR persistence xml file."));
+ ex.print ();
+ return -1;
+ }
+ ACEXML_ENDTRY;
+ return 0;
+}
+
+// Note : Would pass servers by const&, but ACE hash map const_iterator is broken.
+static void saveAsXML (const ACE_CString& fname, Locator_Repository& repo)
+{
+ FILE* fp = ACE_OS::fopen (fname.c_str (), "w");
+ if (fp == 0)
+ {
+ ACE_ERROR ((LM_ERROR, "Couldn't write to file %s\n", fname.c_str()));
+ return;
+ }
+ ACE_OS::fprintf (fp,"<?xml version=\"1.0\"?>\n");
+ ACE_OS::fprintf (fp,"<%s>\n", Locator_XMLHandler::ROOT_TAG);
+
+ // Save servers
+ Locator_Repository::SIMap::ENTRY* sientry = 0;
+ Locator_Repository::SIMap::ITERATOR siit (repo.servers ());
+ for (; siit.next (sientry); siit.advance() )
+ {
+ Server_Info_Ptr& info = sientry->int_id_;
+
+ ACE_CString name = ACEXML_escape_string (info->name);
+ ACE_CString activator = ACEXML_escape_string (info->activator);
+ ACE_CString cmdline = ACEXML_escape_string (info->cmdline);
+ ACE_CString wdir = ACEXML_escape_string (info->dir);
+ ACE_CString partial_ior = ACEXML_escape_string (info->partial_ior);
+ ACE_CString ior = ACEXML_escape_string (info->ior);
+
+ ACE_OS::fprintf (fp,"\t<%s", Locator_XMLHandler::SERVER_INFO_TAG);
+ ACE_OS::fprintf (fp," name=\"%s\"", name.c_str ());
+ ACE_OS::fprintf (fp," activator=\"%s\"", activator.c_str ());
+ ACE_OS::fprintf (fp," command_line=\"%s\"", cmdline.c_str ());
+ ACE_OS::fprintf (fp," working_dir=\"%s\"", wdir.c_str ());
+ ACE_CString amodestr = ImR_Utils::activationModeToString (info->activation_mode);
+ ACE_OS::fprintf (fp," activation_mode=\"%s\"", amodestr.c_str ());
+ ACE_OS::fprintf (fp," start_limit=\"%d\"", info->start_limit);
+ ACE_OS::fprintf (fp," partial_ior=\"%s\"", partial_ior.c_str ());
+ ACE_OS::fprintf (fp," ior=\"%s\"", ior.c_str ());
+ ACE_OS::fprintf (fp,">\n");
+
+ for (CORBA::ULong i = 0; i < info->env_vars.length (); ++i)
+ {
+ ACE_OS::fprintf (fp,"\t\t<%s", Locator_XMLHandler::ENVIRONMENT_TAG);
+ ACE_OS::fprintf (fp," name=\"%s\"", info->env_vars[i].name.in ());
+ ACE_CString val = ACEXML_escape_string (info->env_vars[i].value.in ());
+ ACE_OS::fprintf (fp," value=\"%s\"", val.c_str ());
+ ACE_OS::fprintf (fp,"/>\n");
+ }
+
+ ACE_OS::fprintf (fp,"\t</%s>\n", Locator_XMLHandler::SERVER_INFO_TAG);
+ }
+
+ // Save Activators
+ Locator_Repository::AIMap::ENTRY* aientry = 0;
+ Locator_Repository::AIMap::ITERATOR aiit (repo.activators ());
+ for (; aiit.next (aientry); aiit.advance ())
+ {
+ ACE_CString aname = aientry->ext_id_;
+ Activator_Info_Ptr& info = aientry->int_id_;
+ ACE_OS::fprintf (fp,"\t<%s", Locator_XMLHandler::ACTIVATOR_INFO_TAG);
+ ACE_OS::fprintf( fp," name=\"%s\"", aname.c_str ());
+ ACE_OS::fprintf (fp," token=\"%d\"", info->token);
+ ACE_OS::fprintf (fp," ior=\"%s\"", info->ior.c_str ());
+ ACE_OS::fprintf (fp,"/>\n");
+ }
+
+ ACE_OS::fprintf (fp,"</%s>\n", Locator_XMLHandler::ROOT_TAG);
+ ACE_OS::fclose (fp);
+}
+
+Locator_Repository::Locator_Repository ()
+: rmode_ (Options::REPO_NONE)
+, config_ (0)
+{
+}
+
+int
+Locator_Repository::init(const Options& opts)
+{
+ this->rmode_ = opts.repository_mode ();
+ this->fname_ = opts.persist_file_name ();
+
+ int err = 0;
+ switch (this->rmode_)
+ {
+ case Options::REPO_NONE:
+ {
+ break;
+ }
+ case Options::REPO_HEAP_FILE:
+ {
+ if (opts.repository_erase ())
+ {
+ ACE_OS::unlink ( this->fname_.c_str () );
+ }
+ ACE_Configuration_Heap* heap = new ACE_Configuration_Heap ();
+ this->config_.reset (heap);
+ err = heap->open (this->fname_.c_str ());
+ if (err == 0)
+ {
+ loadAsBinary (*this->config_, *this);
+ }
+ break;
+ }
+ case Options::REPO_REGISTRY:
+ {
+#if defined (ACE_WIN32)
+ if (opts.repository_erase ())
+ {
+ ACE_Configuration_Win32Registry config ( HKEY_LOCAL_MACHINE );
+ ACE_Configuration_Section_Key root;
+ config.open_section (config.root_section(), "Software\\TAO", 0, root);
+ config.remove_section (root, "ImplementationRepository", 1);
+ }
+ HKEY root = ACE_Configuration_Win32Registry::
+ resolve_key (HKEY_LOCAL_MACHINE, WIN32_REG_KEY);
+ this->config_.reset (new ACE_Configuration_Win32Registry( root));
+ loadAsBinary (*this->config_, *this);
+#else
+ ACE_ERROR ((LM_ERROR, "Registry persistence is only "
+ "supported on Windows\n"));
+ err = -1;
+#endif
+ break;
+ }
+ case Options::REPO_XML_FILE:
+ {
+ if (opts.repository_erase ())
+ {
+ ACE_OS::unlink ( this->fname_.c_str() );
+ }
+ err = loadAsXML (this->fname_, *this);
+ break;
+ }
+ default:
+ {
+ bool invalid_rmode_specified = false;
+ ACE_ASSERT (invalid_rmode_specified);
+ ACE_UNUSED_ARG (invalid_rmode_specified);
+ err = -1;
+ }
+ }
+ return err;
+}
+
+int
+Locator_Repository::add_server (const ACE_CString& name,
+ const ACE_CString& aname,
+ const ACE_CString& startup_command,
+ const ImplementationRepository::EnvironmentList& env_vars,
+ const ACE_CString& working_dir,
+ ImplementationRepository::ActivationMode activation,
+ int start_limit,
+ const ACE_CString& partial_ior,
+ const ACE_CString& ior,
+ ImplementationRepository::ServerObject_ptr svrobj)
+{
+ int limit = start_limit < 1 ? 1 : start_limit;
+ Server_Info_Ptr info(new Server_Info (name, aname, startup_command,
+ env_vars, working_dir, activation, limit, partial_ior, ior, svrobj));
+
+ int err = servers ().bind (name, info);
+ if (err != 0)
+ {
+ return err;
+ }
+ this->update_server (*info);
+ return 0;
+}
+
+int
+Locator_Repository::add_activator (const ACE_CString& name,
+ const CORBA::Long token,
+ const ACE_CString& ior,
+ ImplementationRepository::Activator_ptr act)
+{
+ Activator_Info_Ptr info (new Activator_Info (name, token, ior, act));
+
+ int err = activators ().bind (lcase (name), info);
+ if (err != 0)
+ {
+ return err;
+ }
+ this->update_activator (*info);
+ return 0;
+}
+
+int
+Locator_Repository::update_server (const Server_Info& info)
+{
+ if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
+ {
+ ACE_ASSERT (this->config_.get () != 0);
+
+ ACE_Configuration& cfg = *this->config_;
+
+ ACE_Configuration_Section_Key root;
+ ACE_Configuration_Section_Key key;
+ int err = cfg.open_section (cfg.root_section(), SERVERS_ROOT_KEY, 1, root);
+ if (err != 0)
+ {
+ ACE_ERROR ((LM_ERROR, "Unable to open config section:%s\n", SERVERS_ROOT_KEY));
+ return err;
+ }
+ err = cfg.open_section (root, info.name.c_str (), 1, key);
+ if (err != 0)
+ {
+ ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", info.name.c_str()));
+ return err;
+ }
+
+ ACE_CString envstr = ImR_Utils::envListToString(info.env_vars);
+
+ cfg.set_string_value (key, ACTIVATOR, info.activator.c_str ());
+ cfg.set_string_value (key, STARTUP_COMMAND, info.cmdline.c_str ());
+ cfg.set_string_value (key, WORKING_DIR, info.dir.c_str ());
+ cfg.set_string_value (key, ENVIRONMENT, envstr);
+ cfg.set_integer_value (key, ACTIVATION, info.activation_mode);
+ cfg.set_integer_value (key, START_LIMIT, info.start_limit);
+ cfg.set_string_value (key, PARTIAL_IOR, info.partial_ior.c_str ());
+ cfg.set_string_value (key, IOR, info.ior.c_str());
+ }
+ else if (rmode_ == Options::REPO_XML_FILE)
+ {
+ saveAsXML (this->fname_, *this);
+ }
+ return 0;
+}
+
+int
+Locator_Repository::update_activator (const Activator_Info& info)
+{
+ if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
+ {
+ ACE_ASSERT(this->config_.get () != 0);
+
+ ACE_Configuration& cfg = *this->config_;
+
+ ACE_Configuration_Section_Key root;
+ ACE_Configuration_Section_Key key;
+ int err = cfg.open_section (cfg.root_section(), ACTIVATORS_ROOT_KEY, 1, root);
+ if (err != 0)
+ {
+ ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", ACTIVATORS_ROOT_KEY));
+ return err;
+ }
+ err = cfg.open_section (root, info.name.c_str (), 1, key);
+ if (err != 0)
+ {
+ ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", info.name.c_str()));
+ return err;
+ }
+
+ cfg.set_integer_value (key, TOKEN, info.token);
+ cfg.set_string_value (key, IOR, info.ior.c_str ());
+ }
+ else if (rmode_ == Options::REPO_XML_FILE)
+ {
+ saveAsXML( this->fname_, *this);
+ }
+ return 0;
+}
+
+Server_Info_Ptr
+Locator_Repository::get_server (const ACE_CString& name)
+{
+ Server_Info_Ptr server (0);
+ servers ().find (name, server);
+ return server;
+}
+
+Activator_Info_Ptr
+Locator_Repository::get_activator (const ACE_CString& name)
+{
+ Activator_Info_Ptr activator (0);
+ activators ().find (lcase (name), activator);
+ return activator;
+}
+
+bool
+Locator_Repository::has_activator (const ACE_CString& name)
+{
+ Activator_Info_Ptr activator (0);
+ return activators().find (lcase (name), activator) == 0;
+}
+
+int
+Locator_Repository::remove_server (const ACE_CString& name)
+{
+ int ret = this->servers().unbind (name);
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
+ {
+ ACE_ASSERT (this->config_.get() != 0);
+ ACE_Configuration& cfg = *this->config_;
+ ACE_Configuration_Section_Key root;
+ int err = cfg.open_section (cfg.root_section (), SERVERS_ROOT_KEY, 0, root);
+ if (err != 0)
+ {
+ return 0; // Already gone.
+ }
+ ret = cfg.remove_section (root, name.c_str (), 1);
+ }
+ else if (rmode_ == Options::REPO_XML_FILE)
+ {
+ saveAsXML (this->fname_, *this);
+ }
+ return ret;
+}
+
+int
+Locator_Repository::remove_activator (const ACE_CString& name)
+{
+ int ret = activators().unbind (lcase(name));
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
+ {
+ ACE_ASSERT (this->config_.get () != 0);
+ ACE_Configuration& cfg = *this->config_;
+ ACE_Configuration_Section_Key root;
+ int err = cfg.open_section (cfg.root_section (), ACTIVATORS_ROOT_KEY, 0, root);
+ if (err != 0)
+ {
+ return 0; // Already gone.
+ }
+ ret = cfg.remove_section (root, name.c_str (), 1);
+ }
+ else if (rmode_ == Options::REPO_XML_FILE)
+ {
+ saveAsXML (this->fname_, *this);
+ }
+ return ret;
+}
+
+Locator_Repository::SIMap&
+Locator_Repository::servers (void)
+{
+ return server_infos_;
+}
+
+Locator_Repository::AIMap&
+Locator_Repository::activators (void)
+{
+ return activator_infos_;
+}
+
+const char*
+Locator_Repository::repo_mode ()
+{
+ switch (rmode_)
+ {
+ case Options::REPO_XML_FILE:
+ case Options::REPO_HEAP_FILE:
+ return fname_.c_str ();
+ case Options::REPO_REGISTRY:
+ return "Registry";
+ case Options::REPO_NONE:
+ return "Disabled";
+ }
+ return "Disabled";
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h
new file mode 100644
index 00000000000..2ef50b5753a
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h
@@ -0,0 +1,114 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+* @file Locator_Repository.h
+*
+* $Id$
+*
+* This class implements the Repository for the Implementation Repository.
+*
+* @author Darrell Brunsch <brunsch@cs.wustl.edu>
+* @author Priyanka Gontla <gontla_p@ociweb.com>
+*/
+//=============================================================================
+
+#ifndef REPOSITORY_H
+#define REPOSITORY_H
+
+#include "Server_Info.h"
+#include "Activator_Info.h"
+#include "Locator_Options.h"
+
+#include "ace/Hash_Map_Manager.h"
+#include "ace/Configuration.h"
+#include "ace/Auto_Ptr.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+* @class Locator_Repository
+*
+* @brief Database containing all ImR persistent information.
+*
+*/
+class Locator_Repository
+{
+public:
+ typedef ACE_Hash_Map_Manager_Ex<ACE_CString,
+ Server_Info_Ptr,
+ ACE_Hash<ACE_CString>,
+ ACE_Equal_To<ACE_CString>,
+ ACE_Null_Mutex> SIMap;
+
+ typedef ACE_Hash_Map_Manager_Ex<ACE_CString,
+ Activator_Info_Ptr,
+ ACE_Hash<ACE_CString>,
+ ACE_Equal_To<ACE_CString>,
+ ACE_Null_Mutex> AIMap;
+
+ Locator_Repository();
+
+ /// Initializes the Server Repository
+ int init (const Options& opts);
+
+ /// Add a new server to the Repository
+ int add_server (const ACE_CString& name,
+ const ACE_CString& aname,
+ const ACE_CString& startup_command,
+ const ImplementationRepository::EnvironmentList& environment_vars,
+ const ACE_CString& working_dir,
+ ImplementationRepository::ActivationMode activation,
+ int start_limit,
+ const ACE_CString& partial_ior = ACE_CString(""),
+ const ACE_CString& ior = ACE_CString(""),
+ ImplementationRepository::ServerObject_ptr svrobj = ImplementationRepository::ServerObject::_nil()
+ );
+ /// Add a new activator to the Repository
+ int add_activator (const ACE_CString& name,
+ const CORBA::Long token,
+ const ACE_CString& ior = ACE_CString(""),
+ ImplementationRepository::Activator_ptr act = ImplementationRepository::Activator::_nil()
+ );
+
+ /// Update the associated information.
+ int update_server (const Server_Info& info);
+ /// Update the associated information.
+ int update_activator (const Activator_Info& info);
+
+ /// Returns information related to startup.
+ Server_Info_Ptr get_server (const ACE_CString& name);
+ /// Returns information related to startup.
+ Activator_Info_Ptr get_activator (const ACE_CString& name);
+
+ bool has_activator(const ACE_CString& name);
+
+ /// Removes the server from the Repository.
+ int remove_server (const ACE_CString& name);
+ /// Removes the activator from the Repository.
+ int remove_activator (const ACE_CString& name);
+
+ /// Returns the internal hash map containing the server information.
+ SIMap& servers(void);
+ /// Returns the internal hash map containing the activator information.
+ AIMap& activators(void);
+
+ const char* repo_mode();
+
+private:
+ // Type mechanism to use for persistence.
+ Options::RepoMode rmode_;
+ // The in-memory list of the server information.
+ SIMap server_infos_;
+ // The in-memory list of the activator information.
+ AIMap activator_infos_;
+ // Several rmode_ values require this.
+ ACE_Auto_Ptr<ACE_Configuration> config_;
+ // XML requires the file name
+ ACE_CString fname_;
+};
+
+
+#endif /* REPOSITORY_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp
new file mode 100644
index 00000000000..a1ddcf0b3d9
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp
@@ -0,0 +1,97 @@
+// $Id$
+
+#include "Locator_XMLHandler.h"
+#include "ace/OS_NS_strings.h"
+
+ACE_RCSID (ImplRepo_Service,Locator_XMLHandler,"$Id$")
+
+const char* Locator_XMLHandler::ROOT_TAG = "ImplementationRepository";
+const char* Locator_XMLHandler::SERVER_INFO_TAG = "Servers";
+const char* Locator_XMLHandler::ACTIVATOR_INFO_TAG = "Activators";
+const char* Locator_XMLHandler::ENVIRONMENT_TAG = "EnvironmentVariables";
+
+Locator_XMLHandler::Locator_XMLHandler (Callback& cb)
+: callback_ (cb)
+{
+}
+
+void
+Locator_XMLHandler::startElement (const ACEXML_Char*,
+ const ACEXML_Char*,
+ const ACEXML_Char* qName,
+ ACEXML_Attributes* attrs ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+ ACE_ASSERT (qName != 0);
+ if (ACE_OS::strcasecmp (qName, SERVER_INFO_TAG) == 0)
+ {
+ // We'll use this as a key to determine if we've got a valid record
+ this->server_name_ = "";
+ this->env_vars_.clear();
+
+ if (attrs != 0 && attrs->getLength () == 8)
+ {
+ this->server_name_ = attrs->getValue ((size_t)0);
+ this->activator_name_ = attrs->getValue ((size_t)1);
+ this->command_line_ = attrs->getValue ((size_t)2);
+ this->working_dir_ = attrs->getValue ((size_t)3);
+ this->activation_ = attrs->getValue ((size_t)4);
+ this->env_vars_.clear ();
+ int limit = ACE_OS::atoi (attrs->getValue ((size_t)5));
+ this->start_limit_ = limit;
+ this->partial_ior_ = attrs->getValue ((size_t)6);
+ this->server_object_ior_ = attrs->getValue ((size_t)7);
+ }
+ }
+ else if (ACE_OS::strcasecmp (qName, ACTIVATOR_INFO_TAG) == 0)
+ {
+ if (attrs != 0 && attrs->getLength () == 3)
+ {
+ ACE_CString aname = attrs->getValue ((size_t)0);
+ ACE_CString token_str = attrs->getValue ((size_t)1);
+ long token = ACE_OS::atoi (token_str.c_str ());
+ ACE_CString ior = attrs->getValue ((size_t)2);
+ this->callback_.next_activator (aname, token, ior);
+ }
+ }
+ else if (ACE_OS::strcasecmp (qName, ENVIRONMENT_TAG) == 0)
+ {
+ if (attrs != 0 && attrs->getLength () == 2)
+ {
+ EnvVar ev;
+ ev.name = attrs->getValue ((size_t)0);
+ ev.value = attrs->getValue ((size_t)1);
+ this->env_vars_.push_back (ev);
+ }
+ }
+}
+
+void
+Locator_XMLHandler::endElement (const ACEXML_Char*,
+ const ACEXML_Char*,
+ const ACEXML_Char* qName ACEXML_ENV_ARG_DECL_NOT_USED)
+ ACE_THROW_SPEC ((ACEXML_SAXException))
+{
+ ACE_ASSERT(qName != 0);
+ if (ACE_OS::strcasecmp (qName, SERVER_INFO_TAG) == 0
+ && this->server_name_.length () > 0)
+ {
+ this->callback_.next_server (this->server_name_,
+ this->activator_name_, this->command_line_,
+ this->env_vars_, this->working_dir_, this->activation_,
+ this->start_limit_, this->partial_ior_, this->server_object_ior_);
+ }
+ // activator info is handled in the startElement
+}
+
+bool
+Locator_XMLHandler::EnvVar::operator== (const EnvVar& rhs) const
+{
+ return name == rhs.name && value == rhs.value;
+}
+bool
+Locator_XMLHandler::EnvVar::operator!= (const EnvVar& rhs) const
+{
+ return ! (rhs == *this);
+}
+
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h
new file mode 100644
index 00000000000..ff8691d0a78
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h
@@ -0,0 +1,88 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+ * @file Locator_XMLHandler.h
+ *
+ * $Id$
+ *
+ * @author Justin Michel <michel_j@ociweb.com>
+ */
+//=============================================================================
+
+#ifndef Locator_XMLHandler_H
+#define Locator_XMLHandler_H
+
+#include "ACEXML/common/DefaultHandler.h"
+
+#include "ace/Vector_T.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * Callback SAX XML Handler for parsing XML.
+ */
+class Locator_XMLHandler : public ACEXML_DefaultHandler
+{
+public:
+
+ // XML ELEMENT names
+ static const char* ROOT_TAG;
+ static const char* SERVER_INFO_TAG;
+ static const char* ENVIRONMENT_TAG;
+ static const char* ACTIVATOR_INFO_TAG;
+
+ struct EnvVar {
+ ACE_CString name;
+ ACE_CString value;
+ bool operator==(const EnvVar&) const; // To allow Vector explicit instantiation
+ bool operator!=(const EnvVar&) const; // To allow Vector explicit instantiation
+ };
+
+ typedef ACE_Vector<EnvVar> EnvList;
+
+ struct Callback {
+ virtual ~Callback() {}
+
+ virtual void next_server (const ACE_CString& server_name,
+ const ACE_CString& aname, const ACE_CString& startup_cmd,
+ const EnvList& env_vars, const ACE_CString& working_dir,
+ const ACE_CString& actmode, int start_limit,
+ const ACE_CString& partial_ior, const ACE_CString& ior) = 0;
+
+ virtual void next_activator (const ACE_CString& activator_name,
+ long token,
+ const ACE_CString& ior) = 0;
+ };
+
+ Locator_XMLHandler (Callback& cb);
+
+ virtual void startElement (const ACEXML_Char* namespaceURI,
+ const ACEXML_Char* localName,
+ const ACEXML_Char* qName,
+ ACEXML_Attributes* atts ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException));
+
+ virtual void endElement (const ACEXML_Char* namespaceURI,
+ const ACEXML_Char* localName,
+ const ACEXML_Char* qName ACEXML_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((ACEXML_SAXException));
+
+ private:
+
+ // callback on completion of an element
+ Callback& callback_;
+
+ ACE_CString server_name_;
+ ACE_CString activator_name_;
+ ACE_CString command_line_;
+ ACE_CString activation_;
+ ACE_CString working_dir_;
+ ACE_CString server_object_ior_;
+ ACE_CString partial_ior_;
+ int start_limit_;
+ EnvList env_vars_;
+};
+
+#endif /* Locator_XMLHandler_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/Makefile.am b/TAO/orbsvcs/ImplRepo_Service/Makefile.am
new file mode 100644
index 00000000000..166dacc12a0
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Makefile.am
@@ -0,0 +1,391 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ../bin/mwc.pl -type automake -noreldefs TAO.mwc
+
+ACE_BUILDDIR = $(top_builddir)/..
+ACE_ROOT = $(top_srcdir)/..
+TAO_BUILDDIR = $(top_builddir)
+TAO_IDL = ACE_ROOT=$(ACE_ROOT) TAO_ROOT=$(TAO_ROOT) $(TAO_BUILDDIR)/TAO_IDL/tao_idl
+TAO_IDL_DEP = $(TAO_BUILDDIR)/TAO_IDL/tao_idl
+TAO_IDLFLAGS = -Ge 1 -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -I$(TAO_ROOT) -I$(srcdir) -g $(ACE_BUILDDIR)/apps/gperf/src/gperf
+TAO_ROOT = $(top_srcdir)
+
+bin_PROGRAMS =
+
+## Makefile.ImR_Activator_IDL.am
+
+BUILT_SOURCES = \
+ ImR_ActivatorC.cpp \
+ ImR_ActivatorC.h \
+ ImR_ActivatorC.inl \
+ ImR_ActivatorS.cpp \
+ ImR_ActivatorS.h \
+ ImR_ActivatorS.inl \
+ ImR_ActivatorS_T.cpp \
+ ImR_ActivatorS_T.h \
+ ImR_ActivatorS_T.inl
+
+CLEANFILES = \
+ ImR_Activator-stamp \
+ ImR_ActivatorC.cpp \
+ ImR_ActivatorC.h \
+ ImR_ActivatorC.inl \
+ ImR_ActivatorS.cpp \
+ ImR_ActivatorS.h \
+ ImR_ActivatorS.inl \
+ ImR_ActivatorS_T.cpp \
+ ImR_ActivatorS_T.h \
+ ImR_ActivatorS_T.inl
+
+ImR_ActivatorC.cpp ImR_ActivatorC.h ImR_ActivatorC.inl ImR_ActivatorS.cpp ImR_ActivatorS.h ImR_ActivatorS.inl ImR_ActivatorS_T.cpp ImR_ActivatorS_T.h ImR_ActivatorS_T.inl: ImR_Activator-stamp
+
+ImR_Activator-stamp: $(srcdir)/ImR_Activator.idl $(TAO_IDL_DEP)
+ $(TAO_IDL) $(TAO_IDLFLAGS) -I$(TAO_ROOT)/orbsvcs -GT -Wb,versioning_begin=TAO_BEGIN_VERSIONED_NAMESPACE_DECL -Wb,versioning_end=TAO_END_VERSIONED_NAMESPACE_DECL -Wb,export_macro=ActivatorIDL_Export -Wb,export_include=activator_idl_export.h $(srcdir)/ImR_Activator.idl
+ @touch $@
+
+noinst_LTLIBRARIES = libTAO_ImR_Activator_IDL.la
+
+libTAO_ImR_Activator_IDL_la_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -DACTIVATOR_IDL_BUILD_DLL
+
+libTAO_ImR_Activator_IDL_la_SOURCES = \
+ ImR_ActivatorC.cpp \
+ ImR_ActivatorS.cpp
+
+noinst_HEADERS = \
+ ImR_Activator.idl \
+ ImR_ActivatorC.h \
+ ImR_ActivatorC.inl \
+ ImR_ActivatorS.h \
+ ImR_ActivatorS.inl \
+ ImR_ActivatorS_T.cpp \
+ ImR_ActivatorS_T.h \
+ ImR_ActivatorS_T.inl \
+ activator_idl_export.h
+
+## Makefile.ImR_Locator_IDL.am
+
+if BUILD_CORBA_MESSAGING
+
+BUILT_SOURCES += \
+ ImR_LocatorC.cpp \
+ ImR_LocatorC.h \
+ ImR_LocatorC.inl \
+ ImR_LocatorS.cpp \
+ ImR_LocatorS.h \
+ ImR_LocatorS.inl \
+ ImR_LocatorS_T.cpp \
+ ImR_LocatorS_T.h \
+ ImR_LocatorS_T.inl
+
+CLEANFILES += \
+ ImR_Locator-stamp \
+ ImR_LocatorC.cpp \
+ ImR_LocatorC.h \
+ ImR_LocatorC.inl \
+ ImR_LocatorS.cpp \
+ ImR_LocatorS.h \
+ ImR_LocatorS.inl \
+ ImR_LocatorS_T.cpp \
+ ImR_LocatorS_T.h \
+ ImR_LocatorS_T.inl
+
+ImR_LocatorC.cpp ImR_LocatorC.h ImR_LocatorC.inl ImR_LocatorS.cpp ImR_LocatorS.h ImR_LocatorS.inl ImR_LocatorS_T.cpp ImR_LocatorS_T.h ImR_LocatorS_T.inl: ImR_Locator-stamp
+
+ImR_Locator-stamp: $(srcdir)/ImR_Locator.idl $(TAO_IDL_DEP)
+ $(TAO_IDL) $(TAO_IDLFLAGS) -I$(TAO_ROOT)/orbsvcs -GT -Wb,versioning_begin=TAO_BEGIN_VERSIONED_NAMESPACE_DECL -Wb,versioning_end=TAO_END_VERSIONED_NAMESPACE_DECL -Wb,export_macro=LocatorIDL_Export -Wb,export_include=locator_idl_export.h $(srcdir)/ImR_Locator.idl
+ @touch $@
+
+BUILT_SOURCES += \
+ AsyncStartupWaiterC.cpp \
+ AsyncStartupWaiterC.h \
+ AsyncStartupWaiterC.inl \
+ AsyncStartupWaiterS.cpp \
+ AsyncStartupWaiterS.h \
+ AsyncStartupWaiterS.inl \
+ AsyncStartupWaiterS_T.cpp \
+ AsyncStartupWaiterS_T.h \
+ AsyncStartupWaiterS_T.inl
+
+CLEANFILES += \
+ AsyncStartupWaiter-stamp \
+ AsyncStartupWaiterC.cpp \
+ AsyncStartupWaiterC.h \
+ AsyncStartupWaiterC.inl \
+ AsyncStartupWaiterS.cpp \
+ AsyncStartupWaiterS.h \
+ AsyncStartupWaiterS.inl \
+ AsyncStartupWaiterS_T.cpp \
+ AsyncStartupWaiterS_T.h \
+ AsyncStartupWaiterS_T.inl
+
+AsyncStartupWaiterC.cpp AsyncStartupWaiterC.h AsyncStartupWaiterC.inl AsyncStartupWaiterS.cpp AsyncStartupWaiterS.h AsyncStartupWaiterS.inl AsyncStartupWaiterS_T.cpp AsyncStartupWaiterS_T.h AsyncStartupWaiterS_T.inl: AsyncStartupWaiter-stamp
+
+AsyncStartupWaiter-stamp: $(srcdir)/AsyncStartupWaiter.idl $(TAO_IDL_DEP)
+ $(TAO_IDL) $(TAO_IDLFLAGS) -I$(TAO_ROOT)/orbsvcs -GT -Wb,versioning_begin=TAO_BEGIN_VERSIONED_NAMESPACE_DECL -Wb,versioning_end=TAO_END_VERSIONED_NAMESPACE_DECL -Wb,export_macro=LocatorIDL_Export -Wb,export_include=locator_idl_export.h -GH $(srcdir)/AsyncStartupWaiter.idl
+ @touch $@
+
+noinst_LTLIBRARIES += libTAO_ImR_Locator_IDL.la
+
+libTAO_ImR_Locator_IDL_la_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -DLOCATOR_IDL_BUILD_DLL
+
+libTAO_ImR_Locator_IDL_la_SOURCES = \
+ AsyncStartupWaiterC.cpp \
+ AsyncStartupWaiterS.cpp \
+ ImR_LocatorC.cpp \
+ ImR_LocatorS.cpp
+
+noinst_HEADERS += \
+ AsyncStartupWaiter.idl \
+ AsyncStartupWaiterC.h \
+ AsyncStartupWaiterC.inl \
+ AsyncStartupWaiterS.h \
+ AsyncStartupWaiterS.inl \
+ AsyncStartupWaiterS_T.cpp \
+ AsyncStartupWaiterS_T.h \
+ AsyncStartupWaiterS_T.inl \
+ ImR_Locator.idl \
+ ImR_LocatorC.h \
+ ImR_LocatorC.inl \
+ ImR_LocatorS.h \
+ ImR_LocatorS.inl \
+ ImR_LocatorS_T.cpp \
+ ImR_LocatorS_T.h \
+ ImR_LocatorS_T.inl \
+ locator_idl_export.h
+
+endif BUILD_CORBA_MESSAGING
+
+## Makefile.ImR_Activator.am
+
+if BUILD_ACEXML
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+if !BUILD_MINIMUM_CORBA
+
+noinst_LTLIBRARIES += libTAO_ImR_Activator.la
+
+libTAO_ImR_Activator_la_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(ACE_ROOT)/ACEXML/common \
+ -DACTIVATOR_BUILD_DLL
+
+libTAO_ImR_Activator_la_SOURCES = \
+ Activator_Loader.cpp \
+ Activator_Options.cpp \
+ ImR_Activator_i.cpp
+
+noinst_HEADERS += \
+ Activator_Loader.h \
+ Activator_Options.h \
+ ImR_Activator_i.h \
+ activator_export.h
+
+endif !BUILD_MINIMUM_CORBA
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+endif BUILD_ACEXML
+
+## Makefile.ImR_Activator_Service.am
+
+if BUILD_ACEXML
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+if !BUILD_MINIMUM_CORBA
+
+bin_PROGRAMS += ImR_Activator
+
+ImR_Activator_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(ACE_ROOT)/ACEXML/common \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs
+
+ImR_Activator_SOURCES = \
+ Activator_NT_Service.cpp \
+ ImR_Activator.cpp \
+ Activator_NT_Service.h
+
+ImR_Activator_LDADD = \
+ libTAO_ImR_Activator.la \
+ libTAO_ImR_Activator_IDL.la \
+ libTAO_ImR_Locator_IDL.la \
+ $(TAO_BUILDDIR)/tao/libTAO_ImR_Client.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(ACE_BUILDDIR)/ACEXML/parser/parser/libACEXML_Parser.la \
+ $(ACE_BUILDDIR)/ACEXML/common/libACEXML.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_MINIMUM_CORBA
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+endif BUILD_ACEXML
+
+## Makefile.ImR_Locator.am
+
+if BUILD_ACEXML
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+if !BUILD_MINIMUM_CORBA
+
+noinst_LTLIBRARIES += libTAO_ImR_Locator.la
+
+libTAO_ImR_Locator_la_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs \
+ -I$(ACE_ROOT)/ACEXML/common \
+ -DLOCATOR_BUILD_DLL
+
+libTAO_ImR_Locator_la_SOURCES = \
+ Activator_Info.cpp \
+ Adapter_Activator.cpp \
+ AsyncStartupWaiter_i.cpp \
+ Forwarder.cpp \
+ INS_Locator.cpp \
+ ImR_Locator_i.cpp \
+ Iterator.cpp \
+ Locator_Loader.cpp \
+ Locator_Options.cpp \
+ Locator_Repository.cpp \
+ Locator_XMLHandler.cpp \
+ Server_Info.cpp
+
+noinst_HEADERS += \
+ Activator_Info.h \
+ Adapter_Activator.h \
+ AsyncStartupWaiter_i.h \
+ Forwarder.h \
+ INS_Locator.h \
+ ImR_Locator_i.h \
+ Iterator.h \
+ Locator_Loader.h \
+ Locator_Options.h \
+ Locator_Repository.h \
+ Locator_XMLHandler.h \
+ Server_Info.h \
+ locator_export.h \
+ utils.h
+
+endif !BUILD_MINIMUM_CORBA
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+endif BUILD_ACEXML
+
+## Makefile.ImR_Locator_Service.am
+
+if BUILD_ACEXML
+if BUILD_CORBA_MESSAGING
+if !BUILD_ACE_FOR_TAO
+if !BUILD_MINIMUM_CORBA
+
+bin_PROGRAMS += ImplRepo_Service
+
+ImplRepo_Service_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR) \
+ -I$(ACE_ROOT)/ACEXML/common \
+ -I$(TAO_ROOT)/orbsvcs \
+ -I$(TAO_BUILDDIR)/orbsvcs
+
+ImplRepo_Service_SOURCES = \
+ ImR_Locator.cpp \
+ Locator_NT_Service.cpp \
+ Locator_NT_Service.h
+
+ImplRepo_Service_LDADD = \
+ libTAO_ImR_Locator.la \
+ libTAO_ImR_Activator_IDL.la \
+ libTAO_ImR_Locator_IDL.la \
+ $(TAO_BUILDDIR)/tao/libTAO_ImR_Client.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI_Server.la \
+ $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \
+ $(ACE_BUILDDIR)/ACEXML/parser/parser/libACEXML_Parser.la \
+ $(ACE_BUILDDIR)/ACEXML/common/libACEXML.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PI.la \
+ $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \
+ $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_MINIMUM_CORBA
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_CORBA_MESSAGING
+endif BUILD_ACEXML
+
+## Makefile.tao_imr.am
+
+if !BUILD_MINIMUM_CORBA
+
+bin_PROGRAMS += tao_imr
+
+tao_imr_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR) \
+ -I$(TAO_ROOT) \
+ -I$(TAO_BUILDDIR)
+
+tao_imr_SOURCES = \
+ tao_imr.cpp \
+ tao_imr_i.cpp \
+ tao_imr_i.h
+
+tao_imr_LDADD = \
+ $(TAO_BUILDDIR)/tao/libTAO_ImR_Client.la \
+ $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \
+ $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \
+ $(TAO_BUILDDIR)/tao/libTAO.la \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_MINIMUM_CORBA
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/TAO/orbsvcs/ImplRepo_Service/README.txt b/TAO/orbsvcs/ImplRepo_Service/README.txt
new file mode 100644
index 00000000000..f6f8082f21b
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/README.txt
@@ -0,0 +1,590 @@
+/** -*- HTML-Helper -*- $Id$
+
+@mainpage Implementation Repository
+
+@section intro Introduction
+
+The purpose of the Implementation Repository (ImR) in TAO is for the automatic
+activation of a TAO server when a method is invoked but the server is not
+running. It does this by working with the server to keep track of when it is
+activated and stores information on how to reactivate it. Method
+invocations on the server will actually be sent to the Implementation
+Repository, which will then be able to start the server process if it is not
+already running and forward the invocation to the real server.
+
+@section resources Resources
+
+The ImR in TAO was first based on a paper on the subject by
+<a href="http://www.triodia.com/staff/michi-henning.html">Michi Henning</a>
+called <a href="http://www.triodia.com/staff/michi/cacm.pdf">Binding,
+Migration, and Scalability in CORBA</a>. Mr. Henning later went on to
+coauthor the book
+<a href="http://cseng.awl.com/bookdetail.qry?ISBN=0-201-37927-9&amp;ptype=0">
+Advanced CORBA Programming in C++</a> and included a chapter on the
+Implementation Repository. The description of the ImR in this chapter is used
+as the specification for TAO's ImR.
+
+@ref usersguide - Overall documentation on how to use the ImR in your programs
+
+@ref future - Future Work
+
+@ref ntservice - Running the ImR as a NT Service
+
+@ref imrandnaming - Using the Naming Service with the Implmentation Repository
+
+@ref movefromoldImR - Moving from IMR as in TAO 1.2.2 to the present version.
+
+@section authors Authors
+
+The guy who first worked on ImR and provided a base for the current
+ImR is Darrell Brunsch
+@<<a href="mailto:brunsch@cs.wustl.edu">brunsch@cs.wustl.edu</a>@>.
+The current version is developed by Priyanka Gontla
+@<<a href="mailto:gontla_p@ociweb.com">gontla_p@ociweb.com</a>@>.
+You can reach us by either email (which is better), or through the
+<a href="http://www.cs.wustl.edu/~schmidt/ACE-mail.html">ACE mailing list</a>
+@<<a href="mailto:ace-useres@cs.wustl.edu">ace-users@cs.wustl.edu</a>@>,
+or through the <a href="news:comp.soft-sys.ace">comp.soft-sys.ace</a>
+newsgroup. The newsgroup mirrors the mailing list, but not the other way.
+Also, if you use the mailing list, it is best if you join it before sending
+a question since responses are usually just replied back to the group.
+
+The NT Service part of the ImR was developed by Jeff Parsons @<<a
+href="mailto:parsons@cs.wustl.edu">parsons@cs.wustl.edu</a>@>. He can
+also be reached via the same channels.
+It was later extended and enhanced by Justin Michel <michel_j@ociweb.com>
+
+*/
+
+/**
+@page future Future Work
+
+As with any program, there is always a wishlist of things to do.
+
+@subsection ort Use Object Reference Template (ORT) Features
+
+ Use ORT so that the ImR-ified IORs doesnt have any information
+about the ImR_Activators. Right now, even though, the ImplRepo_Service is
+the one that is exposed to the client, the IOR will have a reference
+to the ImR_Activator. By using ORT features, we want the IOR to refer
+to the ImplRepo_Service rather than the underlying ImR_Activator. That way
+the ImR_Activator is totally blocked from the client using the ImR
+service.
+
+@subsection ort_design Design Considerations
+
+ For the above mentioned purposes, we can say that the ImplRepo_Service
+acts as the gateway which receives requests on behalf of the actual
+ImR_Activator.
+
+ The ImplRepo_Service will now need a new IDL method 'create_object'. The
+create_object method will take the interface_repository_id of the
+object that has to be gatewayed (ImR_Activator's) and the
+CORBA::Object_ptr of the gatewayed object. And, using these two will
+create an object which will point to the ImplRepo_Service and will also
+know that the ultimate receiver is the ImR_Activator.
+
+ So, this is how it works.
+
+ As before, we will first run the ImplRepo_Service. And, then run an
+ImR_Activator. We will use interceptors and in the post_init method,
+we will add an ior interceptor which will have the ImplRepo_Service
+object. By this, the IOR that is generated will actually point to the
+ImplRepo_Service rather than ImR_Activator. So, the IOR which is visible to
+the client will show that the IOR actually points to the ImplRepo_Service.
+
+ When a client sends a request to the ImplRepo_Service, the request
+will come to ImplRepo_Service which will send the request to the actual
+ImR_Activator.
+
+@subsection AMH Use AMH Features
+
+ Use the AMH features to improve the TAO IMR performance.
+
+@subsection logicalnames Logical Server names
+
+In the IDL interface, but not used on the server side or fully implemented in
+tao_ImR.
+
+@subsection shutdown Server Shutdown
+
+Only cooperative shutdown implemented right now. Since we keep track of the
+Process ID, then we could kill the server if it doesn't cooperate.
+
+@subsection optimization Client-side Optimizations
+
+Nothing yet.
+
+@subsection security Server Security
+
+Nothing really here. There is two main things I have in mind.
+
+First, the security service would be useful to restrict access to some
+of the Administration methods
+
+Second, without a security service we should provide some sort of flag to
+the ImR that disables the Administration methods. That way, the database
+can be set up with the servers in a controlled run of the ImR. Then the
+ImR could be run again reading in the database without Admin access.
+
+@subsection federations Federations
+
+Nothing yet.
+
+@subsection dllserver DLL servers
+
+Nothing yet.
+
+@subsection XML Database Support
+
+ As of now, the support is only to be able to have the information
+ about a registered server written to an XML file. Have to support
+retrieving information from the XML file to be able to do any actions
+on the registered servers.
+
+@subsection Remove ImR_Activator
+
+ We can now successfully register an ImR_Activator. But, we have to
+yet provide support to gracefully unregister the ImR_Activator from
+the ImplRepo_Service. The ImplRepo_Service then has to try to transfer the
+servers that were registered with this instance to other activators.
+*/
+
+/**
+@page usersguide Implementation Repository User's Guide
+
+In order for a server to make use of the Implementation Repository, it must
+communicate with the ImR to keep it up to date on such things as the server's
+running status. These functions now are contained within the POA, so when a
+Persistent POA is used on a server that has -ORBUseImR specified, it will
+communicate with an Implementation Repository, if one is available.
+
+@subsection description The New ImR
+
+ The new ImR is based on the ImR in TAO 1.2.2 with added
+features to help improve throughput and load balancing. The work to be
+performed by the Implementation Repository is distributed between two
+entities (ImplRepo_Service and ImR_Activator) to help achieve the goal of
+better throughput and load balance.
+
+@subsection locator ImplRepo_Service
+
+ The ImplRepo_Service acts as the main server which is visible to
+the application intending to use the ImR. It receives requests sent
+via tao_ImR and distributes the work to the registered ImR_Activators.
+It is stateless and does not maintain any information except about the
+ImR_Activators that are registered with it. Its job is to act as
+a mediator between the application and the actual ImR_Activator that does
+the real work. As of now, we only support one ImplRepo_Service to be running at
+any time. ImplRepo_Service can be reached through the usual methods of
+-ORBInitRef and -ORBDefaultInitRef and multicast.
+
+Commandline Arguments that can be passed to ImplRepo_Service
+
+-d debug information
+-m support multicast discovery.
+-o generate the ior.
+-x support persistence to the ImplRepo_Service. We use XML to support
+ persistence. Names of the activators registered with the locator,
+ their IORs, and the servers registered with each of the activators are
+ saved to the xml file. Use this option to pass the name of the file
+ where the data has to be saved.
+
+ And, ofcourse, the ORB Options.
+
+
+@subsection activator ImR_Activator
+
+ ImR_Activators, as you might have guessed, do the real work of
+activating servers or shutting them down and maintaining the information
+about servers related to them. Only one instance of an ImR_Activator
+can be run on one host. The ImR_Activator is not exposed at all to the
+application. Only the ImplRepo_Service needs to and it is the only one that
+can contact the ImR_Activator.
+
+ An instance of ImR_Activator first registers itself with the
+ImplRepo_Service so that it can begin to receive requests. When registering
+with the ImplRepo_Service, it passes the hostname where it is being run and
+its IOR to the ImplRepo_Service. And, the ImplRepo_Service reaches it using the
+same information.
+
+The Commandline paramters that are valid for ImR_Activator are
+
+-c: Run the Service command.
+-d:number Debug Information
+-l lock the database.
+-o Generate the IOR to a file (just in case some one wants
+ to read the IOR)
+-r Enable Win32 regsitry implementation.
+-s Run as a service.
+-t Set a timeout value.
+-h Prints the help.
+
+ When Persistence of an ImR_Activator is required, we will save
+the information about the server's that this ImR_Activator is related
+to in a file (being the easy form of a persistent database). The
+information about each server include its startup options, location,
+working directory which are needed to execute the requests that can
+passed by tao_imr with regards to the server.
+
+ There are two ways in which you can store data in the
+file. One way is to use ACE_Configuration_Heap to save all
+the information to the file. To do this, we have to pass the '-p' option.
+
+-p Pass the ImplRepo service a filename to use for the
+ backing store. Uses ACE_Configuration_Heap.
+
+ The second way is to save in XML-ized format.
+
+-x Pass the filename where the repository information should
+ be saved. Use XML format.
+
+
+@subsection work So how does the whole thing work?
+
+ The first thing to do is to have an ImplRepo_Service running. Once
+the ImplRepo_Service is running, we can instantiate one or more ImR_Activators
+as needed per the application. As mentioned already, the
+ImR_Activators, upon instantiation, register with the ImplRepo_Service to
+be able to receive requests.
+
+ When a new server has to be added or any change has to the
+done to an existing server, a request is to be sent to the ImplRepo_Service
+via the tao_imr utility. Startup commands, the working directory, the
+host where the server should be started up and such other information
+are passed to the ImplRepo_Service via the TAO_ImR commandline arguments.
+
+ If the host where the server should be started up is passed
+while adding a new server, the ImplRepo_Service chooses the ImR_Activator
+that is running on that host to be responsible for the server's
+activities. Otherwise, an ImR_Activator is chosen based on the Round
+robin algorithm. We plan to use better algorithms based on the
+existing load for the same purpose in future. Whatever way the
+ImR_Activator is chosen for a server, once an ImR_Activator is chosen,
+that ImR_Activator remains reponsible for the server throughout the
+server's lifetime.
+
+ After an ImR_Activator is chosen, the ImplRepo_Service passes the
+request to the chosen ImR_Activator. The ImR_Activator acts on the request
+and updates its database to reflect the new state of the server.
+
+@subsection run How is the ImR run?
+
+<ol>
+ <li>First run the <b>ImplRepo_Service</b>
+ <em>Example:<code> </code> </em><code> ImplRepo_Service -o locator.ior<br></code>
+ <li>Run the <b>Activator</b>
+ <em>Example:<code> </code> </em><code> ImR_Activator -ORBInitRef ImplRepoService=file://locator.ior<br></code>
+
+@subsection use How is the ImR used?
+
+The main steps for the lifetime of a server that uses the ImR are generally
+the following:
+
+<ol>
+ <li>Register name and startup commands with the ImR using <b>tao_ImR<br>
+ </b><em>Example:<code> </code> </em><code> tao_ImR -ORBInitRef
+ ImplRepoService=file://locator.ior add plane -c &quot;airplane_server -i
+ -ORBInitRef ImplRepoService=file://locator.ior&quot;<br></code>
+ <br>
+ Note that the name used to register the server is the name of the POA
+ which the objects are created in. So in this example, the airplane_server
+ creates a POA called &quot;plane&quot; and activates its servants under
+ it.<br>
+ <li>Start the server once to generate an ImR-ified IOR<br>
+ <li>Start clients and pass them the above IOR<br>
+ <li>Clients will use the IOR, which will automatically go through the ImR<br>
+ <li>The ImR will start the server if it is not already running<br>
+ <li>At any time when the server is not currently in use by a client, it can be
+ shut down using <strong>tao_ImR<br></strong><em>Example:</em><code> tao_ImR
+ -ORBInitRef ImplRepoService=file://locator.ior shutdown plane<br>
+ </code>
+ <li>After the server isn't needed anymore, it can be removed from the ImR database
+ using <strong>tao_ImR<br></strong><em>Example:<code> </em>tao_ImR -ORBInitRef
+ ImplRepoService=file://locator.ior remove plane</code>
+</ol>
+
+@subsection serverresponsibilities So what does the server need to do?
+
+As of TAO 1.0.9, the Implementation Repository support on the server-side has
+been integrated into the POA. Previously, the IR_Helper class needed to be
+used explicitly. Now only the &quot;-ORBUseImR 1&quot; command line
+argument needs to be used.
+
+There are a couple of restrictions on the server though. Only objects within
+a persistent POA will be supported by the ImR. Also the Implementation
+Repository will key its entries on POA name. What this means for the server
+is that each server must have unique persistent POA names.
+
+@subsection defaultinitref Use of -ORBDefaultInitRef with the ImR
+
+As mentioned in the INS documentation (in TAO/docs/INS.html), a base IOR
+can be passed to the ORB. Then when resolve_initial_reference is called,
+the ORB can append the service name to the base IOR to form a full IOR.
+
+When used with the ImR, this can be a powerful feature. If the ImR's endpoint
+is used as the base IOR, then the ImR can be used to provide many services via
+the resolve_initial_reference functionality.
+
+For example, let's say the ImR service is running on doriath on port 5555 and
+the Name Service is already registered with the ImR (in that the ImR knows how
+to start the Name Service).
+
+Now we should be able to run some client that uses the Name Service like this:
+
+<code>client -ORBDefaultInitRef corbaloc:iiop:doriath:5555/</code>
+
+When the client calls resolve_initial_reference("NameService"), the ORB will
+resolve that to "corbaloc:iiop:doriath:5555/NameService". The ImR
+recognizes this IOR as a pointer to the NameService, and will then
+start it up if necessary. Finally, it will forward the client to the
+Name Service.
+
+Services used in this way have two requirements:
+
+- The server must be registered as the request_initial_reference name. For
+ example, the Name Service is registered as the "NameService", and thus also
+ contains a POA with the name "NameService".
+- The server must also be able to handle the INS name
+ "corbaloc:iiop:machine:port/poa_name", where the poa_name is the
+ same name as above.
+
+@subsection activationmodes What are activation modes
+
+Each server can have one of three different types of activation modes:
+
+<ul>
+ <li>NORMAL is the default. The server can be started via tao_ImR,
+ the command line, and with client requests.
+ <li>MANUAL specifies that the server shouldn't be activated with a
+ client request but can be activated through tao_ImR or via the
+ command line.
+ <li>PER_CLIENT specifies that each request to the ImplRepo will
+ result in a new server process started up. Because clients
+ cache the forwarded reference, there is one server per client
+ (more or less). There are some exceptions, such as if the
+ original IOR is used in different threads (each thread would get
+ a different server). <b>Note:</b> The Implementation Repository
+ doesn't store any information about the started servers in this
+ mode, so it cannot be used to shut down the servers. So the
+ servers must have an alternative way of shutting down.
+ <li>AUTO_START specifies that a server should be activated when the
+ Implementation Repository is started. tao_ImR also has an
+ autostart command to activate all servers marked AUTO_START.
+</ul>
+
+@subsection taoImRior Using the tao_ImR ior command
+
+First, some background.
+
+For the longest time, there was no way with TAO's Implementation Repository
+to register a server and then start using the client immediately. The server
+had to be started once just for the purpose of creating an IOR for the client
+to use. The problem was that it was very difficult to create an IOR without
+running the server.
+
+It would be nice to be able to generate a valid IOR without requiring the
+program to be run. A valid IOR in this case requires two major things. First
+it requires the endpoint of the ImR. This is relatively easy to get, since it
+is encoded in the ImR's IOR. Second it also requires an object key. At the
+least, this involves both the POA hierarchy and the object name.
+
+So if we knew the POA and object names, then we should be able to create an
+IOR for the server. One possibility would be to have tao_ImR ask for both the
+POA and the object, and then create the POA hierarchy to generate an IOR.
+Doing the generation is this manner (letting the POA create the reference)
+shields us from changes in the IOR generation schemes. Since we are using
+the same code that the server would use, our IORs would be up to date.
+
+It ends up there is an easier way to do this. The Interoperable Naming
+Service is intended to be used in situations where an IOR could be created by
+hand. Using the same information as above, it is not difficult to take the
+endpoint information from the ImR and attach the POA name. For example,
+let's say that we are running the ImR on ringil.ece.uci.edu at port 5000.
+The endpoint would be
+&quot;corbaloc:iiop:1.2@ringil.ece.uci.edu:5000&quot;. If we are
+creating an IOR for the nestea server, we'd just need to attach
+&quot;/nestea_server&quot; to the end of the endpoint. Now we have an
+IOR.
+
+So what does this mean for the server?
+
+The main issue here is that the server must be changed to support the
+simplified name. This can be done by using the IORTable like this:
+
+<CODE>
+ CORBA::Object_var table_object =
+ this->orb_->resolve_initial_references ("IORTable",
+ ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+
+ IORTable::Table_var adapter =
+ IORTable::Table::_narrow (table_object.in (), ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ if (CORBA::is_nil (adapter.in ()))
+ {
+ ACE_ERROR ((LM_ERROR, "Nil IORTable\n"));
+ }
+ else
+ {
+ adapter->bind (poa_name, server_str.in (), ACE_TRY_ENV);
+ ACE_TRY_CHECK;
+ }
+</CODE>
+
+These lines, as taken from the nestea_server example, just uses the same
+poa_name as registered with the ImR and associates it with the server_obj
+object in the IOR table. Because the ImR will be able to handle the
+simplified name (if it uses the POA name scheme) then this IOR will work.
+
+Just one more thing, each object that needs an IOR needs to be registered
+with the IOR table. But this raises the problem of uniqueness; they all
+can't have the same name. The ImR will actually only look at the name part
+of the simplified IOR up to the first &quot;/&quot;. So both
+&quot;corbaloc:iiop:1.2@ringil:5000/nestea_server/foo&quot; and
+&quot;corbaloc:iiop:1.2@ringil:5000/nestea_server/bar&quot; will be treated by
+the ImR as objects in the &quot;nestea_server&quot; server.
+
+@subsection persistence Persistent Implementation Repository
+
+Tao's Implementation Repository can be made persistent by doing two things:
+
+<ul>
+<li>
+Always start up the Implementation Repository on the same port. This ensures that
+the Implementation Repository will not have to re-ImR-ify the IORs of every server
+registered to it each time it starts up. The way to accomplish this is to add<br>
+-ORBEndpoint iiop://(hostname):(portnumber)<br>
+
+ to the ImR_Activator's startup command line. The host
+name can be obtained portably in C++ code with the lines<br>
+
+ ACE_INET_addr ad;<br>
+ char *hostname = ad.get_host_name ();<br>
+
+or in a Perl script by adding<br>
+
+ use Sys::Hostname;<br>
+ $hostname = hostname();<br>
+
+There are even specific port numbers, assigned to the OMG by the IANA,
+which can be used for this purpose. They are 683 (for IIOP) and 684
+(for IIOP over SSL). For more information about this, see
+<a href="http://www.iana.org/">http://www.iana.org/</a>
+and <a href="http://www.isi.edu/in-notes/iana/assignments/port-numbers">
+http://www.isi.edu/in-notes/iana/assignments/port-numbers</a>.<br><br>
+<li>
+Pass the ImR a filename to use for the backing store, specified by the
+command line option<br>
+
+-p (filename)<br>
+
+This option must be used the first and every subsequent time the
+persistent ImR is started up.
+
+</ul>
+*/
+
+/**
+@page ntservice Running as an NT service
+
+The ImplRepo_Service.exe can now also function as a Windows NT
+Service. The -c option can be used to install and remove the service
+(this requires Administrator access on the machine).
+
+@note When using the ImplRepo_Service as a service, it must have all
+of its required ACE/TAO DLL's in the path or in the same directory.
+For example, the run_test.pl copies ImplRepo_Service.exe to the
+ACE_wrappers@\bin directory before using "-c install".
+Alternatively, You can set the usual ACE_ROOT, TAO_ROOT, and PATH environment
+variables on a system wide basis.
+
+The service can be then started either from the Windows NT "Services"
+Admin Tool or via the "net" program on the command line:
+
+<CODE>net start "TAO Implementation Repository Locator"</CODE>
+<CODE>net start "TAO Implementation Repository Activator"</CODE>
+
+The Implementation Repository supports start and stop but not pause.
+
+When the Activator is installed using ImR_Activator -c install, it is added
+with a dependency on a locator service. If you don't wish to also install
+the locator on the same machine, then you must use the -c install_no_imr
+option instead.
+
+@subsection serviceopts Service Options
+
+Any options that are specified along with -c install, will be saved in
+the registry under
+HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TAOIMRActivator\Parameters and
+HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TAOIMRLocator\Parameters.
+For example:
+ImR_Activator -c install -d 3 -l -m -o activator.ior -x persist.xml -t 30 -orbendpoint iiop://:9988 -orbdebuglevel 1
+
+The order of arguments makes no difference, but you must run
+-c remove and then -c install if you want to change the parameters.
+
+You can also manually change these using the typical regedit utility.
+
+*/
+
+/**
+@page imrandnaming Naming Service
+
+@subsection lowdown The Short Answer
+
+Register the Naming Service with an Implementation Repository using the
+POA name "NameService". So for example:
+
+<CODE>tao_imr add NameService -c "Naming_Service -ORBUseIMR 1"</CODE>
+
+And then an IOR can be created by:
+
+<CODE>tao_imr ior NameService</CODE>
+
+The above commands depend on multicast (since the commands are shorter and
+easier put in documents). You might need to add "-ORBInitRef
+ImplRepoService=..." for a more robust solution.
+
+@subsection details Various Details
+
+The Naming Service in TAO contains one persistant POA named "NameService".
+If -ORBUseIMR 1 is passed to it, it will communicate with the ImR as any
+other persistent POA does. Also, the Naming Service recognizes the INS
+object key "NameService". This allows you to use the "tao_imr ior"
+command to create corbaloc IORs.
+
+NameService was chosen because resolve_initial_references () uses that
+name. And that allows us to do interesting things with ORBDefaultInitRef
+(as shown in the @ref defaultinitref section).
+
+*/
+
+/**
+@page movefromoldImR Transition from IMR in TAO 1.2.2
+
+
+While the previous version of ImR has a single focal point (ImplRepo_Service)
+for performing all the jobs including receiving various requests,
+maintaining the information about all the servers registered with it
+and actually activating the servers as needed, in the new IMR, we
+distribute the work load between two entities, ImplRepo_Service and
+ImR_Activator, to help achieve the goal of better throughput and load
+balance.
+
+<b>.</b> The added step that you would have to now do is run the
+ImR_Activator. You can just run one instance of it to get the same
+behaviour as you were getting before.
+
+If you run the ImplRepo_Service in multicast mode, the
+ImR_Activator will be able to get access to it via
+multicast. Otherwise, you would have to use one of the reference
+initializing methods to give the ImR_Activator access to the
+ImplRepo_Service.
+
+<b>.</b> As I mentioned before, the previous commandline parameters
+that can be passed to ImplRepoService for the repository purposes will
+now be passed to the ImR_Activator since that is the one that is
+dealing with the database.
+
+*/
diff --git a/TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp b/TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp
new file mode 100644
index 00000000000..91f8d7fa1be
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp
@@ -0,0 +1,66 @@
+// $Id$
+#include "Server_Info.h"
+
+Server_Info::Server_Info
+(
+ const ACE_CString& server_name,
+ const ACE_CString& aname,
+ const ACE_CString& cmdline,
+ const ImplementationRepository::EnvironmentList& env,
+ const ACE_CString& working_dir,
+ ImplementationRepository::ActivationMode amode,
+ int limit,
+ const ACE_CString& partial_ior,
+ const ACE_CString& server_ior,
+ ImplementationRepository::ServerObject_ptr svrobj
+ )
+ : name (server_name)
+ , activator (aname)
+ , cmdline( cmdline)
+ , env_vars (env)
+ , dir (working_dir)
+ , activation_mode (amode)
+ , start_limit (limit)
+ , partial_ior (partial_ior)
+ , ior (server_ior)
+ , server(ImplementationRepository::ServerObject::_duplicate (svrobj))
+ , start_count (0)
+ , waiting_clients (0)
+ , starting (false)
+{
+}
+
+ImplementationRepository::ServerInformation*
+Server_Info::createImRServerInfo (ACE_ENV_SINGLE_ARG_DECL)
+{
+ ImplementationRepository::ServerInformation* info;
+ ACE_NEW_THROW_EX (info, ImplementationRepository::ServerInformation, CORBA::NO_MEMORY ());
+
+ info->server = name.c_str ();
+ info->startup.command_line = cmdline.c_str ();
+ info->startup.environment = env_vars;
+ info->startup.working_directory = dir.c_str ();
+ info->startup.activation = activation_mode;
+ info->startup.activator = activator.c_str ();
+ if (start_count >= start_limit)
+ {
+ info->startup.start_limit = -start_limit;
+ }
+ else
+ {
+ info->startup.start_limit = start_limit;
+ }
+ info->partial_ior = partial_ior.c_str();
+
+ return info;
+}
+
+void
+Server_Info::reset (void)
+{
+ ior = "";
+ partial_ior = "";
+ last_ping = ACE_Time_Value::zero;
+ server = ImplementationRepository::ServerObject::_nil ();
+ // start_count = 0; Note : We can't do this, because it would be reset during startup.
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Server_Info.h b/TAO/orbsvcs/ImplRepo_Service/Server_Info.h
new file mode 100644
index 00000000000..e6c3a910f3b
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Server_Info.h
@@ -0,0 +1,77 @@
+//=============================================================================
+/**
+ * @file Server_Info.h
+ *
+ * $Id$
+ *
+ * This class implements the Server_Info for the Implementation Repository.
+ *
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ * @author Priyanka Gontla <gontla_p@ociweb.com>
+ */
+#ifndef SERVER_INFO_H
+#define SERVER_INFO_H
+
+#include "ace/Bound_Ptr.h"
+
+#include "tao/ImR_Client/ImplRepoC.h"
+
+#include "ace/SString.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+* @brief Information about IMR registered servers.
+*/
+struct Server_Info
+{
+ Server_Info (const ACE_CString& server_name,
+ const ACE_CString& aname,
+ const ACE_CString& cmdline,
+ const ImplementationRepository::EnvironmentList& env,
+ const ACE_CString& working_dir,
+ ImplementationRepository::ActivationMode amode,
+ int start_limit,
+ const ACE_CString& partial_ior = ACE_CString(""),
+ const ACE_CString& server_ior = ACE_CString(""),
+ ImplementationRepository::ServerObject_ptr svrobj = ImplementationRepository::ServerObject::_nil()
+ );
+
+ /// Convert to the corba type
+ ImplementationRepository::ServerInformation* createImRServerInfo(ACE_ENV_SINGLE_ARG_DECL);
+
+ void reset();
+
+ /// The name of the server.
+ ACE_CString name;
+ /// The name of the activator in which this server runs
+ ACE_CString activator;
+ /// The command line startup command (program and arguments).
+ ACE_CString cmdline;
+ /// Environment Variables.
+ ImplementationRepository::EnvironmentList env_vars;
+ /// The working directory.
+ ACE_CString dir;
+ /// The type of activation this supports.
+ ImplementationRepository::ActivationMode activation_mode;
+ /// Limit of retries to start the server
+ int start_limit;
+ /// Current endpoint used by the server.
+ ACE_CString partial_ior;
+ /// IOR of the server object in the server.
+ ACE_CString ior;
+ /// The timestamp of the last time we verified the server is alive
+ ACE_Time_Value last_ping;
+ /// The cached server object
+ ImplementationRepository::ServerObject_var server;
+ int start_count;
+ int waiting_clients;
+ bool starting;
+};
+
+typedef ACE_Strong_Bound_Ptr<Server_Info, ACE_Null_Mutex> Server_Info_Ptr;
+
+#endif /* SERVER_INFO_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/activator_export.h b/TAO/orbsvcs/ImplRepo_Service/activator_export.h
new file mode 100644
index 00000000000..fcd22f8ccde
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/activator_export.h
@@ -0,0 +1,54 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s Activator
+// ------------------------------
+#ifndef ACTIVATOR_EXPORT_H
+#define ACTIVATOR_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (ACTIVATOR_HAS_DLL)
+# define ACTIVATOR_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && ACTIVATOR_HAS_DLL */
+
+#if !defined (ACTIVATOR_HAS_DLL)
+# define ACTIVATOR_HAS_DLL 1
+#endif /* ! ACTIVATOR_HAS_DLL */
+
+#if defined (ACTIVATOR_HAS_DLL) && (ACTIVATOR_HAS_DLL == 1)
+# if defined (ACTIVATOR_BUILD_DLL)
+# define Activator_Export ACE_Proper_Export_Flag
+# define ACTIVATOR_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define ACTIVATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* ACTIVATOR_BUILD_DLL */
+# define Activator_Export ACE_Proper_Import_Flag
+# define ACTIVATOR_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define ACTIVATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* ACTIVATOR_BUILD_DLL */
+#else /* ACTIVATOR_HAS_DLL == 1 */
+# define Activator_Export
+# define ACTIVATOR_SINGLETON_DECLARATION(T)
+# define ACTIVATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* ACTIVATOR_HAS_DLL == 1 */
+
+// Set ACTIVATOR_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (ACTIVATOR_NTRACE)
+# if (ACE_NTRACE == 1)
+# define ACTIVATOR_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define ACTIVATOR_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !ACTIVATOR_NTRACE */
+
+#if (ACTIVATOR_NTRACE == 1)
+# define ACTIVATOR_TRACE(X)
+#else /* (ACTIVATOR_NTRACE == 1) */
+# define ACTIVATOR_TRACE(X) ACE_TRACE_IMPL(X)
+#endif /* (ACTIVATOR_NTRACE == 1) */
+
+#endif /* ACTIVATOR_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/orbsvcs/ImplRepo_Service/activator_idl_export.h b/TAO/orbsvcs/ImplRepo_Service/activator_idl_export.h
new file mode 100644
index 00000000000..5ae5cbc5e22
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/activator_idl_export.h
@@ -0,0 +1,54 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s Activator
+// ------------------------------
+#ifndef ACTIVATOR_IDL_EXPORT_H
+#define ACTIVATOR_IDL_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (ACTIVATOR_IDL_HAS_DLL)
+# define ACTIVATOR_IDL_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && ACTIVATOR_IDL_HAS_DLL */
+
+#if !defined (ACTIVATOR_IDL_HAS_DLL)
+# define ACTIVATOR_IDL_HAS_DLL 1
+#endif /* ! ACTIVATOR_IDL_HAS_DLL */
+
+#if defined (ACTIVATOR_IDL_HAS_DLL) && (ACTIVATOR_IDL_HAS_DLL == 1)
+# if defined (ACTIVATOR_IDL_BUILD_DLL)
+# define ActivatorIDL_Export ACE_Proper_Export_Flag
+# define ACTIVATOR_IDL_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define ACTIVATOR_IDL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* ACTIVATOR_IDL_BUILD_DLL */
+# define ActivatorIDL_Export ACE_Proper_Import_Flag
+# define ACTIVATOR_IDL_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define ACTIVATOR_IDL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* ACTIVATOR_IDL_BUILD_DLL */
+#else /* ACTIVATOR_IDL_HAS_DLL == 1 */
+# define ActivatorIDL_Export
+# define ACTIVATOR_IDL_SINGLETON_DECLARATION(T)
+# define ACTIVATOR_IDL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* ACTIVATOR_IDL_HAS_DLL == 1 */
+
+// Set ACTIVATOR_IDL_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (ACTIVATOR_IDL_NTRACE)
+# if (ACE_NTRACE == 1)
+# define ACTIVATOR_IDL_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define ACTIVATOR_IDL_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !ACTIVATOR_IDL_NTRACE */
+
+#if (ACTIVATOR_IDL_NTRACE == 1)
+# define ACTIVATOR_IDL_TRACE(X)
+#else /* (ACTIVATOR_IDL_NTRACE == 1) */
+# define ACTIVATOR_IDL_TRACE(X) ACE_TRACE_IMPL(X)
+#endif /* (ACTIVATOR_IDL_NTRACE == 1) */
+
+#endif /* ACTIVATOR_IDL_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/orbsvcs/ImplRepo_Service/locator_export.h b/TAO/orbsvcs/ImplRepo_Service/locator_export.h
new file mode 100644
index 00000000000..8a3584386f1
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/locator_export.h
@@ -0,0 +1,54 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s Locator
+// ------------------------------
+#ifndef LOCATOR_EXPORT_H
+#define LOCATOR_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (LOCATOR_HAS_DLL)
+# define LOCATOR_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && LOCATOR_HAS_DLL */
+
+#if !defined (LOCATOR_HAS_DLL)
+# define LOCATOR_HAS_DLL 1
+#endif /* ! LOCATOR_HAS_DLL */
+
+#if defined (LOCATOR_HAS_DLL) && (LOCATOR_HAS_DLL == 1)
+# if defined (LOCATOR_BUILD_DLL)
+# define Locator_Export ACE_Proper_Export_Flag
+# define LOCATOR_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define LOCATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* LOCATOR_BUILD_DLL */
+# define Locator_Export ACE_Proper_Import_Flag
+# define LOCATOR_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define LOCATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* LOCATOR_BUILD_DLL */
+#else /* LOCATOR_HAS_DLL == 1 */
+# define Locator_Export
+# define LOCATOR_SINGLETON_DECLARATION(T)
+# define LOCATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* LOCATOR_HAS_DLL == 1 */
+
+// Set LOCATOR_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (LOCATOR_NTRACE)
+# if (ACE_NTRACE == 1)
+# define LOCATOR_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define LOCATOR_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !LOCATOR_NTRACE */
+
+#if (LOCATOR_NTRACE == 1)
+# define LOCATOR_TRACE(X)
+#else /* (LOCATOR_NTRACE == 1) */
+# define LOCATOR_TRACE(X) ACE_TRACE_IMPL(X)
+#endif /* (LOCATOR_NTRACE == 1) */
+
+#endif /* LOCATOR_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/orbsvcs/ImplRepo_Service/locator_idl_export.h b/TAO/orbsvcs/ImplRepo_Service/locator_idl_export.h
new file mode 100644
index 00000000000..3016cfc767b
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/locator_idl_export.h
@@ -0,0 +1,54 @@
+
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by generate_export_file.pl -s Locator
+// ------------------------------
+#ifndef LOCATOR_IDL_EXPORT_H
+#define LOCATOR_IDL_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS) && !defined (LOCATOR_IDL_HAS_DLL)
+# define LOCATOR_IDL_HAS_DLL 0
+#endif /* ACE_AS_STATIC_LIBS && LOCATOR_IDL_HAS_DLL */
+
+#if !defined (LOCATOR_IDL_HAS_DLL)
+# define LOCATOR_IDL_HAS_DLL 1
+#endif /* ! LOCATOR_IDL_HAS_DLL */
+
+#if defined (LOCATOR_IDL_HAS_DLL) && (LOCATOR_IDL_HAS_DLL == 1)
+# if defined (LOCATOR_IDL_BUILD_DLL)
+# define LocatorIDL_Export ACE_Proper_Export_Flag
+# define LOCATOR_IDL_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define LOCATOR_IDL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else /* LOCATOR_IDL_BUILD_DLL */
+# define LocatorIDL_Export ACE_Proper_Import_Flag
+# define LOCATOR_IDL_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define LOCATOR_IDL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* LOCATOR_IDL_BUILD_DLL */
+#else /* LOCATOR_IDL_HAS_DLL == 1 */
+# define LocatorIDL_Export
+# define LOCATOR_IDL_SINGLETON_DECLARATION(T)
+# define LOCATOR_IDL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* LOCATOR_IDL_HAS_DLL == 1 */
+
+// Set LOCATOR_IDL_NTRACE = 0 to turn on library specific tracing even if
+// tracing is turned off for ACE.
+#if !defined (LOCATOR_IDL_NTRACE)
+# if (ACE_NTRACE == 1)
+# define LOCATOR_IDL_NTRACE 1
+# else /* (ACE_NTRACE == 1) */
+# define LOCATOR_IDL_NTRACE 0
+# endif /* (ACE_NTRACE == 1) */
+#endif /* !LOCATOR_IDL_NTRACE */
+
+#if (LOCATOR_IDL_NTRACE == 1)
+# define LOCATOR_IDL_TRACE(X)
+#else /* (LOCATOR_IDL_NTRACE == 1) */
+# define LOCATOR_IDL_TRACE(X) ACE_TRACE_IMPL(X)
+#endif /* (LOCATOR_IDL_NTRACE == 1) */
+
+#endif /* LOCATOR_IDL_EXPORT_H */
+
+// End of auto generated file.
diff --git a/TAO/orbsvcs/ImplRepo_Service/repository.xml b/TAO/orbsvcs/ImplRepo_Service/repository.xml
new file mode 100644
index 00000000000..d6b5ab4638a
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/repository.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<ImplementationRepository>
+ <Servers name="test" activator="MYHOST" command_line="mysrv" working_dir="mydir" activation_mode="NORMAL" start_limit="1" partial_ior="" ior="">
+ </Servers>
+ <Servers name="test2" activator="MYHOST" command_line="" working_dir="" activation_mode="NORMAL" start_limit="1" partial_ior="" ior="">
+ </Servers>
+ <Activators name="MYHOST" token="1610927480" ior="IOR:010000002b00000049444c3a496d706c656d656e746174696f6e5265706f7369746f72792f416374697661746f723a312e300000010000000000000090000000010102cd150000004a555354414c49454e2e6f63697765622e636f6d00cd1f083900000014010f004e555000000017000000000100000000496d525f416374697661746f7200000000000100000054414f496d52416374697661746f7200000002000000000000000800000001cdcdcd004f4154010000001400000001cdcdcd01000100000000000901010000000000"/>
+</ImplementationRepository>
diff --git a/TAO/orbsvcs/ImplRepo_Service/tao_imr.cpp b/TAO/orbsvcs/ImplRepo_Service/tao_imr.cpp
new file mode 100644
index 00000000000..45b72a2790a
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/tao_imr.cpp
@@ -0,0 +1,15 @@
+/* -*- C++ -*- */
+// $Id$
+
+#include "tao_imr_i.h"
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ TAO_IMR_i tao_imr_i;
+
+ if (tao_imr_i.init (argc, argv) != 0)
+ return 1;
+
+ return tao_imr_i.run ();
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp b/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp
new file mode 100644
index 00000000000..9febb1ae406
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.cpp
@@ -0,0 +1,1111 @@
+// $Id$
+
+#include "tao_imr_i.h"
+
+#include "tao/PortableServer/PortableServer.h"
+#include "tao/PortableServer/ForwardRequestC.h"
+
+#include "tao/Stub.h"
+#include "tao/Profile.h"
+
+#include "ace/Get_Opt.h"
+#include "ace/Read_Buffer.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS.h"
+
+TAO_IMR_i::TAO_IMR_i (void)
+: imr_ (ImplementationRepository::Administration::_nil ())
+{
+ // Nothing
+}
+
+TAO_IMR_i::~TAO_IMR_i (void)
+{
+}
+
+int
+TAO_IMR_i::run ()
+{
+ if (this->op_.get () == 0)
+ {
+ ACE_ERROR ((LM_ERROR, "Unknown operation"));
+ return TAO_IMR_Op::UNKNOWN;
+ }
+
+ return this->op_->run ();
+}
+
+int
+TAO_IMR_i::init (int argc, char **argv)
+{
+ this->argc_ = argc;
+ this->argv_ = argv;
+
+ const char *exception_message = "Null Message";
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ // Retrieve the ORB.
+ this->orb_ = CORBA::ORB_init (this->argc_, this->argv_, "tao_imr_i" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Parse command line and verify parameters.
+ if (this->parse_args () == -1)
+ return -1;
+
+ // Get the ImplRepo object
+ CORBA::Object_var obj =
+ orb_->resolve_initial_references ("ImplRepoService" ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (obj.in ()))
+ {
+ ACE_ERROR ((LM_ERROR, "Unable to resolve the ImR.\n"));
+ return -1;
+ }
+
+ exception_message = "While narrowing ImR";
+
+ this->imr_ =
+ ImplementationRepository::Administration::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (CORBA::is_nil (imr_.in ()))
+ {
+ ACE_ERROR ((LM_ERROR, "Unable to narrow the ImR.\n"));
+ return -1;
+ }
+
+ this->op_->set_imr (this->imr_.in ());
+ }
+ ACE_CATCHANY
+ {
+ ACE_ERROR ((LM_ERROR, "TAO_IMR_i::init - %s\n", exception_message));
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Exception");
+ return -1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+
+// Go through and figure out which operation we should do.
+
+int
+TAO_IMR_i::parse_args (void)
+{
+ // Make sure one command was given
+ if (this->argc_ < 2)
+ {
+ ACE_ERROR((LM_ERROR, "Error: No operation specified.\n"));
+ this->print_usage ();
+ return -1;
+ }
+
+ this->op_.reset (TAO_IMR_Op::make_op (this->argv_[1]));
+
+ // Check for unrecognized operation
+
+ if (this->op_.get () == 0)
+ {
+ ACE_ERROR((LM_ERROR, "Error: Unknown operation '%s'.\n", this->argv_[1]));
+ this->print_usage ();
+ return -1;
+ }
+
+ // Adjust argc and argv so only the command specific args are passed
+ return this->op_->parse (this->argc_ - 1, this->argv_ + 1);
+}
+
+
+// Print out information about all operations.
+
+void
+TAO_IMR_i::print_usage (void)
+{
+ ACE_ERROR ((LM_ERROR, "Usage: tao_imr [options] command [command-arguments]\n"
+ " where [options] are ORB options\n"
+ " where command is one of the following:\n"
+ " start Start a server through the ImR\n"
+ " add Add an entry to the ImR\n"
+ " autostart Activates all AUTO_START servers\n"
+ " ior Creates a simplified IOR\n"
+ " list List the entries in the ImR\n"
+ " remove Remove an entry from the ImR\n"
+ " shutdown Shut down a server through the ImR\n"
+ " shutdown-repo Shut down the ImR\n"
+ " update Update an entry in the ImR\n"
+ " where [command-arguments] depend on the command\n"));
+}
+
+
+// Factory for operations
+
+TAO_IMR_Op *
+TAO_IMR_Op::make_op (const ACE_TCHAR *op_name)
+{
+ if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("activate")) == 0)
+ {
+ ACE_ERROR((LM_ERROR, "Warning: The activate option has been renamed to start.\n"));
+ return new TAO_IMR_Op_Activate ();
+ }
+ else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("start")) == 0)
+ return new TAO_IMR_Op_Activate ();
+ else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("add")) == 0)
+ return new TAO_IMR_Op_Register (true);
+ else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("autostart")) == 0)
+ 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 ("list")) == 0)
+ return new TAO_IMR_Op_List ();
+ else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("remove")) == 0)
+ return new TAO_IMR_Op_Remove ();
+ else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("shutdown")) == 0)
+ return new TAO_IMR_Op_Shutdown ();
+ else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("shutdown-repo")) == 0)
+ return new TAO_IMR_Op_ShutdownRepo ();
+ else if (ACE_OS::strcasecmp (op_name, ACE_TEXT ("update")) == 0)
+ return new TAO_IMR_Op_Register (false);
+
+ return 0;
+}
+
+
+TAO_IMR_Op::~TAO_IMR_Op ()
+{
+ // Nothing
+}
+
+void
+TAO_IMR_Op::set_imr (ImplementationRepository::Administration_ptr imr)
+{
+ this->imr_ = imr;
+}
+
+void
+TAO_IMR_Op::display_server_information (const ImplementationRepository::ServerInformation &info)
+{
+ // Figure out what the activation string is.
+ const char *act = "UNKNOWN STARTUP";
+ if (info.startup.activation == ImplementationRepository::NORMAL)
+ act = "NORMAL";
+ else if (info.startup.activation == ImplementationRepository::MANUAL)
+ act = "MANUAL";
+ else if (info.startup.activation == ImplementationRepository::PER_CLIENT)
+ act = "PER_CLIENT";
+ else if (info.startup.activation == ImplementationRepository::AUTO_START)
+ act = "AUTO_START";
+
+ // Print out information
+ ACE_DEBUG ((LM_DEBUG, "Server <%s>\n", info.server.in ()));
+
+ const char * locked_out = "";
+
+ int limit = info.startup.start_limit;
+ if (info.startup.start_limit < 0)
+ {
+ limit = -limit;
+ locked_out = " Locked Out\n";
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ " Activator: %s\n"
+ " Command Line: %s\n"
+ " Working Directory: %s\n"
+ " Activation Mode: %s\n"
+ " Number of retries: %d\n"
+ "%s",
+ info.startup.activator.in (),
+ info.startup.command_line.in (),
+ info.startup.working_directory.in (),
+ act,
+ limit - 1,
+ locked_out));
+ for (CORBA::ULong i = 0; i < info.startup.environment.length (); ++i)
+ ACE_DEBUG ((LM_DEBUG, "Environment Variable: %s=%s \n",
+ info.startup.environment[i].name.in (),
+ info.startup.environment[i].value.in ()));
+
+ if (info.startup.activation == ImplementationRepository::PER_CLIENT)
+ ACE_DEBUG ((LM_DEBUG,
+ " No running info available for PER_CLIENT mode\n"));
+ else if (ACE_OS::strlen (info.partial_ior.in ()) > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ " Running at endpoint: %s\n",
+ info.partial_ior.in ()));
+ else // I am assuming that a blank partial_ior means currently not running.
+ ACE_DEBUG ((LM_DEBUG,
+ " Not currently running\n"));
+
+ ACE_DEBUG ((LM_DEBUG, "\n"));
+}
+
+TAO_IMR_Op_List::TAO_IMR_Op_List (void)
+: verbose_server_information_ (0)
+{
+ // Nothing
+}
+
+TAO_IMR_Op_Register::TAO_IMR_Op_Register (bool is_add)
+: is_add_ (is_add)
+, set_command_line_ (false)
+, set_environment_vars_(false)
+, set_working_dir_ (false)
+, set_activation_ (false)
+, activation_(ImplementationRepository::NORMAL)
+, set_retry_count_(false)
+, retry_count_ (0)
+, set_activator_ (false)
+{
+ // Nothing
+}
+
+void
+TAO_IMR_Op_Activate::print_usage (void)
+{
+ ACE_ERROR ((LM_ERROR, "Starts a server using its registered Activator.\n"
+ "\n"
+ "Usage: tao_imr [options] start <name>\n"
+ " where [options] are ORB options\n"
+ " where <name> is the name of a registered POA.\n"
+ " -h Displays this\n"));
+}
+
+int
+TAO_IMR_Op_Activate::parse (int argc, ACE_TCHAR **argv)
+{
+ // Check for enough arguments (we need at least one for the server name)
+ if (argc < 2)
+ {
+ this->print_usage ();
+ return -1;
+ }
+
+ // Skip both the program name and the "activate" command
+ ACE_Get_Opt get_opts (argc, argv, "h");
+
+ this->server_name_ = argv[1];
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ this->print_usage ();
+ return -1;
+ default:
+ ACE_ERROR((LM_ERROR, "ERROR : Unknown option '%c'\n", (char) c));
+ this->print_usage ();
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void
+TAO_IMR_Op_Autostart::print_usage (void)
+{
+ ACE_ERROR ((LM_ERROR, "Usage: tao_imr [options] autostart\n"
+ " where [options] are ORB options\n"
+ " -h Displays this\n"));
+}
+
+int
+TAO_IMR_Op_Autostart::parse (int argc, ACE_TCHAR **argv)
+{
+ // Skip the "autostart" command
+ ACE_Get_Opt get_opts (argc, argv, "h");
+
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ {
+ switch (c)
+ {
+ case 'h': // display help
+ this->print_usage ();
+ return -1;
+ default:
+ ACE_ERROR((LM_ERROR, "ERROR : Unknown option '%c'\n", (char) c));
+ this->print_usage ();
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void
+TAO_IMR_Op_IOR::print_usage (void)
+{
+ ACE_ERROR ((LM_ERROR, "Creates an IOR for a server that is registered with the IMR and uses\n"
+ "the InterOperable Naming Service. Please see the documentation for\n"
+ "more information on which server configurations work with this command.\n"
+ "\n"
+ "Usage: tao_imr [options] ior <object_key> [command-arguments]\n"
+ " where [options] are ORB options\n"
+ " where <object_key> matches the simple key bound in the server IORTable.\n"
+ " where [command-arguments] can be\n"
+ " -f filename filename to output the IOR to\n"
+ " -h Displays this\n"));
+}
+
+int
+TAO_IMR_Op_IOR::parse (int argc, ACE_TCHAR **argv)
+{
+ // Check for enough arguments (we need at least one for the server name)
+ if (argc < 2)
+ {
+ this->print_usage ();
+ return -1;
+ }
+
+ // Skip both the program name and the "ior" command
+ ACE_Get_Opt get_opts (argc, argv, "hf:");
+
+ this->server_name_ = argv[1];
+ if (this->server_name_.length() == 0 || this->server_name_[0] == '-')
+ {
+ ACE_ERROR((LM_ERROR, "ERROR : name is required.\n"));
+ this->print_usage ();
+ return -1;
+ }
+
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ {
+ switch (c)
+ {
+ case 'f': // File name
+ this->filename_ = get_opts.opt_arg ();
+ break;
+ case 'h': // display help
+ this->print_usage ();
+ return -1;
+ default:
+ ACE_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)
+{
+ ACE_ERROR ((LM_ERROR, "Lists all or one of the servers in the Implementation Repository\n"
+ "\n"
+ "Usage: tao_imr [options] list [name] [command-arguments]\n"
+ " where [options] are ORB options\n"
+ " where [name] is the optional server name to search for\n"
+ " where [command-arguments] can be\n"
+ " -v Verbose: Displays more info for each server when\n"
+ " displaying more than one server\n"
+ " -h Displays this\n"));
+}
+
+int
+TAO_IMR_Op_List::parse (int argc, ACE_TCHAR **argv)
+{
+ int server_flag = 0;
+
+ if (argc > 1 && argv[1][0] != '-')
+ {
+ this->server_name_ = argv[1];
+ server_flag = 2;
+ }
+
+ // Skip both the program name and the "list" command
+ ACE_Get_Opt get_opts (argc, argv, "vh", server_flag);
+
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ {
+ switch (c)
+ {
+ case 'v': // verbose server display
+ this->verbose_server_information_ = 1;
+ break;
+ case 'h': // display help
+ this->print_usage ();
+ return -1;
+ default:
+ ACE_ERROR((LM_ERROR, "ERROR : Unknown option '%c'\n", (char) c));
+ this->print_usage ();
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void
+TAO_IMR_Op_Remove::print_usage (void)
+{
+ ACE_ERROR ((LM_ERROR, "Removes a server entry\n"
+ "\n"
+ "Usage: tao_imr [options] remove <name>\n"
+ " where [options] are ORB options\n"
+ " where <name> is the POA name used by the server object\n"
+ " -h Displays this\n"));
+}
+
+int
+TAO_IMR_Op_Remove::parse (int argc, ACE_TCHAR **argv)
+{
+ // Check for enough arguments (we need at least one for the server name)
+ if (argc < 2)
+ {
+ this->print_usage ();
+ return -1;
+ }
+
+ // Skip both the program name and the "remove" command
+ ACE_Get_Opt get_opts (argc, argv, "h");
+
+ this->server_name_ = argv[1];
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ this->print_usage ();
+ return -1;
+ default:
+ ACE_ERROR((LM_ERROR, "ERROR : Unknown option '%c'\n", (char) c));
+ this->print_usage ();
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void
+TAO_IMR_Op_Shutdown::print_usage (void)
+{
+ ACE_ERROR ((LM_ERROR, "Shuts down a server\n"
+ "\n"
+ "Usage: tao_imr [options] shutdown <name>\n"
+ " where [options] are ORB options\n"
+ " where <name> is the name of the server object\n"
+ " -h Displays this\n"));
+}
+
+int
+TAO_IMR_Op_Shutdown::parse (int argc, ACE_TCHAR **argv)
+{
+ // Check for enough arguments (we need at least one for the server name)
+ if (argc < 2)
+ {
+ this->print_usage ();
+ return -1;
+ }
+
+ // Skip both the program name and the "shutdown" command
+ ACE_Get_Opt get_opts (argc, argv, "h");
+
+ this->server_name_ = argv[1];
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ this->print_usage ();
+ return -1;
+ default:
+ ACE_ERROR((LM_ERROR, "ERROR : Unknown option '%c'\n", (char) c));
+ this->print_usage ();
+ return -1;
+ }
+ }
+ return 0;
+}
+
+TAO_IMR_Op_ShutdownRepo::TAO_IMR_Op_ShutdownRepo()
+: activators_(false)
+{
+}
+
+void
+TAO_IMR_Op_ShutdownRepo::print_usage (void)
+{
+ ACE_ERROR ((LM_ERROR, "Shuts down the ImR\n"
+ "\n"
+ "Usage: tao_imr [options] shutdown-repo [-a]\n"
+ " where [options] are ORB options\n"
+ " Specify -a to also shutdown any registered ImR Activators.\n"
+ " -h Displays this\n"));
+}
+
+int
+TAO_IMR_Op_ShutdownRepo::parse (int argc, ACE_TCHAR **argv)
+{
+ // Check for enough arguments (we need at least one for the server name)
+ if (argc < 1)
+ {
+ this->print_usage ();
+ return -1;
+ }
+
+ // Skip both the program name and the "shutdown-repo" command
+ ACE_Get_Opt get_opts (argc, argv, "ha");
+
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ this->print_usage ();
+ return -1;
+ case 'a':
+ activators_ = true;
+ break;
+ default:
+ ACE_ERROR((LM_ERROR, "ERROR : Unknown option '%c'\n", (char) c));
+ this->print_usage ();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+void
+TAO_IMR_Op_Register::addenv (ACE_TCHAR *opt)
+{
+ CORBA::ULong length = this->environment_vars_.length ();
+ // Increase the length of the sequence
+ this->environment_vars_.length (length + 1);
+ ACE_CString tokens (opt);
+ int index = tokens.find ("=");
+ // Insert at position length since that is our new element
+ this->environment_vars_ [length].name =
+ CORBA::string_dup (tokens.substr (0, index).c_str ());
+ this->environment_vars_ [length].value =
+ CORBA::string_dup (tokens.substr (index + 1).c_str ());
+}
+
+void
+TAO_IMR_Op_Register::print_usage (void)
+{
+ ACE_ERROR ((LM_ERROR,
+ "Adds/Updates a server entry\n"
+ "\n"
+ "Usage: tao_imr [options] <add|update> <name> [command-arguments]\n"
+ " where [options] are ORB options\n"
+ " where <name> is the POA name used by the server object\n"
+ " where [command-arguments] can be\n"
+ " -h Displays this\n"
+ " -l Activator name.\n"
+ " -c command Startup command\n"
+ " -w dir Working directory\n"
+ " -e name=value Set environment variables\n"
+ " -a mode Set activate mode (NORMAL|MANUAL|PER_CLIENT|AUTO_START)\n"
+ " -r count Set the startup/ping retry count to count\n"));
+}
+
+int
+TAO_IMR_Op_Register::parse (int argc, ACE_TCHAR **argv)
+{
+ // Check for enough arguments (we need at least one for the server name)
+ if (argc < 2)
+ {
+ ACE_ERROR((LM_ERROR, "Error: Must supply at least a server name.\n"));
+ this->print_usage ();
+ return -1;
+ }
+
+ // Skip both the program name and the "update" command
+ ACE_Get_Opt get_opts (argc, argv, "hc:w:a:e:r:R:l:");
+
+ this->server_name_ = argv[1];
+ int c;
+
+ while ((c = get_opts ()) != -1)
+ {
+ switch (c)
+ {
+ case 'c': // Command line arguments
+ this->set_command_line_ = true;
+ this->command_line_ = get_opts.opt_arg ();
+ break;
+ case 'e': // set environment variables
+ this->set_environment_vars_ = true;
+ this->addenv( get_opts.opt_arg () );
+ break;
+ case 'w': // Working Directory
+ this->set_working_dir_ = true;
+ this->working_dir_ = get_opts.opt_arg ();
+ break;
+ case 'a': // Activation Mode
+ this->set_activation_ = true;
+ if (ACE_OS::strcasecmp (get_opts.opt_arg (), "NORMAL") == 0)
+ this->activation_ = ImplementationRepository::NORMAL;
+ else if (ACE_OS::strcasecmp (get_opts.opt_arg (), "MANUAL") == 0)
+ this->activation_ = ImplementationRepository::MANUAL;
+ else if (ACE_OS::strcasecmp (get_opts.opt_arg (), "PER_CLIENT") == 0)
+ this->activation_ = ImplementationRepository::PER_CLIENT;
+ else if (ACE_OS::strcasecmp (get_opts.opt_arg (), "AUTO_START") == 0)
+ this->activation_ = ImplementationRepository::AUTO_START;
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unknown Activation Mode <%s>.\n",
+ get_opts.opt_arg ()),
+ -1);
+ break;
+ case 'r':
+ case 'R': // startup/ping Retry Count
+ {
+ this->set_retry_count_ = true;
+ int rc = ACE_OS::atoi(get_opts.optarg);
+ if (rc > 0)
+ this->retry_count_ = rc;
+ }
+ break;
+ case 'l': /// hostname of the activator
+ this->activator_ = get_opts.optarg;
+ this->set_activator_ = true;
+ break;
+ case 'h': // display help
+ this->print_usage ();
+ return -1;
+ default:
+ ACE_ERROR((LM_ERROR, "ERROR : Unknown option '%c'\n", (char) c));
+ this->print_usage ();
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+// ============================================================================
+// = Run methods
+
+
+int
+TAO_IMR_Op_Activate::run (void)
+{
+ ACE_ASSERT(! CORBA::is_nil(imr_));
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->imr_->activate_server (this->server_name_.c_str () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ ACE_DEBUG ((LM_DEBUG,
+ "Successfully Activated server <%s>\n",
+ this->server_name_.c_str ()));
+ }
+ ACE_CATCH (ImplementationRepository::CannotActivate, ex)
+ {
+ ACE_ERROR ((LM_ERROR, "Cannot activate server <%s>, reason: <%s>\n",
+ this->server_name_.c_str (),
+ ex.reason.in ()));
+ return TAO_IMR_Op::CANNOT_ACTIVATE;
+ }
+ ACE_CATCH (ImplementationRepository::NotFound, ex)
+ {
+ ACE_ERROR ((LM_ERROR, "Could not find server <%s>.\n", this->server_name_.c_str ()));
+ return TAO_IMR_Op::NOT_FOUND;
+ }
+ ACE_CATCH (PortableServer::ForwardRequest, ex)
+ {
+ ACE_RE_THROW;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Activating Server");
+ return TAO_IMR_Op::UNKNOWN;
+ }
+ ACE_ENDTRY;
+
+ return TAO_IMR_Op::NORMAL;
+}
+
+int
+TAO_IMR_Op_Autostart::run (void)
+{
+ ACE_ASSERT(! CORBA::is_nil (imr_));
+
+ ImplementationRepository::ServerInformationList_var server_list;
+ ImplementationRepository::ServerInformationIterator_var server_iter;
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->imr_->list (0,
+ server_list,
+ server_iter
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_ASSERT(CORBA::is_nil (server_iter.in ()));
+
+ CORBA::ULong len = server_list->length ();
+ for (CORBA::ULong i = 0; i < len; ++i)
+ {
+ ACE_TRY_EX (inside)
+ {
+ this->imr_->activate_server (server_list[i].server.in () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK_EX (inside);
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, server_list[i].server.in ());
+ // Ignore exception
+ }
+ ACE_ENDTRY;
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "autostart");
+ return TAO_IMR_Op::UNKNOWN;
+ }
+ ACE_ENDTRY;
+
+ return TAO_IMR_Op::NORMAL;
+}
+
+int
+TAO_IMR_Op_IOR::run (void)
+{
+ ACE_ASSERT (! CORBA::is_nil(imr_));
+
+ // Create a corbaloc string
+ // Todo : Most of this logic duplicates that in the POA.cpp
+ ACE_TRY_NEW_ENV
+ {
+ if (CORBA::is_nil (this->imr_)
+ || !this->imr_->_stubobj ()
+ || !this->imr_->_stubobj ()->profile_in_use ())
+ {
+ ACE_ERROR_RETURN ((
+ LM_ERROR,
+ ACE_TEXT ("Invalid ImR IOR.\n")
+ ), -1);
+ }
+
+ CORBA::String_var imr_str =
+ this->imr_->_stubobj ()->
+ profile_in_use ()->to_string (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Search for "corbaloc:" alone, without the protocol. This code
+ // should be protocol neutral.
+ const char corbaloc[] = "corbaloc:";
+ char *pos = ACE_OS::strstr (imr_str.inout (), corbaloc);
+
+ if (pos == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR, "Could not parse IMR IOR.\n"), -1);
+ }
+ else
+ {
+ pos = ACE_OS::strchr (pos + sizeof (corbaloc), ':');
+ pos = ACE_OS::strchr (pos + 1,
+ this->imr_->_stubobj ()->profile_in_use ()->object_key_delimiter ());
+
+ if (pos)
+ {
+ *(pos + 1) = 0; // Crop the string
+ }
+ else
+ {
+ ACE_ERROR_RETURN ((LM_ERROR, "Could not parse IMR IOR.\n"), -1);
+ }
+ }
+ ACE_CString ior (imr_str.in ());
+
+ // Add the key
+ ior += this->server_name_;
+
+ ACE_DEBUG ((LM_DEBUG, "%s\n", ior.c_str ()));
+
+ if (this->filename_.length () > 0)
+ {
+ FILE *file = ACE_OS::fopen (this->filename_.c_str (), "w");
+
+ if (file == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error: Unable to open %s for writing: %p\n",
+ this->filename_.c_str ()),
+ -1);
+ }
+
+ ACE_OS::fprintf (file, "%s", ior.c_str ());
+ ACE_OS::fclose (file);
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "IOR");
+ return TAO_IMR_Op::UNKNOWN;
+ }
+ ACE_ENDTRY;
+
+ return TAO_IMR_Op::NORMAL;
+}
+
+int
+TAO_IMR_Op_List::run (void)
+{
+ ACE_ASSERT (! CORBA::is_nil(imr_));
+
+ ImplementationRepository::ServerInformationList_var server_list;
+ ImplementationRepository::ServerInformationIterator_var server_iter;
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ // If there is a server name, list only that server. Otherwise, look
+ // at all of them.
+ if (this->server_name_.length () == 0)
+ {
+ this->imr_->list (0,
+ server_list.out(),
+ server_iter.out()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (server_list->length() == 0)
+ {
+ ACE_DEBUG((LM_DEBUG, "No servers found.\n"));
+ return TAO_IMR_Op::NORMAL;
+ }
+
+ for (CORBA::ULong i = 0; i < server_list->length (); i++)
+ this->display_server_information (server_list[i]);
+
+ ACE_ASSERT (CORBA::is_nil (server_iter.in ()));
+ }
+ else
+ {
+ ImplementationRepository::ServerInformation_var si;
+
+ this->imr_->find (this->server_name_.c_str (), si ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->verbose_server_information_ = 1;
+
+ this->display_server_information (si.in ());
+ }
+ }
+ ACE_CATCH (ImplementationRepository::NotFound, ex)
+ {
+ ACE_ERROR ((LM_ERROR, "Could not find server <%s>.\n", this->server_name_.c_str ()));
+ return TAO_IMR_Op::NOT_FOUND;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "List");
+ return TAO_IMR_Op::UNKNOWN;
+ }
+ ACE_ENDTRY;
+
+ return TAO_IMR_Op::NORMAL;
+}
+
+int
+TAO_IMR_Op_Remove::run (void)
+{
+ ACE_ASSERT (! CORBA::is_nil(imr_));
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->imr_->remove_server (this->server_name_.c_str () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "Successfully removed server <%s>\n",
+ this->server_name_.c_str ()));
+ }
+ ACE_CATCH (ImplementationRepository::NotFound, ex)
+ {
+ ACE_ERROR ((LM_ERROR, "Could not find server <%s>.\n",
+ this->server_name_.c_str ()));
+ return TAO_IMR_Op::NOT_FOUND;
+ }
+ ACE_CATCH (CORBA::NO_PERMISSION, ex)
+ {
+ ACE_ERROR ((LM_ERROR, "No Permission: ImplRepo is in Locked mode\n"));
+ return TAO_IMR_Op::NO_PERMISSION;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Removing Server");
+ return TAO_IMR_Op::UNKNOWN;
+ }
+ ACE_ENDTRY;
+
+ return TAO_IMR_Op::NORMAL;
+}
+
+int
+TAO_IMR_Op_Shutdown::run (void)
+{
+ ACE_ASSERT (! CORBA::is_nil(imr_));
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->imr_->shutdown_server (this->server_name_.c_str () ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "Successfully shut down server <%s>\n",
+ this->server_name_.c_str ()));
+ }
+ ACE_CATCH (ImplementationRepository::NotFound, ex)
+ {
+ ACE_ERROR ((LM_ERROR, "Server <%s> already shut down.\n", this->server_name_.c_str ()));
+ return TAO_IMR_Op::NOT_FOUND;
+ }
+ ACE_CATCH(CORBA::TIMEOUT, ex)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Timeout waiting for <%s> to shutdown.\n",
+ this->server_name_.c_str ()));
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Shutting Down Server");
+ return TAO_IMR_Op::UNKNOWN;
+ }
+ ACE_ENDTRY;
+
+ return TAO_IMR_Op::NORMAL;
+}
+
+int
+TAO_IMR_Op_ShutdownRepo::run (void)
+{
+ ACE_ASSERT(! CORBA::is_nil(imr_));
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ bool servers = false; // not implemented yet, if ever
+ this->imr_->shutdown (activators_, servers ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG ((LM_DEBUG, "ImR shutdown initiated.\n"));
+ }
+ ACE_CATCH(CORBA::TIMEOUT, ex)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Timeout waiting for ImR shutdown.\n"));
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Shutting Down ImR");
+ return TAO_IMR_Op::UNKNOWN;
+ }
+ ACE_ENDTRY;
+
+ return TAO_IMR_Op::NORMAL;
+}
+
+int
+TAO_IMR_Op_Register::run (void)
+{
+ ACE_ASSERT (! CORBA::is_nil(imr_));
+
+ ImplementationRepository::ServerInformation_var server_information;
+ ImplementationRepository::StartupOptions local;
+ ImplementationRepository::StartupOptions* options = NULL;
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->imr_->find(this->server_name_.c_str (),
+ server_information.out() ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (server_name_ == server_information->server.in())
+ {
+ if (is_add_)
+ {
+ ACE_DEBUG((LM_DEBUG, "Server <%s> already registered.\n", this->server_name_.c_str ()));
+ return ALREADY_REGISTERED;
+ }
+ options = &server_information->startup;
+ }
+ else // not found
+ {
+ if (!is_add_)
+ {
+ ACE_DEBUG((LM_DEBUG, "Adding Server <%s> on update command.\n", this->server_name_.c_str ()));
+ is_add_ = true;
+ }
+ options = &local;
+ }
+
+ if (this->set_command_line_)
+ options->command_line = CORBA::string_dup (this->command_line_.c_str ());
+
+ if (this->set_environment_vars_)
+ options->environment = this->environment_vars_;
+
+ if (this->set_working_dir_)
+ options->working_directory = CORBA::string_dup (this->working_dir_.c_str ());
+
+ if (this->set_activation_ || is_add_)
+ options->activation = this->activation_;
+
+ if (this->set_retry_count_ || is_add_)
+ options->start_limit = this->retry_count_ + 1;
+
+ if (this->set_activator_)
+ options->activator = CORBA::string_dup(this->activator_.c_str ());
+ // If the command line is set, we must have an activator
+ else if (this->set_command_line_ &&
+ (options->activator.in () == 0 || *options->activator.in () == 0))
+ {
+ char host_name[MAXHOSTNAMELEN + 1];
+ ACE_OS::hostname (host_name, MAXHOSTNAMELEN);
+ options->activator = CORBA::string_dup (host_name);
+ ACE_DEBUG ((LM_DEBUG, "Updating Server <%s> with default activator of <%s>.\n",
+ this->server_name_.c_str (), options->activator.in ()));
+ }
+
+ this->imr_->add_or_update_server (this->server_name_.c_str (), *options ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ ACE_DEBUG((LM_DEBUG, "Successfully registered <%s>.\n", this->server_name_.c_str ()));
+ }
+ ACE_CATCH (CORBA::NO_PERMISSION, ex)
+ {
+ ACE_ERROR ((LM_ERROR, "No Permission: ImplRepo is in Locked mode\n"));
+ return TAO_IMR_Op::NO_PERMISSION;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Updating server");
+ return TAO_IMR_Op::UNKNOWN;
+ }
+ ACE_ENDTRY;
+
+ return TAO_IMR_Op::NORMAL;
+}
+
+// ============================================================================
+// = Display Server Information methods
+
+void
+TAO_IMR_Op_List::display_server_information (const ImplementationRepository::ServerInformation &info)
+{
+ if (this->verbose_server_information_)
+ TAO_IMR_Op::display_server_information (info);
+ else
+ ACE_DEBUG ((LM_DEBUG, "<%s>\n", info.server.in ()));
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.h b/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.h
new file mode 100644
index 00000000000..df728e7002e
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/tao_imr_i.h
@@ -0,0 +1,322 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file tao_imr_i.h
+ *
+ * $Id$
+ *
+ * This class implements the Implementation Repository helper application.
+ *
+ *
+ * @author Darrell Brunsch <brunsch@cs.wustl.edu>
+ */
+//=============================================================================
+#ifndef TAO_IMR_I_H
+#define TAO_IMR_I_H
+
+#include "tao/ImR_Client/ImplRepoC.h"
+#include "tao/corba.h"
+#include "ace/SString.h"
+#include "ace/Auto_Ptr.h"
+
+// Forward Declaration
+class TAO_IMR_Op;
+
+/**
+ * @class TAO_IMR_i
+ *
+ * @brief TAO's command line helper application
+ *
+ * This class talks to the IMR and registers/lists/etc.
+ */
+class TAO_IMR_i
+{
+public:
+
+ // = Constructor and destructor.
+ TAO_IMR_i (void);
+ ~TAO_IMR_i (void);
+
+ /// Execute client code.
+ int run (void);
+
+ /// Initialize the client communication endpoint with server.
+ int init (int argc, char **argv);
+
+private:
+ /// Print out information about all operations.
+ void print_usage (void);
+
+ /// Parses the arguments passed on the command line.
+ int parse_args (void);
+
+ /// # of arguments on the command line.
+ int argc_;
+
+ /// Arguments from command line.
+ ACE_TCHAR **argv_;
+
+ /// Remember our orb.
+ CORBA::ORB_var orb_;
+
+ /// Reference to our Locator interface of
+ /// implementation repository.
+ ImplementationRepository::Administration_var imr_;
+
+ /// What we need to do.
+ ACE_Auto_Ptr<TAO_IMR_Op> op_;
+};
+
+
+/**
+ * @class TAO_IMR_Op
+ *
+ * @brief IMR Operation Base Class
+ *
+ * Provides a base class with virtual methods for each operation strategy.
+ */
+class TAO_IMR_Op
+{
+public:
+ enum RETURN_CODES {
+ NORMAL = 0,
+ UNKNOWN,
+ NO_PERMISSION,
+ ALREADY_REGISTERED,
+ CANNOT_ACTIVATE,
+ NOT_FOUND
+ };
+
+ /// Factory.
+ static TAO_IMR_Op *make_op (const ACE_TCHAR *op_name);
+
+ /// Destructor.
+ virtual ~TAO_IMR_Op (void);
+
+ /// Parse arguments.
+ virtual int parse (int argc, ACE_TCHAR **argv) = 0;
+
+ /// Do the work.
+ virtual int run (void) = 0;
+
+ /// Sets the implrepo locator pointer
+ void set_imr (ImplementationRepository::Administration_ptr imr);
+
+protected:
+ /// Reference to our implementation repository.
+ ImplementationRepository::Administration_ptr imr_;
+
+ // = Helper methods
+
+ /// Prints out the information contained in a ServerInformation structure.
+ void display_server_information (const ImplementationRepository::ServerInformation &info);
+};
+
+
+/**
+ * @class TAO_IMR_Op_Activate
+ *
+ * @brief Activation Operation
+ *
+ * Activation is used to start servers via the Implementation Repository
+ */
+class TAO_IMR_Op_Activate : 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);
+
+ /// POA server name.
+ ACE_CString server_name_;
+};
+
+/**
+ * @class TAO_IMR_Op_Autostart
+ *
+ * @brief Autostart Operation
+ *
+ * Autostart is used to activate all servers with the AUTO_START activation
+ * mode.
+ */
+class TAO_IMR_Op_Autostart : 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);
+};
+
+
+/**
+ * @class TAO_IMR_Op_IOR
+ *
+ * @brief IOR Operation
+ *
+ * IOR is used to create a simple IOR for a server that uses the
+ * IMR and the Interoperable Naming Service.
+ */
+class TAO_IMR_Op_IOR : 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);
+
+ /// POA server name.
+ ACE_CString server_name_;
+
+ /// Filename to output to.
+ ACE_CString filename_;
+};
+
+
+/**
+ * @class TAO_IMR_Op_List
+ *
+ * @brief List Operation
+ *
+ * List is used to either list all the servers registered in the IMR or just
+ * look at one of them.
+ */
+class TAO_IMR_Op_List : public TAO_IMR_Op
+{
+public:
+ TAO_IMR_Op_List (void);
+
+ virtual int parse (int argc, ACE_TCHAR **argv);
+ virtual int run (void);
+
+protected:
+ /// Prints a message about the usage
+ void print_usage (void);
+
+ /// POA server name.
+ ACE_CString server_name_;
+
+ /// If true, more server information is displayed.
+ int verbose_server_information_;
+
+ /// Prints out the information contained in a ServerInformation structure.
+ /// Specialized to only print server information
+ void display_server_information (const ImplementationRepository::ServerInformation &info);
+};
+
+
+/**
+ * @class TAO_IMR_Op_Remove
+ *
+ * @brief Remove Operation
+ *
+ * Remove is used to unregister a server in the IMR.
+ */
+class TAO_IMR_Op_Remove : 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_;
+};
+
+
+/**
+ * @class TAO_IMR_Op_Shutdown
+ *
+ * @brief Shutdown Operation
+ *
+ * Shutdown is used to shutdown a server through the IMR.
+ */
+class TAO_IMR_Op_Shutdown : 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_;
+};
+
+/**
+ * Shutdown the ImR and optionally any registered activators.
+ */
+class TAO_IMR_Op_ShutdownRepo : public TAO_IMR_Op
+{
+public:
+ TAO_IMR_Op_ShutdownRepo();
+ virtual int parse (int argc, ACE_TCHAR **argv);
+ virtual int run (void);
+
+protected:
+ void print_usage (void);
+
+ bool activators_;
+};
+
+/**
+ * @class TAO_IMR_Op_Register
+ *
+ * @brief Register Operation
+ *
+ * Register is used to update/add information for a server
+ * with the IMR.
+ */
+class TAO_IMR_Op_Register : public TAO_IMR_Op
+{
+public:
+ TAO_IMR_Op_Register(bool is_add);
+
+ virtual int parse (int argc, ACE_TCHAR **argv);
+ virtual int run (void);
+
+protected:
+
+ /// Enables pre-registration checks
+ bool is_add_;
+
+ /// Sets one environment variable.
+ void addenv (ACE_TCHAR *opt);
+
+ /// Prints a message about the usage.
+ void print_usage (void);
+
+ /// POA server name.
+ ACE_CString server_name_;
+
+ bool set_command_line_;
+ ACE_CString command_line_;
+
+ bool set_environment_vars_;
+ ImplementationRepository::EnvironmentList environment_vars_;
+
+ bool set_working_dir_;
+ ACE_CString working_dir_;
+
+ bool set_activation_;
+ ImplementationRepository::ActivationMode activation_;
+
+ bool set_retry_count_;
+ int retry_count_;
+
+ bool set_activator_;
+ ACE_CString activator_;
+};
+
+#endif /* TAO_IMR_I_H */
diff --git a/TAO/orbsvcs/ImplRepo_Service/utils.h b/TAO/orbsvcs/ImplRepo_Service/utils.h
new file mode 100644
index 00000000000..2e4effd55b9
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/utils.h
@@ -0,0 +1,98 @@
+//$Id$
+#ifndef TAO_IMR_UTILS_H
+#define TAO_IMR_UTILS_H
+
+#include "tao/ImR_Client/ImplRepoC.h"
+
+#include "ace/SString.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+class ImR_Utils {
+public:
+ static ACE_CString activationModeToString(ImplementationRepository::ActivationMode mode)
+ {
+ switch (mode )
+ {
+ case ImplementationRepository::NORMAL:
+ return "NORMAL";
+ case ImplementationRepository::MANUAL:
+ return "MANUAL";
+ case ImplementationRepository::PER_CLIENT:
+ return "PER_CLIENT";
+ case ImplementationRepository::AUTO_START:
+ return "AUTO_START";
+ default:
+ ACE_ASSERT(mode == ImplementationRepository::NORMAL);
+ return "";
+ }
+ }
+ static ImplementationRepository::ActivationMode parseActivationMode(const ACE_CString& s)
+ {
+ if (s == "NORMAL")
+ return ImplementationRepository::NORMAL;
+ if (s == "MANUAL")
+ return ImplementationRepository::MANUAL;
+ if (s == "PER_CLIENT")
+ return ImplementationRepository::PER_CLIENT;
+ if (s == "AUTO_START")
+ return ImplementationRepository::AUTO_START;
+
+ return ImplementationRepository::NORMAL;
+ }
+ static ACE_CString envListToString(const ImplementationRepository::EnvironmentList& lst)
+ {
+ ACE_CString ret;
+ for (CORBA::ULong n = 0; n < lst.length(); ++n)
+ {
+ ret += "name=\"";
+ ret += lst[n].name.in();
+ ret += "\" value=\"";
+ ret += lst[n].value.in();
+ ret += "\"\n";
+ }
+ return ret;
+ }
+ static ImplementationRepository::EnvironmentList parseEnvList(const ACE_CString& s)
+ {
+ ImplementationRepository::EnvironmentList ret(10);
+
+ const ACE_CString NAMETAG = "name=\"";
+ const ACE_CString VALTAG = "value=\"";
+ const ACE_CString ENDTAG = "\"";
+
+ ACE_CString::size_type i = 0;
+
+ for (CORBA::ULong idx = 0; ; ++idx)
+ {
+ // find name
+ ACE_CString::size_type j = s.find(NAMETAG, i);
+ if (j == ACE_CString::npos) break;
+ j += NAMETAG.length();
+ ACE_CString::size_type k = s.find(ENDTAG, j + 1);
+ if (k == ACE_CString::npos) break;
+ ACE_CString name = s.substr(j, k - j);
+
+ i = k + 1;
+
+ // find value
+ j = s.find(VALTAG, i);
+ if (j == ACE_CString::npos) break;
+ j += VALTAG.length();
+ k = s.find(ENDTAG, j + 1);
+ if (k == ACE_CString::npos) break;
+ ACE_CString value = s.substr(j, k - j);
+
+ i = k + 1;
+
+ ret.length(idx + 1);
+ ret[idx].name = name.c_str();
+ ret[idx].value = value.c_str();
+ }
+ return ret;
+ }
+};
+
+#endif