bug 522804 - fix two more JarMaker lockFile race conditions on Windows. r=pike
authorTed Mielczarek <ted.mielczarek@gmail.com>
Tue, 24 Nov 2009 07:11:25 -0500
changeset 35217 941ad9d7d079246481f365c3cfbfc75a5bbefc94
parent 35216 b85c66115cd2699af8680e89b3bf3a540770ac70
child 35218 21e65793a3ccd94aac98baffe39a55e9be7ed7c7
child 36108 133d4a382af1cc2d7ab028fb93b32951dc03853b
push id10494
push usertmielczarek@mozilla.com
push dateTue, 24 Nov 2009 12:12:31 +0000
treeherdermozilla-central@941ad9d7d079 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspike
bugs522804
milestone1.9.3a1pre
bug 522804 - fix two more JarMaker lockFile race conditions on Windows. r=pike
config/utils.py
--- a/config/utils.py
+++ b/config/utils.py
@@ -48,18 +48,29 @@ class LockFile(object):
   '''LockFile is used by the lockFile method to hold the lock.
 
   This object should not be used directly, but only through
   the lockFile method below.
   '''
   def __init__(self, lockfile):
     self.lockfile = lockfile
   def __del__(self):
-    os.remove(self.lockfile)
-
+    while True:
+      try:
+        os.remove(self.lockfile)
+        break
+      except OSError, e:
+        if e.errno == errno.EACCES:
+          # another process probably has the file open, we'll retry.
+          # just a short sleep since we want to drop the lock ASAP
+          # (but we need to let some other process close the file first)
+          time.sleep(0.1)
+        else:
+          # re-raise unknown errors
+          raise
 
 def lockFile(lockfile, max_wait = 600):
   '''Create and hold a lockfile of the given name, with the given timeout.
 
   To release the lock, delete the returned object.
   '''
   while True:
     try:
@@ -75,28 +86,29 @@ def lockFile(lockfile, max_wait = 600):
         raise
   
     try:
       # the lock file exists, try to stat it to get its age
       # and read its contents to report the owner PID
       f = open(lockfile, "r")
       s = os.stat(lockfile)
     except EnvironmentError, e:
-      if e.errno != errno.ENOENT:
-        sys.exit("%s exists but stat() failed: %s" %
-                 (lockfile, e.strerror))
-      # we didn't create the lockfile, so it did exist, but it's
-      # gone now. Just try again
-      continue
+      if e.errno == errno.ENOENT or \
+         (sys.platform == "win32" and e.errno == errno.EACCES):
+        # we didn't create the lockfile, so it did exist, but it's
+        # gone now. Just try again
+        continue
+      sys.exit("%s exists but stat() failed: %s" %
+               (lockfile, e.strerror))
   
     # we didn't create the lockfile and it's still there, check
     # its age
     now = int(time.time())
     if now - s[stat.ST_MTIME] > max_wait:
-      pid = f.readline()
+      pid = f.readline().rstrip()
       sys.exit("%s has been locked for more than " \
                "%d seconds (PID %s)" % (lockfile, max_wait,
                                         pid))
   
     # it's not been locked too long, wait a while and retry
     f.close()
     time.sleep(1)