From 751caf5f7ccdddcf16f3ba63cbf1d21349ce3191 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Tue, 11 Jan 2022 10:01:02 -0600 Subject: [PATCH] Updated the Windows ScopedAutoTempDirectory creation logic to use a Uuid. (#6789) Previously it was using `GetTickCount()` for the creation of the directory which can collide if0 there are multiple processes creating a temporary directory via teh ScopedAutoTempDirectory constructor. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- .../ScopedAutoTempDirectory_Windows.cpp | 70 +++++++------------ 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/Code/Framework/AzTest/AzTest/Platform/Windows/ScopedAutoTempDirectory_Windows.cpp b/Code/Framework/AzTest/AzTest/Platform/Windows/ScopedAutoTempDirectory_Windows.cpp index fcda5d351a..b5314eda14 100644 --- a/Code/Framework/AzTest/AzTest/Platform/Windows/ScopedAutoTempDirectory_Windows.cpp +++ b/Code/Framework/AzTest/AzTest/Platform/Windows/ScopedAutoTempDirectory_Windows.cpp @@ -8,57 +8,41 @@ #include +#include #include #include #include -#include +#include -namespace AZ +namespace AZ::Test { - namespace Test + ScopedAutoTempDirectory::ScopedAutoTempDirectory() { - ScopedAutoTempDirectory::ScopedAutoTempDirectory() + using UuidString = AZStd::fixed_string; + constexpr DWORD bufferSize = static_cast(AZ::IO::MaxPathLength); + + wchar_t tempDirW[AZ::IO::MaxPathLength]{}; + GetTempPathW(bufferSize, tempDirW); + + AZ::IO::FixedMaxPath tempDirectoryRoot; + AZStd::to_string(tempDirectoryRoot.Native(), tempDirW); + + constexpr int MaxAttempts = 255; + for (int i = 0; i < MaxAttempts; ++i) { - constexpr const DWORD bufferSize = static_cast(AZ::IO::MaxPathLength); - - char tempDir[bufferSize] = {0}; - GetTempPathA(bufferSize, tempDir); - - char workingTempPathBuffer[bufferSize] = {'\0'}; - - int maxAttempts = 2000; // Prevent an infinite loop by setting an arbitrary maximum attempts at finding an available temp folder name - while (maxAttempts > 0) + AZ::IO::FixedMaxPath testPath = tempDirectoryRoot / + AZ::IO::FixedMaxPathString::format("UnitTest-%s", + AZ::Uuid::CreateRandom().ToString().c_str()); + // Try to create the temp directory if it doesn't exist + if (!AZ::IO::SystemFile::Exists(testPath.c_str()) && AZ::IO::SystemFile::CreateDir(testPath.c_str())) { - // Use the system's tick count to base the folder name - ULONGLONG currentTick = GetTickCount64(); - azsnprintf(workingTempPathBuffer, bufferSize, "%sUnitTest-%X", tempDir, aznumeric_cast(currentTick)); - - // Check if the requested directory name is available and re-generate if it already exists - bool exists = AZ::IO::SystemFile::Exists(workingTempPathBuffer); - if (exists) - { - Sleep(1); - maxAttempts--; - continue; - } + azstrncpy(AZStd::data(m_tempDirectory), AZStd::size(m_tempDirectory), + testPath.c_str(), testPath.Native().size()); break; } - - AZ_Error("AzTest", maxAttempts > 0, "Unable to determine a temp directory"); - - if (maxAttempts > 0) - { - // Create the temp directory and track it for deletion - bool tempDirectoryCreated = AZ::IO::SystemFile::CreateDir(workingTempPathBuffer); - if (tempDirectoryCreated) - { - azstrncpy(m_tempDirectory, AZ::IO::MaxPathLength, workingTempPathBuffer, AZ::IO::MaxPathLength); - } - else - { - AZ_Error("AzTest", false, "Unable to create temp directory %s", workingTempPathBuffer); - } - } } - } // Test -} // AZ + + AZ_Error("AzTest", m_tempDirectory[0] != '\0', "Unable to create temp path within directory %s after %d attempts", + tempDirectoryRoot.c_str(), MaxAttempts); + } +} // AZ::Test