summaryrefslogtreecommitdiff
path: root/cpp/src/IcePatch/Server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IcePatch/Server.cpp')
-rw-r--r--cpp/src/IcePatch/Server.cpp224
1 files changed, 128 insertions, 96 deletions
diff --git a/cpp/src/IcePatch/Server.cpp b/cpp/src/IcePatch/Server.cpp
index ef4def210db..bfee1efefda 100644
--- a/cpp/src/IcePatch/Server.cpp
+++ b/cpp/src/IcePatch/Server.cpp
@@ -13,9 +13,10 @@
// **********************************************************************
#include <IceUtil/IceUtil.h>
-#include <Ice/Application.h>
+#include <Ice/Service.h>
#include <IcePatch/FileLocator.h>
#include <IcePatch/IcePatchI.h>
+#include <IcePatch/Util.h>
using namespace std;
using namespace Ice;
@@ -24,41 +25,57 @@ using namespace IcePatch;
namespace IcePatch
{
-class Server : public Application
+class IcePatchService : public Service
{
public:
- void usage();
- virtual int run(int, char*[]);
-};
+ IcePatchService();
-class Updater : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex>
-{
-public:
+ void usage(const string&);
- Updater(const ObjectAdapterPtr&, const IceUtil::Time&);
+protected:
- virtual void run();
- void destroy();
+ virtual bool start(int, char*[]);
+ virtual bool stop();
-protected:
+private:
- const ObjectAdapterPtr _adapter;
- const LoggerPtr _logger;
- const IceUtil::Time _updatePeriod;
- bool _destroy;
+ void runUpdater();
+ void cleanup();
+ void cleanupRec(const FileDescSeq&);
- void cleanup(const FileDescSeq&);
-};
+ IceUtil::Monitor<IceUtil::Mutex> _monitor;
+ IceUtil::ThreadPtr _thread;
+ bool _shutdown;
+ ObjectAdapterPtr _adapter;
+ IceUtil::Time _updatePeriod;
+
+ class UpdaterThread : public IceUtil::Thread
+ {
+ public:
+
+ UpdaterThread(IcePatchService*);
-typedef IceUtil::Handle<Updater> UpdaterPtr;
+ virtual void run();
+ protected:
+
+ IcePatchService* _service;
+ };
+ friend class UpdaterThread;
};
+}
+
+IcePatch::IcePatchService::IcePatchService() :
+ _shutdown(false)
+{
+}
+
void
-IcePatch::Server::usage()
+IcePatch::IcePatchService::usage(const string& name)
{
- cerr << "Usage: " << appName() << " [options]\n";
+ cerr << "Usage: " << name << " [options]\n";
cerr <<
"Options:\n"
"-h, --help Show this message.\n"
@@ -66,115 +83,112 @@ IcePatch::Server::usage()
;
}
-int
-IcePatch::Server::run(int argc, char* argv[])
+bool
+IcePatch::IcePatchService::start(int argc, char* argv[])
{
for(int i = 1; i < argc; ++i)
{
if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
{
- usage();
- return EXIT_SUCCESS;
+ usage(argv[0]);
+ return false;
}
else if(strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0)
{
- cout << ICE_STRING_VERSION << endl;
- return EXIT_SUCCESS;
+ trace(ICE_STRING_VERSION);
+ return false;
}
else
{
- cerr << appName() << ": unknown option `" << argv[i] << "'" << endl;
- usage();
- return EXIT_FAILURE;
+ error(string(argv[0]) + ": unknown option `" + string(argv[i]) + "'");
+ usage(argv[0]);
+ return false;
}
}
-
+
PropertiesPtr properties = communicator()->getProperties();
-
+
//
// Get the IcePatch endpoints.
//
const char* endpointsProperty = "IcePatch.Endpoints";
if(properties->getProperty(endpointsProperty).empty())
{
- cerr << appName() << ": property `" << endpointsProperty << "' is not set" << endl;
- return EXIT_FAILURE;
+ error(string(argv[0]) + ": property `" + endpointsProperty + "' is not set");
+ return false;
}
-
+
//
// Create and initialize the object adapter and the file locator.
//
- ObjectAdapterPtr adapter = communicator()->createObjectAdapter("IcePatch");
- ServantLocatorPtr fileLocator = new FileLocator(adapter);
- adapter->addServantLocator(fileLocator, "IcePatch");
+ string dataDir = properties->getProperty("IcePatch.Directory");
+ if(dataDir.empty())
+ {
+#ifdef _WIN32
+ char cwd[_MAX_PATH];
+ _getcwd(cwd, _MAX_PATH);
+#else
+ char cwd[PATH_MAX];
+ getcwd(cwd, PATH_MAX);
+#endif
+ dataDir = cwd;
+ }
+ _adapter = communicator()->createObjectAdapter("IcePatch");
+ ServantLocatorPtr fileLocator = new FileLocator(_adapter, dataDir);
+ _adapter->addServantLocator(fileLocator, "IcePatch");
//
- // Start the updater if an update period is set.
+ // Start the updater thread if an update period is set.
//
- UpdaterPtr updater;
- IceUtil::Time updatePeriod = IceUtil::Time::seconds(
- properties->getPropertyAsIntWithDefault("IcePatch.UpdatePeriod", 60));
- if(updatePeriod != IceUtil::Time())
+ _updatePeriod = IceUtil::Time::seconds(properties->getPropertyAsIntWithDefault("IcePatch.UpdatePeriod", 60));
+ if(_updatePeriod != IceUtil::Time())
{
- if(updatePeriod < IceUtil::Time::seconds(1))
+ if(_updatePeriod < IceUtil::Time::seconds(1))
{
- updatePeriod = IceUtil::Time::seconds(1);
+ _updatePeriod = IceUtil::Time::seconds(1);
}
- updater = new Updater(adapter, updatePeriod);
- updater->start();
+ _thread = new UpdaterThread(this);
+ _thread->start();
}
//
// Everything ok, let's go.
//
- shutdownOnInterrupt();
- adapter->activate();
- communicator()->waitForShutdown();
- ignoreInterrupt();
+ _adapter->activate();
- //
- // Destroy and join with the updater, if there is one.
- //
- if(updater)
- {
- updater->destroy();
- updater->getThreadControl().join();
- }
-
- return EXIT_SUCCESS;
+ return true;
}
-IcePatch::Updater::Updater(const ObjectAdapterPtr& adapter, const IceUtil::Time& updatePeriod) :
- _adapter(adapter),
- _logger(_adapter->getCommunicator()->getLogger()),
- _updatePeriod(updatePeriod),
- _destroy(false)
+bool
+IcePatch::IcePatchService::stop()
{
+ if(_thread)
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor);
+ _shutdown = true;
+ _monitor.notify();
+ _thread->getThreadControl().join();
+ _thread = 0;
+ }
+ return true;
}
void
-IcePatch::Updater::run()
+IcePatch::IcePatchService::runUpdater()
{
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor);
- while(!_destroy && !Application::interrupted())
+ while(!_shutdown)
{
try
{
- Identity ident;
- ident.category = "IcePatch";
- ident.name = ".";
- ObjectPrx topObj = _adapter->createProxy(ident);
- FilePrx top = FilePrx::checkedCast(topObj);
- assert(top);
- DirectoryDescPtr topDesc = DirectoryDescPtr::dynamicCast(top->describe());
- assert(topDesc);
- cleanup(topDesc->dir->getContents());
+ cleanup();
}
catch(const FileAccessException& ex)
{
- Error out(_logger);
- out << "exception during update:\n" << ex << ":\n" << ex.reason;
+ ostringstream ostr;
+ ostr << "exception during update:\n" << ex << ":\n" << ex.reason;
+ error(ostr.str());
}
catch(const BusyException&)
{
@@ -185,39 +199,46 @@ IcePatch::Updater::run()
catch(const Exception& ex)
{
//
- // Log other exceptions only if we are not destroyed and
- // if we were not interrupted.
+ // Log other exceptions only if we are not destroyed.
//
- if(!_destroy && !Application::interrupted())
+ if(!_shutdown)
{
- Error out(_logger);
- out << "exception during update:\n" << ex;
+ ostringstream ostr;
+ ostr << "exception during update:\n" << ex;
+ error(ostr.str());
}
}
- if(_destroy || Application::interrupted())
+ if(_shutdown)
{
break;
}
- timedWait(_updatePeriod);
+ _monitor.timedWait(_updatePeriod);
}
}
void
-IcePatch::Updater::destroy()
+IcePatch::IcePatchService::cleanup()
{
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
- _destroy = true;
- notify();
+ Identity ident;
+ ident.category = "IcePatch";
+ ident.name = ".";
+ ObjectPrx topObj = _adapter->createProxy(ident);
+ FilePrx top = FilePrx::checkedCast(topObj);
+ assert(top);
+ DirectoryDescPtr topDesc = DirectoryDescPtr::dynamicCast(top->describe());
+ assert(topDesc);
+ cleanupRec(topDesc->dir->getContents());
+ topDesc->dir->describe(); // Refresh the top-level MD5 file.
}
void
-IcePatch::Updater::cleanup(const FileDescSeq& fileDescSeq)
+IcePatch::IcePatchService::cleanupRec(const FileDescSeq& fileDescSeq)
{
for(FileDescSeq::const_iterator p = fileDescSeq.begin(); p != fileDescSeq.end(); ++p)
{
- if(_destroy)
+ if(_shutdown)
{
return;
}
@@ -229,7 +250,7 @@ IcePatch::Updater::cleanup(const FileDescSeq& fileDescSeq)
// Force MD5 files to be created and orphaned files to be
// removed. Then recurse into subdirectories.
//
- cleanup(directoryDesc->dir->getContents());
+ cleanupRec(directoryDesc->dir->getContents());
//
// Call describe(), because BZ2 and MD5 files in the
@@ -251,9 +272,20 @@ IcePatch::Updater::cleanup(const FileDescSeq& fileDescSeq)
}
}
+IcePatch::IcePatchService::UpdaterThread::UpdaterThread(IcePatchService* service) :
+ _service(service)
+{
+}
+
+void
+IcePatch::IcePatchService::UpdaterThread::run()
+{
+ _service->runUpdater();
+}
+
int
main(int argc, char* argv[])
{
- Server app;
- return app.main(argc, argv);
+ IcePatchService svc;
+ return svc.main(argc, argv);
}