X-Git-Url: https://git.distorted.org.uk/~mdw/chopwood/blobdiff_plain/d9ca01b99b8476719e958e0c6ec0a9fcda348e51..e32b221f0be6c37d2a4e6c9dce616e1eb11fdc6d:/backend.py diff --git a/backend.py b/backend.py index 576486c..fda32e0 100644 --- a/backend.py +++ b/backend.py @@ -25,6 +25,8 @@ from __future__ import with_statement +from auto import HOME +import errno as E import itertools as I import os as OS; ENV = OS.environ @@ -206,10 +208,13 @@ class FlatFileBackend (object): specified by the DELIM constructor argument. The file is updated by writing a new version alongside, as `FILE.new', and - renaming it over the old version. If a LOCK file is named then an - exclusive fcntl(2)-style lock is taken out on `LOCKDIR/LOCK' (creating the - file if necessary) during the update operation. Use of a lockfile is - strongly recommended. + renaming it over the old version. If a LOCK is provided then this is done + while holding a lock. By default, an exclusive fcntl(2)-style lock is + taken out on `LOCKDIR/LOCK' (creating the file if necessary) during the + update operation, but subclasses can override the `dolocked' method to + provide alternative locking behaviour; the LOCK parameter is not + interpreted by any other methods. Use of a lockfile is strongly + recommended. The DELIM constructor argument specifies the delimiter character used when splitting lines into fields. The USER and PASSWD arguments give the field @@ -329,11 +334,21 @@ class FlatFileBackend (object): ## If there's a lockfile, then acquire it around the meat of this ## function; otherwise just do the job. - if me._lock is None: - doit() - else: - with U.lockfile(OS.path.join(CFG.LOCKDIR, me._lock), 5): - doit() + if me._lock is None: doit() + else: me.dolocked(me._lock, doit) + + def dolocked(me, lock, func): + """ + Call FUNC with the LOCK held. + + Subclasses can override this method in order to provide alternative + locking functionality. + """ + try: OS.mkdir(CFG.LOCKDIR) + except OSError, e: + if e.errno != E.EEXIST: raise + with U.lockfile(OS.path.join(CFG.LOCKDIR, lock), 5): + func() def _parse(me, line): """Convenience function for constructing a record."""