Skip to content

Commit 5a5c928

Browse files
authoredJan 1, 2022
Rollup merge of #88310 - worldeva:bootstrap-locking, r=Mark-Simulacrum
Lock bootstrap (x.py) build directory Closes #76661, closes #80849, `x.py` creates a lock file at `project_root/lock.db` r? `@jyn514` , because he was one that told me about this~
2 parents ad0d419 + 1326bd6 commit 5a5c928

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed
 

‎src/bootstrap/bootstrap.py

+42
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,42 @@
1515

1616
from time import time
1717

18+
# Acquire a lock on the build directory to make sure that
19+
# we don't cause a race condition while building
20+
# Lock is created in `build_dir/lock.db`
21+
def acquire_lock(build_dir):
22+
try:
23+
import sqlite3
24+
25+
path = os.path.join(build_dir, "lock.db")
26+
try:
27+
con = sqlite3.Connection(path, timeout=0)
28+
curs = con.cursor()
29+
curs.execute("BEGIN EXCLUSIVE")
30+
# The lock is released when the cursor is dropped
31+
return curs
32+
# If the database is busy then lock has already been acquired
33+
# so we wait for the lock.
34+
# We retry every quarter second so that execution is passed back to python
35+
# so that it can handle signals
36+
except sqlite3.OperationalError:
37+
del con
38+
del curs
39+
print("Waiting for lock on build directory")
40+
con = sqlite3.Connection(path, timeout=0.25)
41+
curs = con.cursor()
42+
while True:
43+
try:
44+
curs.execute("BEGIN EXCLUSIVE")
45+
except sqlite3.OperationalError:
46+
pass
47+
return curs
48+
except ImportError:
49+
print("warning: sqlite3 not available in python, skipping build directory lock")
50+
print("please file an issue on rust-lang/rust")
51+
print("this is not a problem for non-concurrent x.py invocations")
52+
return None
53+
1854
def support_xz():
1955
try:
2056
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
@@ -1228,6 +1264,12 @@ def bootstrap(help_triggered):
12281264
build.set_dist_environment(data["dist_server"])
12291265

12301266
build.build = args.build or build.build_triple()
1267+
1268+
# Acquire the lock before doing any build actions
1269+
# The lock is released when `lock` is dropped
1270+
if not os.path.exists(build.build_dir):
1271+
os.makedirs(build.build_dir)
1272+
lock = acquire_lock(build.build_dir)
12311273
build.update_submodules()
12321274

12331275
# Fetch/build the bootstrap

0 commit comments

Comments
 (0)
Please sign in to comment.