Autogen: Use std::istreambuf_iterator for file so string reading

This adds a dedicated mutex for file reading and writing to
cmQtAutoGenerator::FileSystem. The purpose of the change is
to avoid that long files reads block cmsys based path computations,
which are protected by an other mutex.
This commit is contained in:
Sebastian Holtermann 2018-04-03 13:36:47 +02:00
parent ccc38fa509
commit 1d2c9d8c6d
2 changed files with 35 additions and 21 deletions

View File

@ -219,6 +219,20 @@ bool cmQtAutoGenerator::FileSystem::FileExists(std::string const& filename)
return cmSystemTools::FileExists(filename); return cmSystemTools::FileExists(filename);
} }
bool cmQtAutoGenerator::FileSystem::FileExists(std::string const& filename,
bool isFile)
{
std::lock_guard<std::mutex> lock(Mutex_);
return cmSystemTools::FileExists(filename, isFile);
}
unsigned long cmQtAutoGenerator::FileSystem::FileLength(
std::string const& filename)
{
std::lock_guard<std::mutex> lock(Mutex_);
return cmSystemTools::FileLength(filename);
}
bool cmQtAutoGenerator::FileSystem::FileIsOlderThan( bool cmQtAutoGenerator::FileSystem::FileIsOlderThan(
std::string const& buildFile, std::string const& sourceFile, std::string const& buildFile, std::string const& sourceFile,
std::string* error) std::string* error)
@ -248,15 +262,15 @@ bool cmQtAutoGenerator::FileSystem::FileRead(std::string& content,
std::string* error) std::string* error)
{ {
bool success = false; bool success = false;
if (FileExists(filename, true)) {
unsigned long const length = FileLength(filename);
{ {
std::lock_guard<std::mutex> lock(Mutex_); std::lock_guard<std::mutex> lock(Mutex_);
if (cmSystemTools::FileExists(filename, true)) {
std::size_t const length = cmSystemTools::FileLength(filename);
cmsys::ifstream ifs(filename.c_str(), (std::ios::in | std::ios::binary)); cmsys::ifstream ifs(filename.c_str(), (std::ios::in | std::ios::binary));
if (ifs) { if (ifs) {
if (length > 0) { content.reserve(length);
content.resize(length); content.assign(std::istreambuf_iterator<char>{ ifs },
ifs.read(&content.front(), content.size()); std::istreambuf_iterator<char>{});
if (ifs) { if (ifs) {
success = true; success = true;
} else { } else {
@ -265,19 +279,14 @@ bool cmQtAutoGenerator::FileSystem::FileRead(std::string& content,
error->append("Reading from the file failed."); error->append("Reading from the file failed.");
} }
} }
} else {
// Readable but empty file
content.clear();
success = true;
}
} else if (error != nullptr) { } else if (error != nullptr) {
error->append("Opening the file for reading failed."); error->append("Opening the file for reading failed.");
} }
}
} else if (error != nullptr) { } else if (error != nullptr) {
error->append( error->append(
"The file does not exist, is not readable or is a directory."); "The file does not exist, is not readable or is a directory.");
} }
}
return success; return success;
} }

View File

@ -99,7 +99,12 @@ public:
std::string GetFilePathChecksum(std::string const& filename); std::string GetFilePathChecksum(std::string const& filename);
// -- File access // -- File access
/// @brief Wrapper for cmSystemTools::FileExists
bool FileExists(std::string const& filename); bool FileExists(std::string const& filename);
/// @brief Wrapper for cmSystemTools::FileExists
bool FileExists(std::string const& filename, bool isFile);
/// @brief Wrapper for cmSystemTools::FileLength
unsigned long FileLength(std::string const& filename);
bool FileIsOlderThan(std::string const& buildFile, bool FileIsOlderThan(std::string const& buildFile,
std::string const& sourceFile, std::string const& sourceFile,
std::string* error = nullptr); std::string* error = nullptr);