~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/lockfile/lockfile/mkdirlockfile.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from __future__ import absolute_import, division
 
2
 
 
3
import time
 
4
import os
 
5
import sys
 
6
import errno
 
7
 
 
8
from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout,
 
9
               AlreadyLocked)
 
10
 
 
11
class MkdirLockFile(LockBase):
 
12
    """Lock file by creating a directory."""
 
13
    def __init__(self, path, threaded=True):
 
14
        """
 
15
        >>> lock = MkdirLockFile('somefile')
 
16
        >>> lock = MkdirLockFile('somefile', threaded=False)
 
17
        """
 
18
        LockBase.__init__(self, path, threaded)
 
19
        # Lock file itself is a directory.  Place the unique file name into
 
20
        # it.
 
21
        self.unique_name  = os.path.join(self.lock_file,
 
22
                                         "%s.%s%s" % (self.hostname,
 
23
                                                      self.tname,
 
24
                                                      self.pid))
 
25
 
 
26
    def acquire(self, timeout=None):
 
27
        end_time = time.time()
 
28
        if timeout is not None and timeout > 0:
 
29
            end_time += timeout
 
30
 
 
31
        if timeout is None:
 
32
            wait = 0.1
 
33
        else:
 
34
            wait = max(0, timeout / 10)
 
35
 
 
36
        while True:
 
37
            try:
 
38
                os.mkdir(self.lock_file)
 
39
            except OSError:
 
40
                err = sys.exc_info()[1]
 
41
                if err.errno == errno.EEXIST:
 
42
                    # Already locked.
 
43
                    if os.path.exists(self.unique_name):
 
44
                        # Already locked by me.
 
45
                        return
 
46
                    if timeout is not None and time.time() > end_time:
 
47
                        if timeout > 0:
 
48
                            raise LockTimeout
 
49
                        else:
 
50
                            # Someone else has the lock.
 
51
                            raise AlreadyLocked
 
52
                    time.sleep(wait)
 
53
                else:
 
54
                    # Couldn't create the lock for some other reason
 
55
                    raise LockFailed("failed to create %s" % self.lock_file)
 
56
            else:
 
57
                open(self.unique_name, "wb").close()
 
58
                return
 
59
 
 
60
    def release(self):
 
61
        if not self.is_locked():
 
62
            raise NotLocked
 
63
        elif not os.path.exists(self.unique_name):
 
64
            raise NotMyLock
 
65
        os.unlink(self.unique_name)
 
66
        os.rmdir(self.lock_file)
 
67
 
 
68
    def is_locked(self):
 
69
        return os.path.exists(self.lock_file)
 
70
 
 
71
    def i_am_locking(self):
 
72
        return (self.is_locked() and
 
73
                os.path.exists(self.unique_name))
 
74
 
 
75
    def break_lock(self):
 
76
        if os.path.exists(self.lock_file):
 
77
            for name in os.listdir(self.lock_file):
 
78
                os.unlink(os.path.join(self.lock_file, name))
 
79
            os.rmdir(self.lock_file)