summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Glacier/ClientBlobject.cpp2
-rw-r--r--cpp/src/Glacier/GlacierI.cpp273
-rw-r--r--cpp/src/Glacier/GlacierI.h5
-rw-r--r--cpp/src/Glacier/GlacierRouter.cpp9
-rw-r--r--cpp/src/Glacier/GlacierStarter.cpp8
-rw-r--r--cpp/src/Glacier/RouterI.cpp5
-rw-r--r--cpp/src/Glacier/ServerBlobject.cpp2
-rw-r--r--cpp/src/Ice/PropertiesI.cpp2
8 files changed, 222 insertions, 84 deletions
diff --git a/cpp/src/Glacier/ClientBlobject.cpp b/cpp/src/Glacier/ClientBlobject.cpp
index 9cd92e4a459..b8cf3dd76cb 100644
--- a/cpp/src/Glacier/ClientBlobject.cpp
+++ b/cpp/src/Glacier/ClientBlobject.cpp
@@ -33,8 +33,10 @@ Glacier::ClientBlobject::~ClientBlobject()
void
Glacier::ClientBlobject::destroy()
{
+ //
// No mutex protection necessary, destroy is only called after all
// object adapters have shut down.
+ //
_communicator = 0;
_logger = 0;
_routingTable = 0;
diff --git a/cpp/src/Glacier/GlacierI.cpp b/cpp/src/Glacier/GlacierI.cpp
index 0d2ef4a4c2c..82861ada133 100644
--- a/cpp/src/Glacier/GlacierI.cpp
+++ b/cpp/src/Glacier/GlacierI.cpp
@@ -22,13 +22,30 @@ using namespace Ice;
using namespace Glacier;
Glacier::StarterI::StarterI(const CommunicatorPtr& communicator) :
- _communicator(communicator)
+ _communicator(communicator),
+ _logger(_communicator->getLogger()),
+ _properties(_communicator->getProperties())
{
+ _traceLevel = atoi(_properties->getProperty("Glacier.Trace.Starter").c_str());
+}
+
+void
+Glacier::StarterI::destroy()
+{
+ //
+ // No mutex protection necessary, destroy is only called after all
+ // object adapters have shut down.
+ //
+ _communicator = 0;
+ _logger = 0;
+ _properties = 0;
}
RouterPrx
Glacier::StarterI::startRouter(const string& userId, const string& password, const Current&)
{
+ assert(_communicator); // Destroyed?
+
//
// TODO: userId/password check
//
@@ -36,82 +53,131 @@ Glacier::StarterI::startRouter(const string& userId, const string& password, con
//
// Start a router
//
+ string path = _properties->getProperty("Glacier.Starter.RouterPath");
+ if (path.empty())
+ {
+ path = "glacier";
+ }
+
string uuid = IceUtil::generateUUID();
- char buf[4*1024];
+ pid_t pid;
+ int fds[2];
+
try
{
- int fds[2];
if (pipe(fds) != 0)
{
SystemException ex(__FILE__, __LINE__);
ex.error = getSystemErrno();
throw ex;
}
- pid_t pid = fork();
+ pid = fork();
if (pid == -1)
{
SystemException ex(__FILE__, __LINE__);
ex.error = getSystemErrno();
throw ex;
}
- if (pid == 0) // Child process
+ }
+ catch(const LocalException& ex)
+ {
+ ostringstream s;
+ s << ex;
+ _logger->error(s.str());
+
+ ex.ice_throw();
+ }
+
+ if (pid == 0) // Child process
+ {
+ //
+ // Close all filedescriptors, except for standard input,
+ // standard output, standard error output, and the write side
+ // of the newly created pipe.
+ //
+ int maxFd = static_cast<int>(sysconf(_SC_OPEN_MAX));
+ for (int fd = 3; fd < maxFd; ++fd)
{
- //
- // Close all filedescriptors, except for standard input,
- // standard output, standard error output, and the write side
- // of the newly created pipe.
- //
- int maxFd = static_cast<int>(sysconf(_SC_OPEN_MAX));
- for (int fd = 3; fd < maxFd; ++fd)
+ if (fd != fds[1])
{
- if (fd != fds[1])
- {
- close(fd);
- }
+ close(fd);
}
-
- //
- // Setup arguments to start the router with.
- //
- StringSeq args = _communicator->getProperties()->getCommandLineOptions();
- args.push_back("--Glacier.Router.Identity=" + uuid);
- ostringstream s;
- s << "--Glacier.Router.PrintProxyOnFd=" << fds[1];
- args.push_back(s.str());
-
- //
- // Convert to standard argc/argv.
- //
- int argc = args.size() + 1;
- char** argv = static_cast<char**>(malloc((argc + 1) * sizeof(char*)));
- StringSeq::iterator p;
- int i;
- for (p = args.begin(), i = 1; p != args.end(); ++p, ++i)
+ }
+
+ //
+ // Setup arguments to start the router with.
+ //
+ StringSeq args = _properties->getCommandLineOptions();
+ args.push_back("--Glacier.Router.Identity=" + uuid);
+ ostringstream s;
+ s << "--Glacier.Router.PrintProxyOnFd=" << fds[1];
+ args.push_back(s.str());
+ string overwrite = _properties->getProperty("Glacier.Starter.PropertiesOverwrite");
+ if (!overwrite.empty())
+ {
+ string::size_type end = 0;
+ while (end != string::npos)
{
- assert(i < argc);
- argv[i] = strdup(p->c_str());
+ static const string delim = " \t\r\n";
+
+ string::size_type beg = overwrite.find_first_not_of(delim, end);
+ if (beg == string::npos)
+ {
+ break;
+ }
+
+ end = overwrite.find_first_of(delim, beg);
+ string arg;
+ if (end == string::npos)
+ {
+ arg = overwrite.substr(beg);
+ }
+ else
+ {
+ arg = overwrite.substr(beg, end - beg);
+ }
+ if (arg.find("--") != 0)
+ {
+ arg = "--" + arg;
+ }
+ args.push_back(arg);
}
- assert(i == argc);
- argv[0] = strdup("glacier"); // TODO: Property
- argv[argc] = 0;
-
+ }
+
+ //
+ // Convert to standard argc/argv.
+ //
+ int argc = args.size() + 1;
+ char** argv = static_cast<char**>(malloc((argc + 1) * sizeof(char*)));
+ StringSeq::iterator p;
+ int i;
+ for (p = args.begin(), i = 1; p != args.end(); ++p, ++i)
+ {
+ assert(i < argc);
+ argv[i] = strdup(p->c_str());
+ }
+ assert(i == argc);
+ argv[0] = strdup(path.c_str());
+ argv[argc] = 0;
+
+ //
+ // Try to start the router.
+ //
+ if (execvp(argv[0], argv) == -1)
+ {
//
- // Try to start the router.
+ // Send any errors to the parent process, using the write
+ // end of the pipe.
//
- if (execvp(argv[0], argv) == -1)
- {
- //
- // Send any errors to the parent process, using the write
- // end of the pipe.
- //
- ostringstream s;
- s << "can't execute `" << argv[0] << "': " << strerror(errno);
- write(fds[1], s.str().c_str(), s.str().length());
- close(fds[1]);
- exit(EXIT_FAILURE);
- }
+ string msg = "can't execute `" + path + "': " + strerror(errno);
+ write(fds[1], msg.c_str(), msg.length());
+ close(fds[1]);
+ exit(EXIT_FAILURE);
}
- else // Parent process
+ }
+ else // Parent process
+ {
+ try
{
//
// Close the write side of the newly created pipe
@@ -136,7 +202,19 @@ Glacier::StarterI::startRouter(const string& userId, const string& password, con
FD_ZERO(&fdSet);
FD_SET(fds[0], &fdSet);
struct timeval tv;
- tv.tv_sec = 5; // TODO: Property
+ string timeout = _properties->getProperty("Glacier.Starter.StartupTimeout");
+ if (timeout.empty())
+ {
+ tv.tv_sec = 10; // 10 seconds default.
+ }
+ else
+ {
+ tv.tv_sec = atoi(timeout.c_str());
+ if (tv.tv_sec < 1)
+ {
+ tv.tv_sec = 1; // One second is minimum.
+ }
+ }
tv.tv_usec = 0;
int ret = ::select(fds[0] + 1, &fdSet, 0, 0, &tv);
@@ -154,7 +232,9 @@ Glacier::StarterI::startRouter(const string& userId, const string& password, con
if (ret == 0) // Timeout
{
- assert(false); // TODO: Handle this situation.
+ CannotStartRouterException ex;
+ ex.reason = "timeout while starting `" + path + "'";
+ throw ex;
}
assert(FD_ISSET(fds[0], &fdSet));
@@ -162,6 +242,7 @@ Glacier::StarterI::startRouter(const string& userId, const string& password, con
//
// Read the response
//
+ char buf[4*1024];
ssize_t sz = read(fds[0], buf, sizeof(buf)/sizeof(char) - 1);
if(sz == -1)
{
@@ -169,33 +250,63 @@ Glacier::StarterI::startRouter(const string& userId, const string& password, con
ex.error = getSystemErrno();
throw ex;
}
- assert(sz != 0); // TODO: Handle EOF
+
+ if (sz == 0) // EOF?
+ {
+ CannotStartRouterException ex;
+ ex.reason = "got EOF from `" + path + "'";
+ throw ex;
+ }
+
buf[sz] = '\0'; // Terminate the string we got back.
+
+ if (strncmp(buf, uuid.c_str(), uuid.length()) == 0)
+ {
+ //
+ // We got the stringified router proxy.
+ //
+ RouterPrx router = RouterPrx::uncheckedCast(_communicator->stringToProxy(buf));
+
+ if (_traceLevel >= 2)
+ {
+ ostringstream s;
+ s << "started new router:\n" << _communicator->proxyToString(router);
+ _logger->trace("Glacier", s.str());
+ }
+
+ return router;
+ }
+ else
+ {
+ //
+ // We got something else.
+ //
+ CannotStartRouterException ex;
+ ex.reason = buf;
+ throw ex;
+ }
}
- }
- catch(const LocalException& ex)
- {
- // TODO: Log exception or print warning
- cerr << ex << endl;
- ex.ice_throw();
- }
+ catch(const CannotStartRouterException& ex)
+ {
+ if (_traceLevel >= 1)
+ {
+ ostringstream s;
+ s << "router starter exception:\n" << ex << ":\n" << ex.reason;
+ _logger->trace("Glacier", s.str());
+ }
+
+ ex.ice_throw();
+ }
+ catch(const Exception& ex)
+ {
+ ostringstream s;
+ s << ex;
+ _logger->error(s.str());
- if (strncmp(buf, uuid.c_str(), uuid.length()) == 0)
- {
- //
- // We got the stringified router proxy.
- //
- return RouterPrx::uncheckedCast(_communicator->stringToProxy(buf));
- }
- else
- {
- //
- // We got something else.
- //
- CannotStartRouterException ex;
- ex.reason = buf;
- // TODO: Log exception.
- cerr << ex << endl;
- throw ex;
+ ex.ice_throw();
+ }
}
+
+ assert(false); // Should never be reached.
+ return 0; // To keep the compiler from complaining.
}
diff --git a/cpp/src/Glacier/GlacierI.h b/cpp/src/Glacier/GlacierI.h
index 34bbddb26be..f28d542f560 100644
--- a/cpp/src/Glacier/GlacierI.h
+++ b/cpp/src/Glacier/GlacierI.h
@@ -23,11 +23,16 @@ public:
StarterI(const Ice::CommunicatorPtr&);
+ void destroy();
+
Ice::RouterPrx startRouter(const std::string&, const std::string&, const Ice::Current&);
private:
Ice::CommunicatorPtr _communicator;
+ Ice::LoggerPtr _logger;
+ Ice::PropertiesPtr _properties;
+ int _traceLevel;
};
}
diff --git a/cpp/src/Glacier/GlacierRouter.cpp b/cpp/src/Glacier/GlacierRouter.cpp
index 887fc2c3b2d..353bb50c300 100644
--- a/cpp/src/Glacier/GlacierRouter.cpp
+++ b/cpp/src/Glacier/GlacierRouter.cpp
@@ -206,6 +206,15 @@ Glacier::Router::run(int argc, char* argv[])
{
cerr << appName() << ": cannot write stringified router proxy to filedescriptor " << fd << ": "
<< strerror(errno) << endl;
+
+ //
+ // Destroy the router. The client and server blobjects get
+ // destroyed by ServantLocator::deactivate.
+ //
+ RouterI* rtr = dynamic_cast<RouterI*>(router.get());
+ assert(rtr);
+ rtr->destroy();
+
return EXIT_FAILURE;
}
close(fd);
diff --git a/cpp/src/Glacier/GlacierStarter.cpp b/cpp/src/Glacier/GlacierStarter.cpp
index ea00a323196..4f0280e167c 100644
--- a/cpp/src/Glacier/GlacierStarter.cpp
+++ b/cpp/src/Glacier/GlacierStarter.cpp
@@ -85,6 +85,14 @@ Glacier::Router::run(int argc, char* argv[])
// We're done, let's wait for shutdown.
//
communicator()->waitForShutdown();
+
+ //
+ // Destroy the starter.
+ //
+ StarterI* st = dynamic_cast<StarterI*>(starter.get());
+ assert(st);
+ st->destroy();
+
return EXIT_SUCCESS;
}
diff --git a/cpp/src/Glacier/RouterI.cpp b/cpp/src/Glacier/RouterI.cpp
index a4cb32406f0..96b8fb03ab6 100644
--- a/cpp/src/Glacier/RouterI.cpp
+++ b/cpp/src/Glacier/RouterI.cpp
@@ -35,8 +35,10 @@ Glacier::RouterI::~RouterI()
void
Glacier::RouterI::destroy()
{
+ //
// No mutex protection necessary, destroy is only called after all
// object adapters have shut down.
+ //
_clientAdapter = 0;
_serverAdapter = 0;
_logger = 0;
@@ -74,8 +76,7 @@ Glacier::RouterI::addProxy(const ObjectPrx& proxy, const Current&)
if (_routingTableTraceLevel)
{
ostringstream s;
- s << "adding proxy to routing table:\n"
- << _clientAdapter->getCommunicator()->proxyToString(proxy);
+ s << "adding proxy to routing table:\n" << _clientAdapter->getCommunicator()->proxyToString(proxy);
_logger->trace("Glacier", s.str());
}
diff --git a/cpp/src/Glacier/ServerBlobject.cpp b/cpp/src/Glacier/ServerBlobject.cpp
index 16d3ae71c01..785191963f6 100644
--- a/cpp/src/Glacier/ServerBlobject.cpp
+++ b/cpp/src/Glacier/ServerBlobject.cpp
@@ -31,8 +31,10 @@ Glacier::ServerBlobject::~ServerBlobject()
void
Glacier::ServerBlobject::destroy()
{
+ //
// No mutex protection necessary, destroy is only called after all
// object adapters have shut down.
+ //
_clientAdapter = 0;
_logger = 0;
}
diff --git a/cpp/src/Ice/PropertiesI.cpp b/cpp/src/Ice/PropertiesI.cpp
index 06e13051d4e..96dc5cf9cb4 100644
--- a/cpp/src/Ice/PropertiesI.cpp
+++ b/cpp/src/Ice/PropertiesI.cpp
@@ -198,7 +198,7 @@ Ice::PropertiesI::parse(istream& in)
void
Ice::PropertiesI::parseLine(const string& line)
{
- const string delim = " \t";
+ static const string delim = " \t\r\n";
string s = line;
string::size_type idx = s.find('#');