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
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// Sometimes anti-virus software hangs on to new files so we
|
||||
// cannot delete them immediately. Try a few times.
|
||||
int tries = 5;
|
||||
cmSystemTools::WindowsFileRetry retry =
|
||||
cmSystemTools::GetWindowsFileRetry();
|
||||
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;
|
||||
cmSystemTools::ReportLastSystemError(m.c_str());
|
||||
|
|
|
@ -863,6 +863,44 @@ bool cmSystemTools::CopyFileIfDifferent(const char* source,
|
|||
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)
|
||||
{
|
||||
|
@ -874,10 +912,10 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
|
|||
fails then remove the read-only attribute from any existing destination.
|
||||
Try multiple times since we may be racing against another process
|
||||
creating/opening the destination file just before our MoveFileEx. */
|
||||
int tries = 5;
|
||||
WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry();
|
||||
while(!MoveFileExW(cmsys::Encoding::ToWide(oldname).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.
|
||||
if(GetLastError() != ERROR_ACCESS_DENIED)
|
||||
|
@ -896,10 +934,10 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
|
|||
else
|
||||
{
|
||||
// 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
|
||||
/* On UNIX we have an OS-provided call to do this atomically. */
|
||||
return rename(oldname, newname) == 0;
|
||||
|
|
|
@ -460,6 +460,15 @@ public:
|
|||
/** Tokenize a string */
|
||||
static std::vector<std::string> tokenize(const std::string& str,
|
||||
const std::string& sep);
|
||||
|
||||
#ifdef _WIN32
|
||||
struct WindowsFileRetry
|
||||
{
|
||||
unsigned int Count;
|
||||
unsigned int Delay;
|
||||
};
|
||||
static WindowsFileRetry GetWindowsFileRetry();
|
||||
#endif
|
||||
private:
|
||||
static bool s_ForceUnixPaths;
|
||||
static bool s_RunCommandHideConsole;
|
||||
|
|
Loading…
Reference in New Issue