Skip to content

Commit c386b6c

Browse files
committed
Refactor Ports.fetch_port to avoid locking the cache where possible
This is in service of improving support for FROZEN_CACHE and is needed as part of #13316. The logic here mirrors the lock in cache.get() where we first attempt to verify the contents of the cache without holding the lock and early out in the common case the what we want is already here.
1 parent 536a14e commit c386b6c

File tree

1 file changed

+19
-23
lines changed

1 file changed

+19
-23
lines changed

tools/system_libs.py

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,10 +1696,6 @@ def fetch_project(name, url, subdir, is_tarbz2=False, sha512hash=None):
16961696
logger.debug(' (at ' + fullname + ')')
16971697
Ports.name_cache.add(name)
16981698

1699-
class State(object):
1700-
retrieved = False
1701-
unpacked = False
1702-
17031699
def retrieve():
17041700
# retrieve from remote server
17051701
logger.info('retrieving port: ' + name + ' from ' + url)
@@ -1724,7 +1720,6 @@ def retrieve():
17241720
shared.exit_with_error('Unexpected hash: ' + actual_hash + '\n'
17251721
'If you are updating the port, please update the hash in the port module.')
17261722
open(fullpath, 'wb').write(data)
1727-
State.retrieved = True
17281723

17291724
def check_tag():
17301725
if is_tarbz2:
@@ -1755,28 +1750,29 @@ def unpack():
17551750
with utils.chdir(fullname):
17561751
z.extractall()
17571752

1758-
State.unpacked = True
1753+
# before acquiring the lock we have an early out if the port already exists
1754+
if os.path.exists(fullpath) and check_tag():
1755+
return
17591756

17601757
# main logic. do this under a cache lock, since we don't want multiple jobs to
17611758
# retrieve the same port at once
1762-
17631759
with shared.Cache.lock():
1764-
if not os.path.exists(fullpath):
1765-
retrieve()
1766-
1767-
if not os.path.exists(fullname):
1768-
unpack()
1769-
1770-
if not check_tag():
1771-
logger.warning('local copy of port is not correct, retrieving from remote server')
1772-
shared.try_delete(fullname)
1773-
shared.try_delete(fullpath)
1774-
retrieve()
1775-
unpack()
1776-
1777-
if State.unpacked:
1778-
# we unpacked a new version, clear the build in the cache
1779-
Ports.clear_project_build(name)
1760+
# Another early out in case another process build the library while we were
1761+
# waiting for the lock
1762+
if os.path.exists(fullpath):
1763+
if check_tag():
1764+
return
1765+
else:
1766+
# file exists but tag is bad
1767+
logger.warning('local copy of port is not correct, retrieving from remote server')
1768+
shared.try_delete(fullname)
1769+
shared.try_delete(fullpath)
1770+
1771+
retrieve()
1772+
unpack()
1773+
1774+
# we unpacked a new version, clear the build in the cache
1775+
Ports.clear_project_build(name)
17801776

17811777
@staticmethod
17821778
def clear_project_build(name):

0 commit comments

Comments
 (0)