Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Unified Diff: build/extract_from_cab.py

Issue 8890072: Yet another fix for concurrent calls to expand.exe. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ToT sync Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/extract_from_cab.py
diff --git a/build/extract_from_cab.py b/build/extract_from_cab.py
index d04bcfd14aa6c25ec2a56d3d4527ff6de58b08b2..d5410d64d8e6a0af24508da30345222c07e82377 100755
--- a/build/extract_from_cab.py
+++ b/build/extract_from_cab.py
@@ -6,29 +6,11 @@
"""Extracts a single file from a CAB archive."""
import os
+import shutil
import subprocess
import sys
import tempfile
-lock_file = os.path.join(tempfile.gettempdir(), 'expand.lock')
-
-
-def acquire_lock():
- while True:
- try:
- fd = os.open(lock_file, os.O_CREAT | os.O_EXCL | os.O_RDWR)
- return fd
- except OSError as e:
- if e.errno != errno.EEXIST:
- raise
- print 'Cab extraction could not get exclusive lock. Retrying in 100ms...'
- time.sleep(0.1)
-
-
-def release_lock(fd):
- os.close(fd)
- os.unlink(lock_file)
-
def main():
if len(sys.argv) != 4:
@@ -37,15 +19,30 @@ def main():
[cab_path, archived_file, output_dir] = sys.argv[1:]
- lock_fd = acquire_lock()
+ # Expand.exe does its work in a fixed-named temporary directory created within
+ # the given output directory. This is a problem for concurrent extractions, so
+ # create a unique temp dir within the desired output directory to work around
+ # this limitation.
+ temp_dir = tempfile.mkdtemp(dir=output_dir)
+
try:
# Invoke the Windows expand utility to extract the file.
level = subprocess.call(
- ['expand', cab_path, '-F:' + archived_file, output_dir])
- if level != 0:
- return level
+ ['expand', cab_path, '-F:' + archived_file, temp_dir])
+ if level == 0:
+ # Move the output file into place, preserving expand.exe's behavior of
+ # paving over any preexisting file.
+ output_file = os.path.join(output_dir, archived_file)
+ try:
+ os.remove(output_file)
+ except OSError:
+ pass
+ os.rename(os.path.join(temp_dir, archived_file), output_file)
finally:
- release_lock(lock_fd)
+ shutil.rmtree(temp_dir, True)
+
+ if level != 0:
+ return level
# The expand utility preserves the modification date and time of the archived
# file. Touch the extracted file. This helps build systems that compare the
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698