diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/IcePatch2/Calc.cpp | 5 | ||||
-rw-r--r-- | cpp/src/IcePatch2/Client.cpp | 316 | ||||
-rw-r--r-- | cpp/src/IcePatch2/Server.cpp | 4 | ||||
-rw-r--r-- | cpp/src/IcePatch2/Util.cpp | 277 |
4 files changed, 391 insertions, 211 deletions
diff --git a/cpp/src/IcePatch2/Calc.cpp b/cpp/src/IcePatch2/Calc.cpp index 7b70bb7f7cb..393e9fb5110 100644 --- a/cpp/src/IcePatch2/Calc.cpp +++ b/cpp/src/IcePatch2/Calc.cpp @@ -104,10 +104,7 @@ main(int argc, char* argv[]) FileInfoSeq infoSeq; getFileInfoSeq(".", infoSeq, true, compress, verbose); - - sort(infoSeq.begin(), infoSeq.end(), FileInfoCompare()); - - saveFileInfoSeq(dataDir + ".sum", infoSeq); + saveFileInfoSeq(dataDir, infoSeq); } catch(const string& ex) { diff --git a/cpp/src/IcePatch2/Client.cpp b/cpp/src/IcePatch2/Client.cpp index c5627a191d2..7b1de496c3b 100644 --- a/cpp/src/IcePatch2/Client.cpp +++ b/cpp/src/IcePatch2/Client.cpp @@ -33,6 +33,26 @@ private: }; +class DecompressorDestroyer +{ +public: + + DecompressorDestroyer(DecompressorPtr decompressor) : + _decompressor(decompressor) + { + } + + ~DecompressorDestroyer() + { + _decompressor->destroy(); + _decompressor->getThreadControl().join(); + } + +private: + + const DecompressorPtr _decompressor; +}; + int IcePatch2::Client::run(int argc, char* argv[]) { @@ -126,7 +146,7 @@ IcePatch2::Client::run(int argc, char* argv[]) { try { - loadFileInfoSeq(dataDir + ".sum", infoSeq); + loadFileInfoSeq(dataDir, infoSeq); } catch(const string& ex) { @@ -146,15 +166,13 @@ IcePatch2::Client::run(int argc, char* argv[]) thorough = true; } } - + if(thorough) { getFileInfoSeq(".", infoSeq, false, false, false); - saveFileInfoSeq(dataDir + ".sum", infoSeq); + saveFileInfoSeq(dataDir, infoSeq); } - sort(infoSeq.begin(), infoSeq.end(), FileInfoCompare()); - const char* endpointsProperty = "IcePatch2.Endpoints"; const string endpoints = properties->getProperty(endpointsProperty); if(endpoints.empty()) @@ -201,21 +219,22 @@ IcePatch2::Client::run(int argc, char* argv[]) { FileInfoSeq fileSeq = fileServer->getFileInfo1Seq(node0); - sort(fileSeq.begin(), fileSeq.end(), FileInfoCompare()); + sort(fileSeq.begin(), fileSeq.end(), FileInfoLess()); + fileSeq.erase(unique(fileSeq.begin(), fileSeq.end(), FileInfoEqual()), fileSeq.end()); set_difference(tree0.nodes[node0].files.begin(), tree0.nodes[node0].files.end(), fileSeq.begin(), fileSeq.end(), back_inserter(removeFiles), - FileInfoCompare()); + FileInfoLess()); set_difference(fileSeq.begin(), fileSeq.end(), tree0.nodes[node0].files.begin(), tree0.nodes[node0].files.end(), back_inserter(updateFiles), - FileInfoCompare()); + FileInfoLess()); } for(unsigned int i = 0; i < progress.size(); ++i) @@ -231,172 +250,210 @@ IcePatch2::Client::run(int argc, char* argv[]) cout << endl; - sort(removeFiles.begin(), removeFiles.end(), FileInfoCompare()); - sort(updateFiles.begin(), updateFiles.end(), FileInfoCompare()); + sort(removeFiles.begin(), removeFiles.end(), FileInfoLess()); + sort(updateFiles.begin(), updateFiles.end(), FileInfoLess()); FileInfoSeq::const_iterator p; - p = removeFiles.begin(); - while(p != removeFiles.end()) + if(!removeFiles.empty()) { - cout << "remove: " << p->path << endl; - - if(!dry) + p = removeFiles.begin(); + while(p != removeFiles.end()) { - try + cout << "remove: " << getBasename(p->path) << endl; + + if(!dry) { - removeRecursive(p->path); + try + { + removeRecursive(p->path); + } + catch(const string&) + { + } } - catch(const string&) + + string dir = p->path + '/'; + + do { + ++p; } + while(p != removeFiles.end() && p->path.size() > dir.size() && + p->path.compare(0, dir.size(), dir) == 0); } - string dir = p->path + '/'; - - do + if(!dry) { - ++p; + FileInfoSeq newInfoSeq; + newInfoSeq.reserve(infoSeq.size()); + + set_difference(infoSeq.begin(), + infoSeq.end(), + removeFiles.begin(), + removeFiles.end(), + back_inserter(newInfoSeq), + FileInfoLess()); + + infoSeq.swap(newInfoSeq); + + saveFileInfoSeq(dataDir, infoSeq); } - while(p != removeFiles.end() && p->path.size() > dir.size() && p->path.compare(0, dir.size(), dir) == 0); } - Long total = 0; - Long updated = 0; - - for(p = updateFiles.begin(); p != updateFiles.end(); ++p) + if(!updateFiles.empty()) { - if(p->size > 0) // Regular, non-empty file? + string pathLog = dataDir + ".log"; + ofstream fileLog; + + if(!dry) { - total += p->size; + fileLog.open(pathLog.c_str()); + if(!fileLog) + { + cerr << argv[0] << ": cannot open `" + pathLog + "' for writing: " + strerror(errno); + return EXIT_FAILURE; + } } - } - - for(p = updateFiles.begin(); p != updateFiles.end(); ++p) - { - cout << "update: " << p->path << ' ' << flush; - - if(p->size < 0) // Directory? + + Long total = 0; + Long updated = 0; + + for(p = updateFiles.begin(); p != updateFiles.end(); ++p) { - if(!dry) + if(p->size > 0) // Regular, non-empty file? { - createDirectoryRecursive(p->path); + total += p->size; } } - else // Regular file. + + DecompressorPtr decompressor = new Decompressor; + DecompressorDestroyer decompressorDestroyer(decompressor); + decompressor->start(); + + for(p = updateFiles.begin(); p != updateFiles.end(); ++p) { - string pathBZ2 = p->path + ".bz2"; - ofstream fileBZ2; + cout << "update: " << getBasename(p->path) << ' ' << flush; - if(!dry) + if(p->size < 0) // Directory? { - string dir = getDirname(pathBZ2); - if(!dir.empty()) + if(!dry) { - createDirectoryRecursive(dir); + createDirectoryRecursive(p->path); + fileLog << *p << endl; } + } + else // Regular file. + { + string pathBZ2 = p->path + ".bz2"; + ofstream fileBZ2; - try - { - removeRecursive(pathBZ2); - } - catch(...) + if(!dry) { - } + string dir = getDirname(pathBZ2); + if(!dir.empty()) + { + createDirectoryRecursive(dir); + } - fileBZ2.open(pathBZ2.c_str(), ios::binary); - if(!fileBZ2) - { - cerr << argv[0] << ": cannot open `" + pathBZ2 + "' for writing: " + strerror(errno); - return EXIT_FAILURE; + try + { + removeRecursive(pathBZ2); + } + catch(...) + { + } + + fileBZ2.open(pathBZ2.c_str(), ios::binary); + if(!fileBZ2) + { + cerr << argv[0] << ": cannot open `" + pathBZ2 + "' for writing: " + strerror(errno); + return EXIT_FAILURE; + } } - } - Int pos = 0; - string progress; + Int pos = 0; + string progress; - while(pos < p->size) - { - ByteSeq bytes; - - try + while(pos < p->size) { - bytes = fileServer->getFileCompressed(p->path, pos, chunk); - } - catch(const FileAccessException& ex) - { - cerr << argv[0] << ": server error for `" << p->path << "':" << ex.reason << endl; - return EXIT_FAILURE; - } + ByteSeq bytes; - if(bytes.empty()) - { - cerr << argv[0] << ": size mismatch for `" << p->path << "'" << endl; - return EXIT_FAILURE; - } - - if(!dry) - { - fileBZ2.write(reinterpret_cast<char*>(&bytes[0]), bytes.size()); + try + { + bytes = fileServer->getFileCompressed(p->path, pos, chunk); + } + catch(const FileAccessException& ex) + { + cerr << argv[0] << ": server error for `" << p->path << "':" << ex.reason << endl; + return EXIT_FAILURE; + } - if(!fileBZ2) + if(bytes.empty()) { - cerr << argv[0] << ": cannot write `" + pathBZ2 + "': " + strerror(errno); + cerr << argv[0] << ": size mismatch for `" << p->path << "'" << endl; return EXIT_FAILURE; } - } - pos += bytes.size(); - updated += bytes.size(); + if(!dry) + { + fileBZ2.write(reinterpret_cast<char*>(&bytes[0]), bytes.size()); - for(unsigned int i = 0; i < progress.size(); ++i) - { - cout << '\b'; + if(!fileBZ2) + { + cerr << argv[0] << ": cannot write `" + pathBZ2 + "': " + strerror(errno); + return EXIT_FAILURE; + } + } + + pos += bytes.size(); + updated += bytes.size(); + + for(unsigned int i = 0; i < progress.size(); ++i) + { + cout << '\b'; + } + ostringstream s; + s << pos << '/' << p->size << " (" << updated << '/' << total << ')'; + progress = s.str(); + cout << progress << flush; } - ostringstream s; - s << pos << '/' << p->size << " (" << updated << '/' << total << ')'; - progress = s.str(); - cout << progress << flush; - } - if(!dry) - { - fileBZ2.close(); - uncompressFile(p->path); - remove(pathBZ2); + if(!dry) + { + fileBZ2.close(); + fileLog << *p << endl; + + decompressor->checkForException(); + decompressor->add(p->path); + } } - } - cout << endl; - } + cout << endl; + } - // - // After a complete and successful patch, we write a new - // summary file. - // - if(!dry) - { - FileInfoSeq newInfoSeq1; - newInfoSeq1.reserve(infoSeq.size()); + decompressor->destroy(); + decompressor->getThreadControl().join(); + decompressor->checkForException(); + + if(!dry) + { + fileLog.close(); + + FileInfoSeq newInfoSeq; + newInfoSeq.reserve(infoSeq.size()); - set_difference(infoSeq.begin(), - infoSeq.end(), - removeFiles.begin(), - removeFiles.end(), - back_inserter(newInfoSeq1), - FileInfoCompare()); - - FileInfoSeq newInfoSeq2; - newInfoSeq2.reserve(newInfoSeq1.size() + updateFiles.size()); - - set_union(newInfoSeq1.begin(), - newInfoSeq1.end(), - updateFiles.begin(), - updateFiles.end(), - back_inserter(newInfoSeq2), - FileInfoCompare()); - - saveFileInfoSeq(dataDir + ".sum", newInfoSeq2); + set_union(infoSeq.begin(), + infoSeq.end(), + updateFiles.begin(), + updateFiles.end(), + back_inserter(newInfoSeq), + FileInfoLess()); + + infoSeq.swap(newInfoSeq); + + saveFileInfoSeq(dataDir, infoSeq); + } } } catch(const string& ex) @@ -404,11 +461,6 @@ IcePatch2::Client::run(int argc, char* argv[]) cerr << argv[0] << ": " << ex << endl; return EXIT_FAILURE; } - catch(const char* ex) - { - cerr << argv[0] << ": " << ex << endl; - return EXIT_FAILURE; - } return EXIT_SUCCESS; } diff --git a/cpp/src/IcePatch2/Server.cpp b/cpp/src/IcePatch2/Server.cpp index 2ad9f40eafc..49f40899343 100644 --- a/cpp/src/IcePatch2/Server.cpp +++ b/cpp/src/IcePatch2/Server.cpp @@ -114,9 +114,7 @@ IcePatch2::PatcherService::start(int argc, char* argv[]) throw "cannot change directory to `" + dataDir + "': " + strerror(errno); } - loadFileInfoSeq(dataDir + ".sum", infoSeq); - - sort(infoSeq.begin(), infoSeq.end(), FileInfoCompare()); + loadFileInfoSeq(dataDir, infoSeq); } catch(const string& ex) { diff --git a/cpp/src/IcePatch2/Util.cpp b/cpp/src/IcePatch2/Util.cpp index 80544f472b4..021f852e64d 100644 --- a/cpp/src/IcePatch2/Util.cpp +++ b/cpp/src/IcePatch2/Util.cpp @@ -45,7 +45,7 @@ scandir(const char* dir, struct dirent*** namelist, { return -1; } - + *namelist = 0; while((entry = readdir(d)) != 0) { @@ -56,7 +56,7 @@ scandir(const char* dir, struct dirent*** namelist, { return -1; } - + entrysize = sizeof(struct dirent) - sizeof(entry->d_name) + strlen(entry->d_name) + 1; (*namelist)[i] = (struct dirent*)malloc(entrysize); if((*namelist)[i] == 0) @@ -72,7 +72,7 @@ scandir(const char* dir, struct dirent*** namelist, { return -1; } - + if(i == 0) { return -1; @@ -82,7 +82,7 @@ scandir(const char* dir, struct dirent*** namelist, { qsort((void *)(*namelist), (size_t)i, sizeof(struct dirent *), compar); } - + return i; } @@ -134,9 +134,9 @@ string IcePatch2::normalize(const string& path) { string result = path; - + string::size_type pos; - + #ifdef WIN32 for(pos = 0; pos < result.size(); ++pos) { @@ -146,13 +146,13 @@ IcePatch2::normalize(const string& path) } } #endif - + pos = 0; while((pos = result.find("//", pos)) != string::npos) { result.erase(pos, 1); } - + pos = 0; while((pos = result.find("/./", pos)) != string::npos) { @@ -161,17 +161,17 @@ IcePatch2::normalize(const string& path) if(result.substr(0, 2) == "./") { - result.erase(0, 2); + result.erase(0, 2); } if(result.size() >= 2 && result.substr(result.size() - 2, 2) == "/.") { - result.erase(result.size() - 2, 2); + result.erase(result.size() - 2, 2); } if(result.size() >= 1 && result[result.size() - 1] == '/') { - result.erase(result.size() - 1); + result.erase(result.size() - 1); } return result; @@ -271,19 +271,19 @@ IcePatch2::removeRecursive(const string& pa) { throw "cannot stat `" + path + "': " + strerror(errno); } - + if(S_ISDIR(buf.st_mode)) { StringSeq paths = readDirectory(path); - for(StringSeq::const_iterator p = paths.begin(); p != paths.end(); ++p) + for(StringSeq::const_iterator p = paths.begin(); p != paths.end(); ++p) { removeRecursive(path + '/' + *p); } - + #ifdef _WIN32 if(_rmdir(path.c_str()) == -1) #else - if(rmdir(path.c_str()) == -1) + if(rmdir(path.c_str()) == -1) #endif { throw "cannot remove directory `" + path + "': " + strerror(errno); @@ -308,7 +308,7 @@ IcePatch2::readDirectory(const string& pa) { throw "cannot read directory `" + path + "': " + strerror(errno); } - + StringSeq result; while(true) @@ -321,17 +321,17 @@ IcePatch2::readDirectory(const string& pa) result.push_back(name); } - if(_findnext(h, &data) == -1) - { - if(errno == ENOENT) - { - break; - } + if(_findnext(h, &data) == -1) + { + if(errno == ENOENT) + { + break; + } - string ex = "cannot read directory `" + path + "': " + strerror(errno); - _findclose(h); - throw ex; - } + string ex = "cannot read directory `" + path + "': " + strerror(errno); + _findclose(h); + throw ex; + } } _findclose(h); @@ -364,7 +364,7 @@ IcePatch2::readDirectory(const string& pa) result.push_back(name); } } - + free(namelist); return result; @@ -401,7 +401,7 @@ IcePatch2::compressBytesToFile(const string& pa, const ByteSeq& bytes, Int pos) { throw "cannot open `" + path + "' for writing: " + strerror(errno); } - + int bzError; BZFILE* bzFile = BZ2_bzWriteOpen(&bzError, stdioFile, 5, 0, 0); if(bzError != BZ_OK) @@ -414,7 +414,7 @@ IcePatch2::compressBytesToFile(const string& pa, const ByteSeq& bytes, Int pos) fclose(stdioFile); throw ex; } - + BZ2_bzWrite(&bzError, bzFile, const_cast<Byte*>(&bytes[pos]), bytes.size() - pos); if(bzError != BZ_OK) { @@ -427,7 +427,7 @@ IcePatch2::compressBytesToFile(const string& pa, const ByteSeq& bytes, Int pos) fclose(stdioFile); throw ex; } - + BZ2_bzWriteClose(&bzError, bzFile, 0, 0, 0); if(bzError != BZ_OK) { @@ -439,12 +439,12 @@ IcePatch2::compressBytesToFile(const string& pa, const ByteSeq& bytes, Int pos) fclose(stdioFile); throw ex; } - + fclose(stdioFile); } void -IcePatch2::uncompressFile(const string& pa) +IcePatch2::decompressFile(const string& pa) { const string path = normalize(pa); const string pathBZ2 = path + ".bz2"; @@ -454,13 +454,13 @@ IcePatch2::uncompressFile(const string& pa) { throw "cannot open `" + path + "' for writing: " + strerror(errno); } - + FILE* stdioFileBZ2 = fopen(pathBZ2.c_str(), "rb"); if(!stdioFileBZ2) { throw "cannot open `" + pathBZ2 + "' for reading: " + strerror(errno); } - + int bzError; BZFILE* bzFile = BZ2_bzReadOpen(&bzError, stdioFileBZ2, 0, 0, 0, 0); if(bzError != BZ_OK) @@ -473,10 +473,10 @@ IcePatch2::uncompressFile(const string& pa) fclose(stdioFileBZ2); throw ex; } - + const Int numBZ2 = 64 * 1024; Byte bytesBZ2[numBZ2]; - + while(bzError != BZ_STREAM_END) { int sz = BZ2_bzRead(&bzError, bzFile, bytesBZ2, numBZ2); @@ -491,7 +491,7 @@ IcePatch2::uncompressFile(const string& pa) fclose(stdioFileBZ2); throw ex; } - + if(sz > 0) { long pos = ftell(stdioFileBZ2); @@ -501,7 +501,7 @@ IcePatch2::uncompressFile(const string& pa) fclose(stdioFileBZ2); throw "cannot get read position for `" + pathBZ2 + "': " + strerror(errno); } - + file.write(reinterpret_cast<char*>(bytesBZ2), sz); if(!file) { @@ -527,8 +527,8 @@ IcePatch2::uncompressFile(const string& pa) fclose(stdioFileBZ2); } -void -IcePatch2::getFileInfoSeq(const string& pa, FileInfoSeq& infoSeq, bool size, bool compress, bool verbose) +static void +getFileInfoSeqNoSort(const string& pa, FileInfoSeq& infoSeq, bool size, bool compress, bool verbose) { const string path = normalize(pa); @@ -582,7 +582,7 @@ IcePatch2::getFileInfoSeq(const string& pa, FileInfoSeq& infoSeq, bool size, boo { throw "cannot stat `" + path + "': " + strerror(errno); } - + if(S_ISDIR(buf.st_mode)) { FileInfo info; @@ -598,11 +598,11 @@ IcePatch2::getFileInfoSeq(const string& pa, FileInfoSeq& infoSeq, bool size, boo info.checksum.swap(bytesSHA); infoSeq.push_back(info); - + StringSeq content = readDirectory(path); for(StringSeq::const_iterator p = content.begin(); p != content.end() ; ++p) { - getFileInfoSeq(path + '/' + *p, infoSeq, size, compress, verbose); + getFileInfoSeqNoSort(path + '/' + *p, infoSeq, size, compress, verbose); } } else if(S_ISREG(buf.st_mode)) @@ -627,7 +627,7 @@ IcePatch2::getFileInfoSeq(const string& pa, FileInfoSeq& infoSeq, bool size, boo cout << path << ": calculating checksum" << endl; } } - + int fd = open(path.c_str(), O_RDONLY); if(fd == -1) { @@ -639,9 +639,9 @@ IcePatch2::getFileInfoSeq(const string& pa, FileInfoSeq& infoSeq, bool size, boo close(fd); throw "cannot read `" + path + "': " + strerror(errno); } - + close(fd); - + if(compress) { string pathBZ2 = path + ".bz2"; @@ -668,7 +668,7 @@ IcePatch2::getFileInfoSeq(const string& pa, FileInfoSeq& infoSeq, bool size, boo cout << path << ": calculating checksum for empty file" << endl; } } - + ByteSeq bytesSHA(20); SHA1(reinterpret_cast<unsigned char*>(&bytes[0]), bytes.size(), reinterpret_cast<unsigned char*>(&bytesSHA[0])); @@ -686,39 +686,86 @@ IcePatch2::getFileInfoSeq(const string& pa, FileInfoSeq& infoSeq, bool size, boo } void -IcePatch2::saveFileInfoSeq(const string& path, const FileInfoSeq& infoSeq) +IcePatch2::getFileInfoSeq(const string& pa, FileInfoSeq& infoSeq, bool size, bool compress, bool verbose) +{ + getFileInfoSeqNoSort(pa, infoSeq, size, compress, verbose); + sort(infoSeq.begin(), infoSeq.end(), FileInfoLess()); + infoSeq.erase(unique(infoSeq.begin(), infoSeq.end(), FileInfoEqual()), infoSeq.end()); +} + +void +IcePatch2::saveFileInfoSeq(const string& pa, const FileInfoSeq& infoSeq) { - ofstream os(path.c_str()); - if(!os) { - throw "cannot open `" + path + "' for writing: " + strerror(errno); + const string path = normalize(pa + ".sum"); + + ofstream os(path.c_str()); + if(!os) + { + throw "cannot open `" + path + "' for writing: " + strerror(errno); + } + + for(FileInfoSeq::const_iterator p = infoSeq.begin(); p != infoSeq.end(); ++p) + { + os << *p << '\n'; + } } - - for(FileInfoSeq::const_iterator p = infoSeq.begin(); p != infoSeq.end(); ++p) + { - os << *p << '\n'; + const string pathLog = normalize(pa + ".log"); + + try + { + remove(pathLog); + } + catch(...) + { + } } } void -IcePatch2::loadFileInfoSeq(const string& path, FileInfoSeq& infoSeq) +IcePatch2::loadFileInfoSeq(const string& pa, FileInfoSeq& infoSeq) { - ifstream is(path.c_str()); - if(!is) { - throw "cannot open `" + path + "' for reading: " + strerror(errno); + const string path = normalize(pa + ".sum"); + + ifstream is(path.c_str()); + if(!is) + { + throw "cannot open `" + path + "' for reading: " + strerror(errno); + } + + while(is.good()) + { + FileInfo info; + is >> info; + + if(is.good()) + { + infoSeq.push_back(info); + } + } } - - while(is.good()) + { - FileInfo info; - is >> info; - - if(is.good()) + const string pathLog = normalize(pa + ".log"); + + ifstream is(pathLog.c_str()); + while(is.good()) { - infoSeq.push_back(info); + FileInfo info; + is >> info; + + if(is.good()) + { + infoSeq.push_back(info); + } } } + + sort(infoSeq.begin(), infoSeq.end(), FileInfoLess()); + infoSeq.erase(unique(infoSeq.begin(), infoSeq.end(), FileInfoEqual()), infoSeq.end()); } void @@ -732,26 +779,26 @@ IcePatch2::getFileTree1(const FileInfoSeq& infoSeq, FileTree1& tree1) else { tree1.files.reserve(infoSeq.size()); - + FileInfoSeq::const_iterator p = infoSeq.begin(); - + ByteSeq allChecksums; allChecksums.resize(infoSeq.size() * 20); ByteSeq::iterator q = allChecksums.begin(); - + while(p < infoSeq.end()) { tree1.files.push_back(*p); - + assert(p->checksum.size() == 20); copy(p->checksum.begin(), p->checksum.end(), q); - + ++p; q += 20; } - sort(tree1.files.begin(), tree1.files.end(), FileInfoCompare()); - + sort(tree1.files.begin(), tree1.files.end(), FileInfoLess()); + tree1.checksum.resize(20); SHA1(reinterpret_cast<unsigned char*>(&allChecksums[0]), allChecksums.size(), reinterpret_cast<unsigned char*>(&tree1.checksum[0])); @@ -815,3 +862,89 @@ IcePatch2::operator>>(istream& is, FileInfo& info) return is; } + +IcePatch2::Decompressor::Decompressor() : + _destroy(false) +{ +} + +IcePatch2::Decompressor::~Decompressor() +{ + assert(_destroy); +} + +void +IcePatch2::Decompressor::destroy() +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + _destroy = true; + + notify(); +} +void +IcePatch2::Decompressor::add(const string& file) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + assert(!_destroy); + + if(_files.empty()) + { + notify(); + } + + _files.push_back(file); +} + +void +IcePatch2::Decompressor::checkForException() const +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + if(!_exception.empty()) + { + assert(_destroy); + throw _exception; + } +} + +void +IcePatch2::Decompressor::run() +{ + while(true) + { + std::string file; + + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + while(!_destroy && _files.empty()) + { + wait(); + } + + if(_destroy && _files.empty()) + { + return; + } + + assert(!_files.empty()); + file = _files.front(); + _files.pop_front(); + } + + try + { + decompressFile(file); + remove(file + ".bz2"); + } + catch(const string& ex) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + _destroy = true; + _exception = ex; + return; + } + } +} |