diff options
author | skip.montanaro <skip.montanaro@gmail.com> | 2010-11-08 01:58:08 +0000 |
---|---|---|
committer | skip.montanaro <skip.montanaro@gmail.com> | 2010-11-08 01:58:08 +0000 |
commit | ecd17a7a6329c6e52717e0145bf52571109941d7 (patch) | |
tree | 4016be174125ae4d054fac7650a05ebdb941283c | |
parent | c68688bc2f9a0d17c30c013b1e20e310472b9cd3 (diff) | |
download | lockfile-ecd17a7a6329c6e52717e0145bf52571109941d7.tar.gz |
Allow timeout in constructor - resolves issue 3
-rw-r--r-- | lockfile/__init__.py | 3 | ||||
-rw-r--r-- | lockfile/linklockfile.py | 1 | ||||
-rw-r--r-- | lockfile/mkdirlockfile.py | 5 | ||||
-rw-r--r-- | lockfile/pidlockfile.py | 5 | ||||
-rw-r--r-- | lockfile/sqlitelockfile.py | 5 | ||||
-rw-r--r-- | lockfile/symlinklockfile.py | 8 | ||||
-rw-r--r-- | test/compliancetest.py | 27 |
7 files changed, 41 insertions, 13 deletions
diff --git a/lockfile/__init__.py b/lockfile/__init__.py index 2f273be..f1188f1 100644 --- a/lockfile/__init__.py +++ b/lockfile/__init__.py @@ -154,7 +154,7 @@ class NotMyLock(UnlockError): class LockBase: """Base class for platform-specific lock classes.""" - def __init__(self, path, threaded=True): + def __init__(self, path, threaded=True, timeout=None): """ >>> lock = LockBase('somefile') >>> lock = LockBase('somefile', threaded=False) @@ -176,6 +176,7 @@ class LockBase: "%s%s.%s" % (self.hostname, self.tname, self.pid)) + self.timeout = timeout def acquire(self, timeout=None): """ diff --git a/lockfile/linklockfile.py b/lockfile/linklockfile.py index 5bfbd98..a906568 100644 --- a/lockfile/linklockfile.py +++ b/lockfile/linklockfile.py @@ -19,6 +19,7 @@ class LinkLockFile(LockBase): except IOError: raise LockFailed("failed to create %s" % self.unique_name) + timeout = timeout or self.timeout end_time = time.time() if timeout is not None and timeout > 0: end_time += timeout diff --git a/lockfile/mkdirlockfile.py b/lockfile/mkdirlockfile.py index d26076d..646311a 100644 --- a/lockfile/mkdirlockfile.py +++ b/lockfile/mkdirlockfile.py @@ -10,12 +10,12 @@ from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, class MkdirLockFile(LockBase): """Lock file by creating a directory.""" - def __init__(self, path, threaded=True): + def __init__(self, path, threaded=True, timeout=None): """ >>> lock = MkdirLockFile('somefile') >>> lock = MkdirLockFile('somefile', threaded=False) """ - LockBase.__init__(self, path, threaded) + LockBase.__init__(self, path, threaded, timeout) # Lock file itself is a directory. Place the unique file name into # it. self.unique_name = os.path.join(self.lock_file, @@ -24,6 +24,7 @@ class MkdirLockFile(LockBase): self.pid)) def acquire(self, timeout=None): + timeout = timeout or self.timeout end_time = time.time() if timeout is not None and timeout > 0: end_time += timeout diff --git a/lockfile/pidlockfile.py b/lockfile/pidlockfile.py index 4fbbbc8..3fc8f63 100644 --- a/lockfile/pidlockfile.py +++ b/lockfile/pidlockfile.py @@ -34,10 +34,10 @@ class PIDLockFile(LockBase): >>> lock = PIDLockFile('somefile') """ - def __init__(self, path, threaded=False): + def __init__(self, path, threaded=False, timeout=None): # pid lockfiles don't support threaded operation, so always force # False as the threaded arg. - LockBase.__init__(self, path, False) + LockBase.__init__(self, path, False, timeout) dirname = os.path.dirname(self.lock_file) basename = os.path.split(self.path)[-1] self.unique_name = self.path @@ -70,6 +70,7 @@ class PIDLockFile(LockBase): the lock could not be acquired. """ + timeout = timeout or self.timeout end_time = time.time() if timeout is not None and timeout > 0: end_time += timeout diff --git a/lockfile/sqlitelockfile.py b/lockfile/sqlitelockfile.py index 44ca3ed..ec75490 100644 --- a/lockfile/sqlitelockfile.py +++ b/lockfile/sqlitelockfile.py @@ -10,12 +10,12 @@ class SQLiteLockFile(LockBase): testdb = None - def __init__(self, path, threaded=True): + def __init__(self, path, threaded=True, timeout=None): """ >>> lock = SQLiteLockFile('somefile') >>> lock = SQLiteLockFile('somefile', threaded=False) """ - LockBase.__init__(self, path, threaded) + LockBase.__init__(self, path, threaded, timeout) self.lock_file = unicode(self.lock_file) self.unique_name = unicode(self.unique_name) @@ -45,6 +45,7 @@ class SQLiteLockFile(LockBase): atexit.register(os.unlink, SQLiteLockFile.testdb) def acquire(self, timeout=None): + timeout = timeout or self.timeout end_time = time.time() if timeout is not None and timeout > 0: end_time += timeout diff --git a/lockfile/symlinklockfile.py b/lockfile/symlinklockfile.py index 2266c7b..da683b9 100644 --- a/lockfile/symlinklockfile.py +++ b/lockfile/symlinklockfile.py @@ -9,9 +9,9 @@ from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, class SymlinkLockFile(LockBase): """Lock access to a file using symlink(2).""" - def __init__(self, path, threaded=True): + def __init__(self, path, threaded=True, timeout=None): # super(SymlinkLockFile).__init(...) - LockBase.__init__(self, path, threaded) + LockBase.__init__(self, path, threaded, timeout) # split it back! self.unique_name = os.path.split(self.unique_name)[1] @@ -21,13 +21,13 @@ class SymlinkLockFile(LockBase): # open(self.unique_name, "wb").close() #except IOError: # raise LockFailed("failed to create %s" % self.unique_name) - + timeout = timeout or self.timeout end_time = time.time() if timeout is not None and timeout > 0: end_time += timeout while True: - # Try and create a hard link to it. + # Try and create a symbolic link to it. try: os.symlink(self.unique_name, self.lock_file) except OSError: diff --git a/test/compliancetest.py b/test/compliancetest.py index 1cc5c99..a67675d 100644 --- a/test/compliancetest.py +++ b/test/compliancetest.py @@ -94,12 +94,35 @@ class ComplianceTest(object): e2.set() t.join() -## def test_acquire_timeout_threaded(self): -## self._test_acquire_timeout_helper(True) + def test_acquire_timeout_threaded(self): + self._test_acquire_timeout_helper(True) def test_acquire_timeout_unthreaded(self): self._test_acquire_timeout_helper(False) + def _test_context_timeout_helper(self, tbool): + # Timeout test + e1, e2 = threading.Event(), threading.Event() + t = _in_thread(self._lock_wait_unlock, e1, e2) + e1.wait() # wait for thread t to acquire lock + lock2 = lockfile.LockFile(self._testfile(), threaded=tbool, + timeout=0.2) + assert lock2.is_locked() + try: + lock2.acquire() + except lockfile.LockTimeout: + pass + else: + lock2.release() + raise AssertionError("did not raise LockTimeout in thread %s" % + threading.current_thread().get_name()) + + e2.set() + t.join() + + def test_context_timeout_unthreaded(self): + self._test_context_timeout_helper(False) + def _test_release_basic_helper(self, tbool): lock = lockfile.LockFile(self._testfile(), threaded=tbool) lock.acquire() |