"""This module implements a very simple locking mechanism.  This can
be used to ensure that only 1 process has access to a resource at a
time.


Functions:
acquire    Acquire a lock.
release    Release a lock.

"""

def _make_lockfile(lockname):
    #import datafile
    #return datafile.make("%s.lock" % lockname)
    import os
    import tempfile
    return os.path.join(tempfile.gettempdir(), "%s.lock" % lockname)

def acquire(lockname, blocking=1, timeout=None):
    """Acquire a lock, return value indicates success or failure."""
    import os
    import time
    lockfile = _make_lockfile(lockname)
    start = time.time()
    while 1:
        if timeout is not None and time.time() >= start+timeout:
            raise AssertionError, "Unable to acquire lock on %s: timed out" % \
                  lockname
        try:
            os.symlink("/dev/null", lockfile)
            return 1
        except OSError, x:
            pass
        if not blocking:
            return 0
    raise AssertionError, "How did I get here?"

def release(lockname):
    """Release a lock."""
    import os
    lockfile = _make_lockfile(lockname)
    try:
        # os.unlink works about 10x faster than os.rmdir
        #os.rmdir(lockfile)
        os.unlink(lockfile)
    except OSError, x:
        pass
