diff options
author | Dwayne Boone <dwayne@zeroc.com> | 2009-10-02 09:35:28 -0230 |
---|---|---|
committer | Dwayne Boone <dwayne@zeroc.com> | 2009-10-02 09:35:28 -0230 |
commit | 6d8d16b3761eaa24c9c754dd0f2cc1a70de8fad0 (patch) | |
tree | ff37056717cff166bc705112f54e98074f8d1f40 /cpp/src/IcePatch2/ClientUtil.cpp | |
parent | 3772. Recovering from Glacier2 / Ice router session failure. (diff) | |
download | ice-6d8d16b3761eaa24c9c754dd0f2cc1a70de8fad0.tar.bz2 ice-6d8d16b3761eaa24c9c754dd0f2cc1a70de8fad0.tar.xz ice-6d8d16b3761eaa24c9c754dd0f2cc1a70de8fad0.zip |
C++Builder 2010 support
Diffstat (limited to 'cpp/src/IcePatch2/ClientUtil.cpp')
-rw-r--r-- | cpp/src/IcePatch2/ClientUtil.cpp | 1018 |
1 files changed, 0 insertions, 1018 deletions
diff --git a/cpp/src/IcePatch2/ClientUtil.cpp b/cpp/src/IcePatch2/ClientUtil.cpp deleted file mode 100644 index d5f13208698..00000000000 --- a/cpp/src/IcePatch2/ClientUtil.cpp +++ /dev/null @@ -1,1018 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#include <IceUtil/Unicode.h> -#include <IceUtil/StringUtil.h> -#include <IceUtil/FileUtil.h> -#define ICE_PATCH2_API_EXPORTS -#include <IcePatch2/ClientUtil.h> -#include <IcePatch2/Util.h> -#include <IcePatch2/FileServerI.h> -#include <list> - -#ifdef __BCPLUSPLUS__ -# include <iterator> -#endif - -using namespace std; -using namespace Ice; -using namespace IcePatch2; - -namespace IcePatch2 -{ - -class Decompressor : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex> -{ -public: - - Decompressor(const string& dataDir) : - _dataDir(dataDir), - _destroy(false) - { - } - - virtual ~Decompressor() - { - assert(_destroy); - } - - void - destroy() - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - _destroy = true; - notify(); - } - - void - add(const FileInfo& info) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - if(!_exception.empty()) - { - throw _exception; - } - _files.push_back(info); - notify(); - } - - void - exception() const - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - if(!_exception.empty()) - { - throw _exception; - } - } - - void - log(FILE* fp) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - for(FileInfoSeq::const_iterator p = _filesDone.begin(); p != _filesDone.end(); ++p) - { - if(fputc('+', fp) == EOF || !writeFileInfo(fp, *p)) - { - throw "error writing log file:\n" + IceUtilInternal::lastErrorToString(); - } - } - - _filesDone.clear(); - } - - virtual void - run() - { - FileInfo info; - - while(true) - { - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - if(!info.path.empty()) - { - _filesDone.push_back(info); - } - - while(!_destroy && _files.empty()) - { - wait(); - } - - if(!_files.empty()) - { - info = _files.front(); - _files.pop_front(); - } - else - { - return; - } - } - - try - { - decompressFile(_dataDir + '/' + info.path); - setFileFlags(_dataDir + '/' + info.path, info); - remove(_dataDir + '/' + info.path + ".bz2"); - } - catch(const string& ex) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - _destroy = true; - _exception = ex; - return; - } - } - } - -private: - - const string _dataDir; - - string _exception; - list<FileInfo> _files; - FileInfoSeq _filesDone; - - bool _destroy; -}; - -} - -IcePatch2::Patcher::Patcher(const CommunicatorPtr& communicator, const PatcherFeedbackPtr& feedback) : - _feedback(feedback), - _dataDir(simplify(communicator->getProperties()->getPropertyWithDefault("IcePatch2.Directory", "."))), - _thorough(communicator->getProperties()->getPropertyAsInt("IcePatch2.Thorough") > 0), - _chunkSize(communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2.ChunkSize", 100)), - _remove(communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2.Remove", 1)), - _log(0) -{ - PropertiesPtr properties = communicator->getProperties(); - - const char* endpointsProperty = "IcePatch2.Endpoints"; - string endpoints = properties->getProperty(endpointsProperty); - if(endpoints.empty()) - { - throw string("property `") + endpointsProperty + "' is not set"; - } - - Identity id; - id.category = properties->getPropertyWithDefault("IcePatch2.InstanceName", "IcePatch2"); - id.name = "server"; - - ObjectPrx serverBase = communicator->stringToProxy("\"" + communicator->identityToString(id) + "\" :" + endpoints); - FileServerPrx server = FileServerPrx::checkedCast(serverBase); - if(!server) - { - throw "proxy `" + communicator->identityToString(id) + ':' + endpoints + "' is not a file server."; - } - - init(server); -} - -IcePatch2::Patcher::Patcher(const FileServerPrx& server, - const PatcherFeedbackPtr& feedback, - const string& dataDir, - bool thorough, - Ice::Int chunkSize, - Ice::Int remove) : - _feedback(feedback), - _dataDir(simplify(dataDir)), - _thorough(thorough), - _chunkSize(chunkSize), - _remove(remove) -{ - init(server); -} - -IcePatch2::Patcher::~Patcher() -{ -} - -namespace -{ - -class PatcherGetFileInfoSeqCB : public GetFileInfoSeqCB -{ -public: - - PatcherGetFileInfoSeqCB(const PatcherFeedbackPtr& feedback) : - _feedback(feedback) - { - } - - virtual bool - remove(const string&) - { - return true; - } - - virtual bool - checksum(const string& path) - { - return _feedback->checksumProgress(path); - } - - virtual bool compress(const string&) - { - assert(false); // Nothing must get compressed when we are patching. - return true; - } - -private: - - const PatcherFeedbackPtr _feedback; -}; - -class AMIGetFileInfoSeq : public AMI_FileServer_getFileInfoSeq, public IceUtil::Monitor<IceUtil::Mutex> -{ -public: - - AMIGetFileInfoSeq() : - _done(false) - { - } - - FileInfoSeq - getFileInfoSeq() - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - while(!_done) - { - wait(); - } - - _done = false; - - if(_exception.get()) - { - auto_ptr<Exception> ex = _exception; - _fileInfoSeq.clear(); - ex->ice_throw(); - } - - FileInfoSeq fileInfoSeq; - fileInfoSeq.swap(_fileInfoSeq); - return fileInfoSeq; - } - - virtual void - ice_response(const FileInfoSeq& fileInfoSeq) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - _fileInfoSeq = fileInfoSeq; - _done = true; - notify(); - } - - virtual void - ice_exception(const Exception& ex) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - _exception.reset(ex.ice_clone()); - _done = true; - notify(); - } - -private: - - bool _done; - FileInfoSeq _fileInfoSeq; - auto_ptr<Exception> _exception; -}; - -typedef IceUtil::Handle<AMIGetFileInfoSeq> AMIGetFileInfoSeqPtr; - -} - -bool -IcePatch2::Patcher::prepare() -{ - _localFiles.clear(); - - bool thorough = _thorough; - - if(!thorough) - { - try - { - loadFileInfoSeq(_dataDir, _localFiles); - } - catch(const string& ex) - { - thorough = _feedback->noFileSummary(ex); - if(!thorough) - { - return false; - } - } - } - - if(thorough) - { - if(!_feedback->checksumStart()) - { - return false; - } - - PatcherGetFileInfoSeqCB cb(_feedback); - if(!getFileInfoSeq(_dataDir, 0, &cb, _localFiles)) - { - return false; - } - - if(!_feedback->checksumEnd()) - { - return false; - } - - saveFileInfoSeq(_dataDir, _localFiles); - } - - FileTree0 tree0; - getFileTree0(_localFiles, tree0); - - if(tree0.checksum != _serverCompress->getChecksum()) - { - if(!_feedback->fileListStart()) - { - return false; - } - - ByteSeqSeq checksumSeq = _serverCompress->getChecksumSeq(); - if(checksumSeq.size() != 256) - { - throw string("server returned illegal value"); - } - - AMIGetFileInfoSeqPtr curCB; - AMIGetFileInfoSeqPtr nxtCB; - - for(int node0 = 0; node0 < 256; ++node0) - { - if(tree0.nodes[node0].checksum != checksumSeq[node0]) - { - if(!curCB) - { - assert(!nxtCB); - curCB = new AMIGetFileInfoSeq; - nxtCB = new AMIGetFileInfoSeq; - _serverCompress->getFileInfoSeq_async(curCB, node0); - } - else - { - assert(nxtCB); - swap(nxtCB, curCB); - } - - int node0Nxt = node0; - - do - { - ++node0Nxt; - } - while(node0Nxt < 256 && tree0.nodes[node0Nxt].checksum == checksumSeq[node0Nxt]); - - if(node0Nxt < 256) - { - _serverCompress->getFileInfoSeq_async(nxtCB, node0Nxt); - } - - FileInfoSeq files = curCB->getFileInfoSeq(); - - sort(files.begin(), files.end(), FileInfoLess()); - files.erase(unique(files.begin(), files.end(), FileInfoEqual()), files.end()); - - // - // Compute the set of files which were removed. - // - set_difference(tree0.nodes[node0].files.begin(), - tree0.nodes[node0].files.end(), - files.begin(), - files.end(), - back_inserter(_removeFiles), - FileInfoWithoutFlagsLess()); // NOTE: We ignore the flags here. - - // - // Compute the set of files which were updated (either the file contents, flags or both). - // - FileInfoSeq updatedFiles; - updatedFiles.reserve(files.size()); - - set_difference(files.begin(), - files.end(), - tree0.nodes[node0].files.begin(), - tree0.nodes[node0].files.end(), - back_inserter(updatedFiles), - FileInfoLess()); - - // - // Compute the set of files whose contents was updated. - // - FileInfoSeq contentsUpdatedFiles; - contentsUpdatedFiles.reserve(files.size()); - - set_difference(files.begin(), - files.end(), - tree0.nodes[node0].files.begin(), - tree0.nodes[node0].files.end(), - back_inserter(contentsUpdatedFiles), - FileInfoWithoutFlagsLess()); // NOTE: We ignore the flags here. - copy(contentsUpdatedFiles.begin(), contentsUpdatedFiles.end(), back_inserter(_updateFiles)); - - // - // Compute the set of files whose flags were updated. - // - set_difference(updatedFiles.begin(), - updatedFiles.end(), - contentsUpdatedFiles.begin(), - contentsUpdatedFiles.end(), - back_inserter(_updateFlags), - FileInfoLess()); - } - - if(!_feedback->fileListProgress((node0 + 1) * 100 / 256)) - { - return false; - } - } - - if(!_feedback->fileListEnd()) - { - return false; - } - } - - sort(_removeFiles.begin(), _removeFiles.end(), FileInfoLess()); - sort(_updateFiles.begin(), _updateFiles.end(), FileInfoLess()); - sort(_updateFlags.begin(), _updateFlags.end(), FileInfoLess()); - - string pathLog = simplify(_dataDir + '/' + logFile); - _log = IceUtilInternal::fopen(pathLog, "w"); - if(!_log) - { - throw "cannot open `" + pathLog + "' for writing:\n" + IceUtilInternal::lastErrorToString(); - } - - return true; -} - -bool -IcePatch2::Patcher::patch(const string& d) -{ - string dir = simplify(d); - - if(dir.empty() || dir == ".") - { - if(!_removeFiles.empty()) - { - if(!removeFiles(_removeFiles)) - { - return false; - } - } - - if(!_updateFiles.empty()) - { - if(!updateFiles(_updateFiles)) - { - return false; - } - } - - if(!_updateFlags.empty()) - { - if(!updateFlags(_updateFlags)) - { - return false; - } - } - - return true; - } - else - { - string dirWithSlash = simplify(dir + '/'); - - FileInfoSeq::const_iterator p; - - FileInfoSeq remove; - for(p = _removeFiles.begin(); p != _removeFiles.end(); ++p) - { - if(p->path == dir) - { - remove.push_back(*p); - } - else if(p->path.compare(0, dirWithSlash.size(), dirWithSlash) == 0) - { - remove.push_back(*p); - } - } - - FileInfoSeq update; - for(p = _updateFiles.begin(); p != _updateFiles.end(); ++p) - { - if(p->path == dir) - { - update.push_back(*p); - } - else if(p->path.compare(0, dirWithSlash.size(), dirWithSlash) == 0) - { - update.push_back(*p); - } - } - - FileInfoSeq updateFlag; - for(p = _updateFlags.begin(); p != _updateFlags.end(); ++p) - { - if(p->path == dir) - { - updateFlag.push_back(*p); - } - else if(p->path.compare(0, dirWithSlash.size(), dirWithSlash) == 0) - { - updateFlag.push_back(*p); - } - } - - if(!remove.empty()) - { - if(!removeFiles(remove)) - { - return false; - } - } - - if(!update.empty()) - { - if(!updateFiles(update)) - { - return false; - } - } - - if(!updateFlag.empty()) - { - if(!updateFlags(updateFlag)) - { - return false; - } - } - - return true; - } -} - -void -IcePatch2::Patcher::finish() -{ - if(_log != 0) - { - fclose(_log); - _log = 0; - } - - saveFileInfoSeq(_dataDir, _localFiles); -} - -void -IcePatch2::Patcher::init(const FileServerPrx& server) -{ - if(_dataDir.empty()) - { - throw string("no data directory specified"); - } - - // - // Make sure that _chunkSize doesn't exceed MessageSizeMax, otherwise - // it won't work at all. - // - int sizeMax = - server->ice_getCommunicator()->getProperties()->getPropertyAsIntWithDefault("Ice.MessageSizeMax", 1024); - if(_chunkSize < 1) - { - const_cast<Int&>(_chunkSize) = 1; - } - else if(_chunkSize > sizeMax) - { - const_cast<Int&>(_chunkSize) = sizeMax; - } - if(_chunkSize == sizeMax) - { - const_cast<Int&>(_chunkSize) = _chunkSize * 1024 - 512; // Leave some headroom for protocol header. - } - else - { - const_cast<Int&>(_chunkSize) *= 1024; - } - - if(!IceUtilInternal::isAbsolutePath(_dataDir)) - { - string cwd; - if(IceUtilInternal::getcwd(cwd) != 0) - { - throw "cannot get the current directory:\n" + IceUtilInternal::lastErrorToString(); - } - const_cast<string&>(_dataDir) = simplify(cwd + '/' + _dataDir); - } - - const_cast<FileServerPrx&>(_serverCompress) = FileServerPrx::uncheckedCast(server->ice_compress(true)); - const_cast<FileServerPrx&>(_serverNoCompress) = FileServerPrx::uncheckedCast(server->ice_compress(false)); -} - -bool -IcePatch2::Patcher::removeFiles(const FileInfoSeq& files) -{ - if(_remove < 1) - { - return true; - } - - for(FileInfoSeq::const_reverse_iterator p = files.rbegin(); p != files.rend(); ++p) - { - try - { - remove(_dataDir + '/' + p->path); - if(fputc('-', _log) == EOF || ! writeFileInfo(_log, *p)) - { - throw "error writing log file:\n" + IceUtilInternal::lastErrorToString(); - } - } - catch(...) - { - if(_remove < 2) // We ignore errors if IcePatch2.Remove >= 2. - { - throw; - } - } - } - - FileInfoSeq newLocalFiles; - newLocalFiles.reserve(_localFiles.size()); - - set_difference(_localFiles.begin(), - _localFiles.end(), - files.begin(), - files.end(), - back_inserter(newLocalFiles), - FileInfoLess()); - - _localFiles.swap(newLocalFiles); - - FileInfoSeq newRemoveFiles; - - set_difference(_removeFiles.begin(), - _removeFiles.end(), - files.begin(), - files.end(), - back_inserter(newRemoveFiles), - FileInfoLess()); - - _removeFiles.swap(newRemoveFiles); - - return true; -} - -bool -IcePatch2::Patcher::updateFiles(const FileInfoSeq& files) -{ - DecompressorPtr decompressor = new Decompressor(_dataDir); -#if defined(__hppa) - // - // The thread stack size is only 64KB only HP-UX and that's not - // enough for this thread. - // - decompressor->start(256 * 1024); // 256KB -#else - decompressor->start(); -#endif - bool result; - - try - { - result = updateFilesInternal(files, decompressor); - } - catch(...) - { - decompressor->destroy(); - decompressor->getThreadControl().join(); - decompressor->log(_log); - throw; - } - - decompressor->destroy(); - decompressor->getThreadControl().join(); - decompressor->log(_log); - decompressor->exception(); - - return result; -} - -namespace -{ - -class AMIGetFileCompressed : public AMI_FileServer_getFileCompressed, public IceUtil::Monitor<IceUtil::Mutex> -{ -public: - - AMIGetFileCompressed() : - _done(false) - { - } - - ByteSeq - getFileCompressed() - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - while(!_done) - { - wait(); - } - - _done = false; - - if(_exception.get()) - { - auto_ptr<Exception> ex = _exception; - _bytes.clear(); - ex->ice_throw(); - } - - ByteSeq bytes; - bytes.swap(_bytes); - return bytes; - } - - virtual void - ice_response(const pair<const Ice::Byte*, const Ice::Byte*>& bytes) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - ByteSeq(bytes.first, bytes.second).swap(_bytes); - _done = true; - notify(); - } - - virtual void - ice_exception(const Exception& ex) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - _exception.reset(ex.ice_clone()); - _done = true; - notify(); - } - -private: - - bool _done; - ByteSeq _bytes; - auto_ptr<Exception> _exception; -}; - -typedef IceUtil::Handle<AMIGetFileCompressed> AMIGetFileCompressedPtr; - -} - -bool -IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const DecompressorPtr& decompressor) -{ - FileInfoSeq::const_iterator p; - - Long total = 0; - Long updated = 0; - - for(p = files.begin(); p != files.end(); ++p) - { - if(p->size > 0) // Regular, non-empty file? - { - total += p->size; - } - } - - AMIGetFileCompressedPtr curCB; - AMIGetFileCompressedPtr nxtCB; - - for(p = files.begin(); p != files.end(); ++p) - { - if(p->size < 0) // Directory? - { - createDirectoryRecursive(_dataDir + '/' + p->path); - if(fputc('+', _log) == EOF || !writeFileInfo(_log, *p)) - { - throw "error writing log file:\n" + IceUtilInternal::lastErrorToString(); - } - } - else // Regular file. - { - if(!_feedback->patchStart(p->path, p->size, updated, total)) - { - return false; - } - - if(p->size == 0) - { - string path = simplify(_dataDir + '/' + p->path); - FILE* fp = IceUtilInternal::fopen(path, "wb"); - if(fp == 0) - { - throw "cannot open `" + path +"' for writing:\n" + IceUtilInternal::lastErrorToString(); - } - fclose(fp); - } - else - { - string pathBZ2 = simplify(_dataDir + '/' + p->path + ".bz2"); - - string dir = getDirname(pathBZ2); - if(!dir.empty()) - { - createDirectoryRecursive(dir); - } - - try - { - removeRecursive(pathBZ2); - } - catch(...) - { - } - - FILE* fileBZ2 = IceUtilInternal::fopen(pathBZ2, "wb"); - if(fileBZ2 == 0) - { - throw "cannot open `" + pathBZ2 + "' for writing:\n" + IceUtilInternal::lastErrorToString(); - } - - try - { - Int pos = 0; - - while(pos < p->size) - { - if(!curCB) - { - assert(!nxtCB); - curCB = new AMIGetFileCompressed; - nxtCB = new AMIGetFileCompressed; - _serverNoCompress->getFileCompressed_async(curCB, p->path, pos, _chunkSize); - } - else - { - assert(nxtCB); - swap(nxtCB, curCB); - } - - if(pos + _chunkSize < p->size) - { - _serverNoCompress->getFileCompressed_async(nxtCB, p->path, pos + _chunkSize, _chunkSize); - } - else - { - FileInfoSeq::const_iterator q = p + 1; - - while(q != files.end() && q->size <= 0) - { - ++q; - } - - if(q != files.end()) - { - _serverNoCompress->getFileCompressed_async(nxtCB, q->path, 0, _chunkSize); - } - } - - ByteSeq bytes; - - try - { - bytes = curCB->getFileCompressed(); - } - catch(const FileAccessException& ex) - { - throw "error from IcePatch2 server for `" + p->path + "': " + ex.reason; - } - - if(bytes.empty()) - { - throw "size mismatch for `" + p->path + "'"; - } - - if(fwrite(reinterpret_cast<char*>(&bytes[0]), bytes.size(), 1, fileBZ2) != 1) - { - throw ": cannot write `" + pathBZ2 + "':\n" + IceUtilInternal::lastErrorToString(); - } - - pos += static_cast<int>(bytes.size()); - updated += bytes.size(); - - if(!_feedback->patchProgress(pos, p->size, updated, total)) - { - fclose(fileBZ2); - return false; - } - } - } - catch(...) - { - fclose(fileBZ2); - throw; - } - - fclose(fileBZ2); - - decompressor->log(_log); - decompressor->add(*p); - } - - if(!_feedback->patchEnd()) - { - return false; - } - } - } - - FileInfoSeq newLocalFiles; - newLocalFiles.reserve(_localFiles.size()); - - set_union(_localFiles.begin(), - _localFiles.end(), - files.begin(), - files.end(), - back_inserter(newLocalFiles), - FileInfoLess()); - - _localFiles.swap(newLocalFiles); - - FileInfoSeq newUpdateFiles; - - set_difference(_updateFiles.begin(), - _updateFiles.end(), - files.begin(), - files.end(), - back_inserter(newUpdateFiles), - FileInfoLess()); - - _updateFiles.swap(newUpdateFiles); - - return true; -} - -bool -IcePatch2::Patcher::updateFlags(const FileInfoSeq& files) -{ - for(FileInfoSeq::const_iterator p = files.begin(); p != files.end(); ++p) - { - if(p->size >= 0) // Regular file? - { - setFileFlags(_dataDir + '/' + p->path, *p); - } - } - - // - // Remove the old files whose flags were updated from the set of - // local files. - // - FileInfoSeq localFiles; - localFiles.reserve(_localFiles.size()); - set_difference(_localFiles.begin(), - _localFiles.end(), - files.begin(), - files.end(), - back_inserter(localFiles), - FileInfoWithoutFlagsLess()); // NOTE: We ignore the flags. - - // - // Add the new files to the set of local file. - // - _localFiles.clear(); - set_union(localFiles.begin(), - localFiles.end(), - files.begin(), - files.end(), - back_inserter(_localFiles), - FileInfoLess()); - - FileInfoSeq newUpdateFlags; - - set_difference(_updateFlags.begin(), - _updateFlags.end(), - files.begin(), - files.end(), - back_inserter(newUpdateFlags), - FileInfoLess()); - - _updateFlags.swap(newUpdateFlags); - - return true; -} - |