Use flock()
authorPeter Palfrader <peter@palfrader.org>
Mon, 12 Mar 2012 15:16:28 +0000 (16:16 +0100)
committerPeter Palfrader <peter@palfrader.org>
Mon, 12 Mar 2012 15:16:28 +0000 (16:16 +0100)
debian/changelog
ud-generate

index 57f4daf..569eb31 100644 (file)
@@ -46,6 +46,7 @@ userdir-ldap (0.3.80) UNRELEASED; urgency=low
     - UDLdap.py: make a cache for __getitem__() decisions.
     - wrap cdbmake calls in eatmydata.  Nothing else does any fsync stuff,
       so doing it here just costs a lot.
+  * ud-generate: Use a flock() lock instead of python's lockfile class.
 
   [ Stephen Gran ]
   * Fix deprecation warnings for sha module by using hashlib module instead
@@ -58,7 +59,7 @@ userdir-ldap (0.3.80) UNRELEASED; urgency=low
   * ud-replicate: set correct permissions for web-passwords
   * add freecdb to depends
 
- -- Peter Palfrader <weasel@debian.org>  Mon, 12 Mar 2012 15:51:06 +0100
+ -- Peter Palfrader <weasel@debian.org>  Mon, 12 Mar 2012 16:15:13 +0100
 
 userdir-ldap (0.3.79) unstable; urgency=low
 
index badef2f..fd6a16b 100755 (executable)
@@ -28,8 +28,7 @@
 #   along with this program; if not, write to the Free Software
 #   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-import string, re, time, ldap, optparse, sys, os, pwd, posix, socket, base64, hashlib, shutil, errno, tarfile, grp
-import lockfile
+import string, re, time, ldap, optparse, sys, os, pwd, posix, socket, base64, hashlib, shutil, errno, tarfile, grp, fcntl
 from userdir_ldap import *
 from userdir_exceptions import *
 import UDLdap
@@ -89,25 +88,23 @@ def safe_rmtree(dir):
       else:
          raise e
 
-def get_lock(fn, wait=5*60, max_age=3600*6):
-   try:
-      stat = os.stat(fn + '.lock')
-      if stat.st_mtime < time.time() - max_age:
-         sys.stderr.write("Removing stale lock %s"%(fn + '.lock'))
-         os.unlink(fn + '.lock')
-   except OSError, error:
-      if error.errno == errno.ENOENT:
-         pass
-      else:
-         raise
+def get_lock(fn, wait=5*60):
+   f = open(fn, "w")
+   sl = 0.1
+   ends = time.time() + wait
 
-   lock = lockfile.FileLock(fn)
-   try:
-      lock.acquire(timeout=wait)
-   except lockfile.LockTimeout:
-      return None
-
-   return lock
+   while True:
+      success = False
+      try:
+         fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
+         return f
+      except IOError:
+         pass
+      if time.time() >= ends:
+         return None
+      sl = min(sl*2, 10, ends - time.time())
+      time.sleep(sl)
+   return None
 
 
 def Sanitize(Str):
@@ -1317,7 +1314,7 @@ def ud_generate():
 
    finally:
       if lock is not None:
-         lock.release()
+         lock.close()
 
 if __name__ == "__main__":
    ud_generate()