diff options
Diffstat (limited to 'cpp/src/IcePatch/Server.cpp')
-rw-r--r-- | cpp/src/IcePatch/Server.cpp | 224 |
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); } |