Skip to content

Commit bd2a2e3

Browse files
authored
Merge pull request #4844 from mwichmann/fix/cachedir-race-again
Further tweak CacheDir for races
2 parents 39708de + 514b544 commit bd2a2e3

3 files changed

Lines changed: 15 additions & 8 deletions

File tree

CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
7272
the general unavailablility of the obsolete build-time Qt3 package.
7373
- A few more typing cleanups in Environment (and in one case which
7474
affected it in the Node package).
75+
- Adjust race protection for CacheDir - now uses a unique temporary
76+
directory for each writer before doing the move, instead of depending
77+
on a one-time uuid to make a path to the file.
7578
- Clarify VariantDir behavior when switching to not duplicate sources
7679
and tweak wording a bit.
7780

RELEASE.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ FIXES
4747

4848
- Fix --debug=includes for case of multiple source files.
4949

50+
- Adjust race protection for CacheDir - now uses a unique temporary
51+
directory for each writer before doing the move, instead of depending
52+
on a one-time uuid to make a path to the file.
53+
5054
IMPROVEMENTS
5155
------------
5256

SCons/CacheDir.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
import stat
3232
import sys
3333
import tempfile
34-
import uuid
3534

3635
import SCons.Action
3736
import SCons.Errors
37+
# import SCons.Node.FS # used for hash_chunksice, but causes import loop
3838
import SCons.Warnings
3939
import SCons.Util
4040

@@ -49,7 +49,6 @@
4949
cache_force = False
5050
cache_show = False
5151
cache_readonly = False
52-
cache_tmp_uuid = uuid.uuid4().hex
5352

5453
def CacheRetrieveFunc(target, source, env) -> int:
5554
t = target[0]
@@ -110,7 +109,6 @@ def CachePushFunc(target, source, env) -> None:
110109

111110
cd.CacheDebug('CachePush(%s): pushing to %s\n', t, cachefile)
112111

113-
tempfile = "%s.tmp%s"%(cachefile,cache_tmp_uuid)
114112
errfmt = "Unable to copy %s to cache. Cache file is %s"
115113

116114
try:
@@ -119,11 +117,13 @@ def CachePushFunc(target, source, env) -> None:
119117
msg = errfmt % (str(target), cachefile)
120118
raise SCons.Errors.SConsEnvironmentError(msg)
121119
try:
122-
if fs.islink(t.get_internal_path()):
123-
fs.symlink(fs.readlink(t.get_internal_path()), tempfile)
124-
else:
125-
cd.copy_to_cache(env, t.get_internal_path(), tempfile)
126-
fs.rename(tempfile, cachefile)
120+
with tempfile.TemporaryDirectory(dir=cachedir) as temp_dir:
121+
temp_file = os.path.join(temp_dir, os.path.basename(cachefile))
122+
if fs.islink(t.get_internal_path()):
123+
fs.symlink(fs.readlink(t.get_internal_path()), temp_file)
124+
else:
125+
cd.copy_to_cache(env, t.get_internal_path(), temp_file)
126+
fs.rename(temp_file, cachefile)
127127

128128
except OSError:
129129
# It's possible someone else tried writing the file at the

0 commit comments

Comments
 (0)