Skip to content

Commit a7c361d

Browse files
committed
pythongh-93584: Avoid file race condition in build process
1 parent 70690c7 commit a7c361d

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

Lib/_bootsubprocess.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
subprocess is unavailable. setup.py is not used on Windows.
55
"""
66
import os
7+
import time
78

89

910
# distutils.spawn used by distutils.command.build_ext
@@ -70,7 +71,9 @@ def check_output(cmd, **kwargs):
7071
if not _check_cmd(cmd):
7172
raise ValueError(f"unsupported command: {cmd!r}")
7273

73-
tmp_filename = "check_output.tmp"
74+
# include pid and time stamp to avoid file name clashes with parallel
75+
# builds.
76+
tmp_filename = f"check_output-{os.getpid()}-{int(time.time() )}.tmp"
7477
if not isinstance(cmd, str):
7578
cmd = " ".join(cmd)
7679
cmd = f"{cmd} >{tmp_filename}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Avoid file race condition in ``setup.py`` ``add_multiarch_paths()`` method
2+
and ``_bootsubprocess.check_output()`` function.

setup.py

+11-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import shlex
1111
import sys
1212
import sysconfig
13+
import time
1314
import warnings
1415
from glob import glob, escape
1516
import _osx_support
@@ -688,9 +689,15 @@ def check_extension_import(self, ext):
688689
def add_multiarch_paths(self):
689690
# Debian/Ubuntu multiarch support.
690691
# https://wiki.ubuntu.com/MultiarchSpec
691-
tmpfile = os.path.join(self.build_temp, 'multiarch')
692-
if not os.path.exists(self.build_temp):
693-
os.makedirs(self.build_temp)
692+
693+
# Poor man's conflict avoidance. PGO build use $(MAKE), which runs
694+
# make in a separate, untracked process. Sometimes main and subproces
695+
# run `make sharedmods` at the same time. One process removes
696+
# "multiarch" file of the other process.
697+
tmpfile = os.path.join(
698+
self.build_temp, f"multiarch-{os.getpid()}-{int(time.time() )}.tmp"
699+
)
700+
os.makedirs(self.build_temp, exist_ok=True)
694701
ret = run_command(
695702
'%s -print-multiarch > %s 2> /dev/null' % (CC, tmpfile))
696703
multiarch_path_component = ''
@@ -713,9 +720,7 @@ def add_multiarch_paths(self):
713720
opt = ''
714721
if CROSS_COMPILING:
715722
opt = '-t' + sysconfig.get_config_var('HOST_GNU_TYPE')
716-
tmpfile = os.path.join(self.build_temp, 'multiarch')
717-
if not os.path.exists(self.build_temp):
718-
os.makedirs(self.build_temp)
723+
os.makedirs(self.build_temp, exist_ok=True)
719724
ret = run_command(
720725
'dpkg-architecture %s -qDEB_HOST_MULTIARCH > %s 2> /dev/null' %
721726
(opt, tmpfile))

0 commit comments

Comments
 (0)