From fc1a1870b5b4e1ef5a555426acd762f19387a57b Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 28 Nov 2011 01:55:01 +0000 Subject: [PATCH] lit/TestRunner.py: [Win32] Introduce WinWaitReleased(f), to wait for file handles to be released by children. When wait() has finished, opened handles (especially writing stdout to file) might not be released immediately. To wait for released, poll to attempt renaming. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145222 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/lit/lit/TestRunner.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/utils/lit/lit/TestRunner.py b/utils/lit/lit/TestRunner.py index f5f7c19891b..b450c33df62 100644 --- a/utils/lit/lit/TestRunner.py +++ b/utils/lit/lit/TestRunner.py @@ -23,6 +23,41 @@ kUseCloseFDs = not kIsWindows # Use temporary files to replace /dev/null on Windows. kAvoidDevNull = kIsWindows +def RemoveForce(f): + try: + os.remove(f) + except OSError: + pass + +def WinRename(f_o, f_n): + import time + retry_cnt = 256 + while (True): + try: + os.rename(f_o, f_n) + break + except WindowsError, (winerror, strerror): + retry_cnt = retry_cnt - 1 + if retry_cnt <= 0: + raise + elif winerror == 32: # ERROR_SHARING_VIOLATION + time.sleep(0.01) + else: + raise + +def WinWaitReleased(f): + import random + t = "%s%06d" % (f, random.randint(0, 999999)) + RemoveForce(t) + try: + WinRename(f, t) # rename + WinRename(t, f) # restore + except WindowsError, (winerror, strerror): + if winerror == 3: # ERROR_PATH_NOT_FOUND + pass + else: + raise + def executeCommand(command, cwd=None, env=None): p = subprocess.Popen(command, cwd=cwd, stdin=subprocess.PIPE, @@ -68,6 +103,7 @@ def executeShCmd(cmd, cfg, cwd, results): input = subprocess.PIPE stderrTempFiles = [] opened_files = [] + written_files = [] named_temp_files = [] # To avoid deadlock, we use a single stderr stream for piped # output. This is null until we have seen some output using @@ -124,6 +160,8 @@ def executeShCmd(cmd, cfg, cwd, results): if r[1] == 'a': r[2].seek(0, 2) opened_files.append(r[2]) + if r[1] in 'aw': + written_files.append(r[0]) result = r[2] final_redirects.append(result) @@ -224,6 +262,11 @@ def executeShCmd(cmd, cfg, cwd, results): else: exitCode = res + # Make sure written_files is released by other (child) processes. + if (kIsWindows): + for f in written_files: + WinWaitReleased(f) + # Remove any named temporary files we created. for f in named_temp_files: try: -- 2.11.0