summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2002-04-02 01:28:59 +0000
committerMark Spruiell <mes@zeroc.com>2002-04-02 01:28:59 +0000
commit2c7658451fb8e832451f758648dea584a13fd9ce (patch)
treef23c606d3785af50917c9b459070d601244c4b9b /cpp
parentadding future ops (diff)
downloadice-2c7658451fb8e832451f758648dea584a13fd9ce.tar.bz2
ice-2c7658451fb8e832451f758648dea584a13fd9ce.tar.xz
ice-2c7658451fb8e832451f758648dea584a13fd9ce.zip
initial clean-up
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/IceBox/Exception.cpp23
-rw-r--r--cpp/src/IceBox/Makefile3
-rw-r--r--cpp/src/IceBox/Server.cpp4
-rw-r--r--cpp/src/IceBox/ServiceManagerI.cpp433
-rw-r--r--cpp/src/IceBox/ServiceManagerI.h22
5 files changed, 251 insertions, 234 deletions
diff --git a/cpp/src/IceBox/Exception.cpp b/cpp/src/IceBox/Exception.cpp
deleted file mode 100644
index 342349c4b1d..00000000000
--- a/cpp/src/IceBox/Exception.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// MutableRealms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceBox/IceBox.h>
-#include <Ice/Stream.h>
-
-using namespace std;
-using namespace Ice;
-using namespace IceInternal;
-
-void
-IceBox::ServiceFailureException::ice_print(ostream& out) const
-{
- Exception::ice_print(out);
- out << ":\nservice failure exception";
-}
diff --git a/cpp/src/IceBox/Makefile b/cpp/src/IceBox/Makefile
index 7a7d381449c..218845f02c2 100644
--- a/cpp/src/IceBox/Makefile
+++ b/cpp/src/IceBox/Makefile
@@ -21,8 +21,7 @@ ADMIN = $(top_srcdir)/bin/iceboxadmin
TARGETS = $(NAME) $(VERSIONED_NAME) $(SERVER) $(ADMIN)
-OBJS = IceBox.o \
- Exception.o
+OBJS = IceBox.o
SOBJS = ServiceManagerI.o \
Server.o
diff --git a/cpp/src/IceBox/Server.cpp b/cpp/src/IceBox/Server.cpp
index 13c18d746df..edb4ad5d01a 100644
--- a/cpp/src/IceBox/Server.cpp
+++ b/cpp/src/IceBox/Server.cpp
@@ -27,9 +27,9 @@ main(int argc, char* argv[])
try
{
communicator = initialize(argc, argv);
- ServiceManagerI* serviceManagerImpl = new ServiceManagerI(communicator);
+ ServiceManagerI* serviceManagerImpl = new ServiceManagerI(communicator, argc, argv);
serviceManager = serviceManagerImpl;
- status = serviceManagerImpl->run(argc, argv);
+ status = serviceManagerImpl->run();
}
catch (const Exception& ex)
{
diff --git a/cpp/src/IceBox/ServiceManagerI.cpp b/cpp/src/IceBox/ServiceManagerI.cpp
index 99ae44a9735..517c320204f 100644
--- a/cpp/src/IceBox/ServiceManagerI.cpp
+++ b/cpp/src/IceBox/ServiceManagerI.cpp
@@ -18,9 +18,23 @@ using namespace std;
typedef IceBox::ServicePtr (*SERVICE_FACTORY)(CommunicatorPtr);
-IceBox::ServiceManagerI::ServiceManagerI(CommunicatorPtr communicator)
+IceBox::ServiceManagerI::ServiceManagerI(CommunicatorPtr communicator, int& argc, char* argv[])
: _communicator(communicator)
{
+ _logger = _communicator->getLogger();
+
+ if (argc > 0)
+ {
+ _progName = argv[0];
+ }
+
+ for (int i = 1; i < argc; i++)
+ {
+ _argv.push_back(argv[i]);
+ }
+
+ PropertiesPtr properties = _communicator->getProperties();
+ _options = properties->getCommandLineOptions();
}
IceBox::ServiceManagerI::~ServiceManagerI()
@@ -34,12 +48,10 @@ IceBox::ServiceManagerI::shutdown(const Current& current)
}
int
-IceBox::ServiceManagerI::run(int& argc, char* argv[])
+IceBox::ServiceManagerI::run()
{
try
{
- _logger = _communicator->getLogger();
-
ServiceManagerPtr obj = this;
//
@@ -52,21 +64,69 @@ IceBox::ServiceManagerI::run(int& argc, char* argv[])
adapter->add(obj, stringToIdentity("ServiceManager"));
//
- // Load and initialize the services.
+ // Load and initialize the services defined in the property set
+ // with the prefix "IceBox.Service.". These properties should
+ // have the following format:
+ //
+ // IceBox.Service.Foo=libFoo.so:create [args]
//
- if (!initServices(argc, argv))
+ const string prefix = "IceBox.Service.";
+ PropertiesPtr properties = _communicator->getProperties();
+ StringSeq services = properties->getProperties(prefix);
+ for (StringSeq::size_type i = 0; i < services.size(); i += 2)
{
- stopServices();
- return EXIT_FAILURE;
+ string name = services[i].substr(prefix.size());
+ string value = services[i + 1];
+
+ //
+ // Separate the entry point from the arguments.
+ //
+ string exec;
+ StringSeq args;
+ string::size_type pos = value.find_first_of(" \t\n");
+ if (pos == string::npos)
+ {
+ exec = value;
+ }
+ else
+ {
+ exec = value.substr(0, pos);
+ string::size_type beg = value.find_first_not_of(" \t\n", pos);
+ while (beg != string::npos)
+ {
+ string::size_type end = value.find_first_of(" \t\n", beg);
+ if (end == string::npos)
+ {
+ args.push_back(value.substr(beg));
+ beg = end;
+ }
+ else
+ {
+ args.push_back(value.substr(beg, end - beg));
+ beg = value.find_first_not_of(" \t\n", end);
+ }
+ }
+ }
+
+ init(name, exec, args);
}
//
// Invoke start() on the services.
//
- if (!startServices())
+ map<string,ServiceInfo>::const_iterator r;
+ for (r = _services.begin(); r != _services.end(); ++r)
{
- stopServices();
- return EXIT_FAILURE;
+ try
+ {
+ (*r).second.service->start();
+ }
+ catch (const Exception& ex)
+ {
+ FailureException ex;
+ ex.reason = "ServiceManager: exception in start for service " + (*r).first + ": " + ex.ice_name();
+ throw ex;
+ }
}
//
@@ -79,242 +139,215 @@ IceBox::ServiceManagerI::run(int& argc, char* argv[])
//
// Invoke stop() on the services.
//
- stopServices();
+ stopAll();
+ }
+ catch (const FailureException& ex)
+ {
+ Error out(_logger);
+ out << ex.reason;
+ stopAll();
+ return EXIT_FAILURE;
}
catch (const Exception& ex)
{
Error out(_logger);
out << "ServiceManager: " << ex;
- stopServices();
+ stopAll();
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-bool
-IceBox::ServiceManagerI::initServices(int& argc, char* argv[])
+IceBox::ServicePtr
+IceBox::ServiceManagerI::init(const string& service, const string& exec, const StringSeq& args)
{
//
- // Retrieve all properties with the prefix "IceBox.Service.".
- // These properties should have the following format:
+ // We need to create a property set to pass to init().
+ // The property set is populated from a number of sources.
+ // The precedence order (from lowest to highest) is:
//
- // IceBox.Service.Foo=Package.Foo [args]
+ // 1. Properties defined in the server property set (e.g.,
+ // that were defined in the server's configuration file)
+ // 2. Service arguments
+ // 3. Server arguments
//
- const string prefix = "IceBox.Service.";
- PropertiesPtr properties = _communicator->getProperties();
- StringSeq allOptions = properties->getCommandLineOptions();
- StringSeq arr = properties->getProperties(prefix);
- for (StringSeq::size_type i = 0; i < arr.size(); i += 2)
+ // We'll compose an array of arguments in the above order.
+ //
+ vector<string> l;
+ StringSeq::size_type j;
+ for (j = 0; j < _options.size(); j++)
{
- string name = arr[i].substr(prefix.size());
- string value = arr[i + 1];
-
- //
- // Separate the factory function from the arguments.
- //
- string factoryFunc;
- StringSeq args;
- string::size_type pos = value.find_first_of(" \t\n");
- if (pos == string::npos)
+ if (_options[j].find("--" + service + ".") == 0)
{
- factoryFunc = value;
+ l.push_back(_options[j]);
}
- else
- {
- factoryFunc = value.substr(0, pos);
- string::size_type beg = value.find_first_not_of(" \t\n", pos);
- while (beg != string::npos)
- {
- string::size_type end = value.find_first_of(" \t\n", beg);
- if (end == string::npos)
- {
- args.push_back(value.substr(beg));
- beg = end;
- }
- else
- {
- args.push_back(value.substr(beg, end - beg));
- beg = value.find_first_not_of(" \t\n", end);
- }
- }
- }
-
- //
- // Now we need to create a property set to pass to init().
- // The property set is populated from a number of sources.
- // The precedence order (from lowest to highest) is:
- //
- // 1. Properties defined in the server property set (e.g.,
- // that were defined in the server's configuration file)
- // 2. Service arguments
- // 3. Server arguments
- //
- // We'll compose an array of arguments in the above order.
- //
- vector<string> l;
- StringSeq::size_type j;
- int k;
- for (j = 0; j < allOptions.size(); j++)
- {
- if (allOptions[j].find("--" + name + ".") == 0)
- {
- l.push_back(allOptions[j]);
- }
- }
- for (j = 0; j < args.size(); j++)
- {
- l.push_back(args[j]);
- }
- for (k = 1; k < argc; k++)
+ }
+ for (j = 0; j < args.size(); j++)
+ {
+ l.push_back(args[j]);
+ }
+ for (j = 0; j < _argv.size(); j++)
+ {
+ if (_argv[j].find("--" + service + ".") == 0)
{
- string s = argv[k];
- if (s.find("--" + name + ".") == 0)
- {
- l.push_back(s);
- }
+ l.push_back(_argv[j]);
}
+ }
- //
- // Create the service property set.
- //
- addArgumentPrefix(name);
- int serviceArgc = static_cast<int>(l.size() + 1);
- char** serviceArgv = new char*[serviceArgc + 1];
- serviceArgv[0] = argv[0];
- for (k = 1; k < serviceArgc; k++)
- {
- serviceArgv[k] = const_cast<char*>(l[k - 1].c_str());
- }
- PropertiesPtr serviceProperties = createProperties(serviceArgc, serviceArgv);
- StringSeq serviceArgs;
- for (k = 1; k < serviceArgc; k++)
- {
- serviceArgs.push_back(serviceArgv[k]);
- }
- delete[] serviceArgv;
+ //
+ // Create the service property set.
+ //
+ addArgumentPrefix(service);
+ int serviceArgc = static_cast<int>(l.size() + 1);
+ char** serviceArgv = new char*[serviceArgc + 1];
+ serviceArgv[0] = const_cast<char*>(_progName.c_str());
+ int k;
+ for (k = 1; k < serviceArgc; k++)
+ {
+ serviceArgv[k] = const_cast<char*>(l[k - 1].c_str());
+ }
+ PropertiesPtr serviceProperties = createProperties(serviceArgc, serviceArgv);
+ StringSeq serviceArgs;
+ for (k = 1; k < serviceArgc; k++)
+ {
+ serviceArgs.push_back(serviceArgv[k]);
+ }
+ delete[] serviceArgv;
- //
- // Load the dynamic library.
- //
- string::size_type colon = factoryFunc.rfind(':');
- if (colon == string::npos || colon == factoryFunc.size() - 1)
- {
- Error out(_logger);
- out << "ServiceManager: invalid factory function `" << factoryFunc << "'";
- return false;
- }
- string libName = factoryFunc.substr(0, colon);
- string funcName = factoryFunc.substr(colon + 1);
- DynamicLibraryPtr library = new DynamicLibrary();
- if (!library->load(libName))
+ //
+ // Load the dynamic library.
+ //
+ string::size_type colon = exec.rfind(':');
+ if (colon == string::npos || colon == exec.size() - 1)
+ {
+ FailureException ex;
+ ex.reason = "ServiceManager: invalid factory format `" + exec + "'";
+ throw ex;
+ }
+ string libName = exec.substr(0, colon);
+ string funcName = exec.substr(colon + 1);
+ DynamicLibraryPtr library = new DynamicLibrary();
+ if (!library->load(libName))
+ {
+ string msg = library->getErrorMessage();
+ FailureException ex;
+ ex.reason = "ServiceManager: unable to load library `" + libName + "'";
+ if (!msg.empty())
{
- string msg = library->getErrorMessage();
- Error out(_logger);
- out << "ServiceManager: unable to load library `" << libName << "'";
- if (!msg.empty())
- {
- out << ": " << msg;
- }
- return false;
+ ex.reason += ": " + msg;
}
+ throw ex;
+ }
- //
- // Lookup the factory function and invoke it.
- //
- DynamicLibrary::symbol_type sym = library->getSymbol(funcName);
- if (sym == 0)
- {
- string msg = library->getErrorMessage();
- Error out(_logger);
- out << "ServiceManager: unable to load symbol `" << funcName << "'";
- if (!msg.empty())
- {
- out << ": " << msg;
- }
- return false;
- }
- SERVICE_FACTORY factory = (SERVICE_FACTORY)sym;
- ServicePtr service;
- try
- {
- service = factory(_communicator);
- }
- catch (const Exception& ex)
+ //
+ // Lookup the factory function and invoke it.
+ //
+ DynamicLibrary::symbol_type sym = library->getSymbol(funcName);
+ if (sym == 0)
+ {
+ string msg = library->getErrorMessage();
+ FailureException ex;
+ ex.reason = "ServiceManager: unable to load symbol `" + funcName + "'";
+ if (!msg.empty())
{
- Error out(_logger);
- out << "ServiceManager: exception in factory function `" << funcName << "': " << ex;
- return false;
+ ex.reason += ": " + msg;
}
+ throw ex;
+ }
+ SERVICE_FACTORY factory = (SERVICE_FACTORY)sym;
+ ServiceInfo info;
+ try
+ {
+ info.service = factory(_communicator);
+ }
+ catch (const Exception& ex)
+ {
+ FailureException ex;
+ ex.reason = "ServiceManager: exception in factory function `" + funcName + "': " + ex.ice_name();
+ throw ex;
+ }
- //
- // Invoke Service::init().
- //
- try
- {
- service->init(name, _communicator, serviceProperties, serviceArgs);
- _services[name] = service;
- _libraries.push_back(library);
- }
- catch (const ServiceFailureException& ex)
- {
- Error out(_logger);
- out << "ServiceManager: initialization failed for service " << name;
- return false;
- }
- catch (const Exception& ex)
- {
- Error out(_logger);
- out << "ServiceManager: exception while initializing service " << name << ": " << ex;
- return false;
- }
+ //
+ // Invoke Service::init().
+ //
+ try
+ {
+ info.service->init(service, _communicator, serviceProperties, serviceArgs);
+ info.library = library;
+ _services[service] = info;
+ }
+ catch (const FailureException& ex)
+ {
+ throw;
+ }
+ catch (const Exception& ex)
+ {
+ FailureException ex;
+ ex.reason = "ServiceManager: exception while initializing service " + service + ": " + ex.ice_name();
+ throw ex;
}
- return true;
+ return info.service;
}
-bool
-IceBox::ServiceManagerI::startServices()
+void
+IceBox::ServiceManagerI::stop(const string& service)
{
- map<string,ServicePtr>::const_iterator r;
- for (r = _services.begin(); r != _services.end(); ++r)
+ map<string,ServiceInfo>::iterator r = _services.find(service);
+ assert(r != _services.end());
+ ServiceInfo info = (*r).second;
+ _services.erase(r);
+
+ try
{
- try
- {
- (*r).second->start();
- }
- catch (const ServiceFailureException& ex)
- {
- Error out(_logger);
- out << "ServiceManager: start failed for service " << (*r).first;
- return false;
- }
- catch (const Exception& ex)
- {
- Error out(_logger);
- out << "ServiceManager: exception in start for service " << (*r).first << ": " << ex;
- return false;
- }
+ info.service->stop();
+ }
+ catch (const FailureException& ex)
+ {
+ //
+ // Release the service before the library
+ //
+ info.service = 0;
+ info.library = 0;
+
+ throw;
}
+ catch (const Exception& ex)
+ {
+ //
+ // Release the service before the library
+ //
+ info.service = 0;
+ info.library = 0;
- return true;
+ FailureException ex;
+ ex.reason = "ServiceManager: exception in stop for service " + service + ": " + ex.ice_name();
+ throw ex;
+ }
+
+ //
+ // Release the service before the library
+ //
+ info.service = 0;
+ info.library = 0;
}
void
-IceBox::ServiceManagerI::stopServices()
+IceBox::ServiceManagerI::stopAll()
{
- map<string,ServicePtr>::const_iterator r;
+ map<string,ServiceInfo>::const_iterator r;
for (r = _services.begin(); r != _services.end(); ++r)
{
try
{
- (*r).second->stop();
+ stop((*r).first);
}
- catch (const Exception& ex)
+ catch (const FailureException& ex)
{
Error out(_logger);
- out << "ServiceManager: exception in stop for service " << (*r).first << ": " << ex;
+ out << ex.reason;
}
}
- _services.clear();
+ assert(_services.empty());
}
diff --git a/cpp/src/IceBox/ServiceManagerI.h b/cpp/src/IceBox/ServiceManagerI.h
index 8a84d5aff22..cbfa5edd8b7 100644
--- a/cpp/src/IceBox/ServiceManagerI.h
+++ b/cpp/src/IceBox/ServiceManagerI.h
@@ -24,23 +24,31 @@ class ServiceManagerI : public ServiceManager
{
public:
- ServiceManagerI(::Ice::CommunicatorPtr);
+ ServiceManagerI(::Ice::CommunicatorPtr, int&, char*[]);
virtual ~ServiceManagerI();
virtual void shutdown(const ::Ice::Current&);
- int run(int&, char*[]);
+ int run();
+
+ struct ServiceInfo
+ {
+ ServicePtr service;
+ ::IceInternal::DynamicLibraryPtr library;
+ };
private:
- bool initServices(int&, char*[]);
- bool startServices();
- void stopServices();
+ ServicePtr init(const std::string&, const std::string&, const ::Ice::StringSeq&);
+ void stop(const std::string&);
+ void stopAll();
::Ice::CommunicatorPtr _communicator;
::Ice::LoggerPtr _logger;
- std::map<std::string, ServicePtr> _services;
- std::vector< ::IceInternal::DynamicLibraryPtr > _libraries;
+ std::string _progName; // argv[0]
+ ::Ice::StringSeq _argv; // Filtered server argument vector, not including program name
+ ::Ice::StringSeq _options; // Server property set converted to command-line options
+ std::map<std::string, ServiceInfo> _services;
};
}