Add bb.utils.lockfile() and bb.utils.unlockfile() from Poky. Use these functions...
authorRichard Purdie <rpurdie@linux.intel.com>
Sat, 24 Nov 2007 18:15:49 +0000 (18:15 +0000)
committerRichard Purdie <rpurdie@linux.intel.com>
Sat, 24 Nov 2007 18:15:49 +0000 (18:15 +0000)
ChangeLog
lib/bb/fetch/__init__.py
lib/bb/utils.py

index 55e1f77..4fddeca 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -24,6 +24,7 @@ Changes in BitBake 1.8.x:
        - Add BB_GENERATE_MIRROR_TARBALLS option, set to 0 to make git fetches 
          faster at the expense of not creating mirror tarballs.
        - SRCREV handling updates, improvements and fixes from Poky
+       - Add bb.utils.lockfile() and bb.utils.unlockfile() from Poky
 
 Changes in Bitbake 1.8.8:
        - Rewrite svn fetcher to make adding extra operations easier 
index 4da9211..d75c618 100644 (file)
@@ -141,21 +141,18 @@ def go(d):
                 # Touch md5 file to show activity
                 os.utime(ud.md5, None)
                 continue
-            lf = open(ud.lockfile, "a+")
-            fcntl.flock(lf.fileno(), fcntl.LOCK_EX)
+            lf = bb.utils.lockfile(ud.lockfile)
             if not m.forcefetch(u, ud, d) and os.path.exists(ud.md5):
                 # If someone else fetched this before we got the lock, 
                 # notice and don't try again
                 os.utime(ud.md5, None)
-                fcntl.flock(lf.fileno(), fcntl.LOCK_UN)
-                lf.close
+                bb.utils.unlockfile(lf)
                 continue
         m.go(u, ud, d)
         if ud.localfile:
             if not m.forcefetch(u, ud, d):
                 Fetch.write_md5sum(u, ud, d)
-            fcntl.flock(lf.fileno(), fcntl.LOCK_UN)
-            lf.close
+            bb.utils.unlockfile(lf)
 
 def localpaths(d):
     """
index c2884f2..c27dafd 100644 (file)
@@ -22,7 +22,7 @@ BitBake Utility Functions
 digits = "0123456789"
 ascii_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
-import re
+import re, fcntl, os
 
 def explode_version(s):
     r = []
@@ -202,3 +202,38 @@ def Enum(*names):
    constants = tuple(constants)
    EnumType = EnumClass()
    return EnumType
+
+def lockfile(name):
+    """
+    Use the file fn as a lock file, return when the lock has been aquired.
+    Returns a variable to pass to unlockfile().
+    """
+    while True:
+        # If we leave the lockfiles lying around there is no problem
+        # but we should clean up after ourselves. This gives potential
+        # for races though. To work around this, when we aquire the lock 
+        # we check the file we locked was still the lock file on disk. 
+        # by comparing inode numbers. If they don't match or the lockfile 
+        # no longer exists, we start again.
+
+        # This implementation is unfair since the last person to request the 
+        # lock is the most likely to win it.
+
+        lf = open(name, "a+")
+        fcntl.flock(lf.fileno(), fcntl.LOCK_EX)
+        statinfo = os.fstat(lf.fileno())
+        if os.path.exists(lf.name):
+           statinfo2 = os.stat(lf.name)
+           if statinfo.st_ino == statinfo2.st_ino:
+               return lf
+        # File no longer exists or changed, retry
+        lf.close
+
+def unlockfile(lf):
+    """
+    Unlock a file locked using lockfile()                              
+    """
+    os.unlink(lf.name)
+    fcntl.flock(lf.fileno(), fcntl.LOCK_UN)
+    lf.close
+