Merge topic 'windows-filesystem-retry-config'
7b1f966a
Windows: Make file delete/rename retry configurable
This commit is contained in:
commit
b486c6d49a
|
@ -585,15 +585,20 @@ void cmCoreTryCompile::CleanupFiles(const char* binDir)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
// Sometimes anti-virus software hangs on to new files so we
|
// Sometimes anti-virus software hangs on to new files so we
|
||||||
// cannot delete them immediately. Try a few times.
|
// cannot delete them immediately. Try a few times.
|
||||||
int tries = 5;
|
cmSystemTools::WindowsFileRetry retry =
|
||||||
|
cmSystemTools::GetWindowsFileRetry();
|
||||||
while(!cmSystemTools::RemoveFile(fullPath.c_str()) &&
|
while(!cmSystemTools::RemoveFile(fullPath.c_str()) &&
|
||||||
--tries && cmSystemTools::FileExists(fullPath.c_str()))
|
--retry.Count && cmSystemTools::FileExists(fullPath.c_str()))
|
||||||
{
|
{
|
||||||
cmSystemTools::Delay(500);
|
cmSystemTools::Delay(retry.Delay);
|
||||||
}
|
}
|
||||||
if(tries == 0)
|
if(retry.Count == 0)
|
||||||
|
#else
|
||||||
|
if(!cmSystemTools::RemoveFile(fullPath.c_str()))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
std::string m = "Remove failed on file: " + fullPath;
|
std::string m = "Remove failed on file: " + fullPath;
|
||||||
cmSystemTools::ReportLastSystemError(m.c_str());
|
cmSystemTools::ReportLastSystemError(m.c_str());
|
||||||
|
|
|
@ -863,6 +863,44 @@ bool cmSystemTools::CopyFileIfDifferent(const char* source,
|
||||||
return Superclass::CopyFileIfDifferent(source, destination);
|
return Superclass::CopyFileIfDifferent(source, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
#ifdef _WIN32
|
||||||
|
cmSystemTools::WindowsFileRetry cmSystemTools::GetWindowsFileRetry()
|
||||||
|
{
|
||||||
|
static WindowsFileRetry retry = {0,0};
|
||||||
|
if(!retry.Count)
|
||||||
|
{
|
||||||
|
unsigned int data[2] = {0,0};
|
||||||
|
HKEY const keys[2] = {HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE};
|
||||||
|
wchar_t const* const values[2] = {L"FilesystemRetryCount",
|
||||||
|
L"FilesystemRetryDelay"};
|
||||||
|
for(int k=0; k < 2; ++k)
|
||||||
|
{
|
||||||
|
HKEY hKey;
|
||||||
|
if(RegOpenKeyExW(keys[k], L"Software\\Kitware\\CMake\\Config",
|
||||||
|
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
for(int v=0; v < 2; ++v)
|
||||||
|
{
|
||||||
|
DWORD dwData, dwType, dwSize = 4;
|
||||||
|
if(!data[v] &&
|
||||||
|
RegQueryValueExW(hKey, values[v], 0, &dwType, (BYTE *)&dwData,
|
||||||
|
&dwSize) == ERROR_SUCCESS &&
|
||||||
|
dwType == REG_DWORD && dwSize == 4)
|
||||||
|
{
|
||||||
|
data[v] = static_cast<unsigned int>(dwData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retry.Count = data[0]? data[0] : 5;
|
||||||
|
retry.Delay = data[1]? data[1] : 500;
|
||||||
|
}
|
||||||
|
return retry;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
|
bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
|
||||||
{
|
{
|
||||||
|
@ -874,10 +912,10 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
|
||||||
fails then remove the read-only attribute from any existing destination.
|
fails then remove the read-only attribute from any existing destination.
|
||||||
Try multiple times since we may be racing against another process
|
Try multiple times since we may be racing against another process
|
||||||
creating/opening the destination file just before our MoveFileEx. */
|
creating/opening the destination file just before our MoveFileEx. */
|
||||||
int tries = 5;
|
WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry();
|
||||||
while(!MoveFileExW(cmsys::Encoding::ToWide(oldname).c_str(),
|
while(!MoveFileExW(cmsys::Encoding::ToWide(oldname).c_str(),
|
||||||
cmsys::Encoding::ToWide(newname).c_str(),
|
cmsys::Encoding::ToWide(newname).c_str(),
|
||||||
MOVEFILE_REPLACE_EXISTING) && --tries)
|
MOVEFILE_REPLACE_EXISTING) && --retry.Count)
|
||||||
{
|
{
|
||||||
// Try again only if failure was due to access permissions.
|
// Try again only if failure was due to access permissions.
|
||||||
if(GetLastError() != ERROR_ACCESS_DENIED)
|
if(GetLastError() != ERROR_ACCESS_DENIED)
|
||||||
|
@ -896,10 +934,10 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The file may be temporarily in use so wait a bit.
|
// The file may be temporarily in use so wait a bit.
|
||||||
cmSystemTools::Delay(100);
|
cmSystemTools::Delay(retry.Delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tries > 0;
|
return retry.Count > 0;
|
||||||
#else
|
#else
|
||||||
/* On UNIX we have an OS-provided call to do this atomically. */
|
/* On UNIX we have an OS-provided call to do this atomically. */
|
||||||
return rename(oldname, newname) == 0;
|
return rename(oldname, newname) == 0;
|
||||||
|
|
|
@ -460,6 +460,15 @@ public:
|
||||||
/** Tokenize a string */
|
/** Tokenize a string */
|
||||||
static std::vector<std::string> tokenize(const std::string& str,
|
static std::vector<std::string> tokenize(const std::string& str,
|
||||||
const std::string& sep);
|
const std::string& sep);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
struct WindowsFileRetry
|
||||||
|
{
|
||||||
|
unsigned int Count;
|
||||||
|
unsigned int Delay;
|
||||||
|
};
|
||||||
|
static WindowsFileRetry GetWindowsFileRetry();
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
static bool s_ForceUnixPaths;
|
static bool s_ForceUnixPaths;
|
||||||
static bool s_RunCommandHideConsole;
|
static bool s_RunCommandHideConsole;
|
||||||
|
|
Loading…
Reference in New Issue