summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/ctest_exclusions.cmake9
-rw-r--r--Modules/ExternalData.cmake9
2 files changed, 8 insertions, 10 deletions
diff --git a/.gitlab/ci/ctest_exclusions.cmake b/.gitlab/ci/ctest_exclusions.cmake
index a68a693..b885a6a 100644
--- a/.gitlab/ci/ctest_exclusions.cmake
+++ b/.gitlab/ci/ctest_exclusions.cmake
@@ -13,15 +13,6 @@ if (CTEST_CMAKE_GENERATOR MATCHES "Visual Studio")
"^ExternalProjectUpdateSetup$")
endif ()
-if (CMAKE_HOST_WIN32)
- list(APPEND test_exclusions
- # This test often fails with an undiagnosed subtle race due to the test
- # re-using the same objects for many files. Some copy operations fail
- # to open their input with ERROR_SHARING_VIOLATION.
- "^Module.ExternalData$"
- )
-endif()
-
string(REPLACE ";" "|" test_exclusions "${test_exclusions}")
if (test_exclusions)
set(test_exclusions "(${test_exclusions})")
diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake
index d6fbae9..b439636 100644
--- a/Modules/ExternalData.cmake
+++ b/Modules/ExternalData.cmake
@@ -1101,7 +1101,14 @@ function(_ExternalData_download_object name hash algo var_obj var_success var_er
set(success 1)
if(found)
- file(RENAME "${tmp}" "${obj}")
+ # Atomically create the object. If we lose a race with another process,
+ # do not replace it. Content-addressing ensures it has what we expect.
+ file(RENAME "${tmp}" "${obj}" NO_REPLACE RESULT result)
+ if (result STREQUAL "NO_REPLACE")
+ file(REMOVE "${tmp}")
+ elseif (result)
+ message(FATAL_ERROR "Failed to rename:\n \"${tmp}\"\nto:\n \"${obj}\"\nwith error:\n ${result}")
+ endif()
message(STATUS "Downloaded object: \"${obj}\"")
elseif(EXISTS "${staged}")
set(obj "${staged}")