~cbehrens/nova/lp844160-build-works-with-zones

« back to all changes in this revision

Viewing changes to vendor/lockfile/lockfile/sqlitelockfile.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
 
 
6
from . import LockBase, NotLocked, NotMyLock, LockTimeout, AlreadyLocked
 
7
 
 
8
class SQLiteLockFile(LockBase):
 
9
    "Demonstrate SQL-based locking."
 
10
 
 
11
    import tempfile
 
12
    _fd, testdb = tempfile.mkstemp()
 
13
    os.close(_fd)
 
14
    os.unlink(testdb)
 
15
    del _fd, tempfile
 
16
 
 
17
    def __init__(self, path, threaded=True):
 
18
        """
 
19
        >>> lock = SQLiteLockFile('somefile')
 
20
        >>> lock = SQLiteLockFile('somefile', threaded=False)
 
21
        """
 
22
        LockBase.__init__(self, path, threaded)
 
23
        self.lock_file = unicode(self.lock_file)
 
24
        self.unique_name = unicode(self.unique_name)
 
25
 
 
26
        import sqlite3
 
27
        self.connection = sqlite3.connect(SQLiteLockFile.testdb)
 
28
        
 
29
        c = self.connection.cursor()
 
30
        try:
 
31
            c.execute("create table locks"
 
32
                      "("
 
33
                      "   lock_file varchar(32),"
 
34
                      "   unique_name varchar(32)"
 
35
                      ")")
 
36
        except sqlite3.OperationalError:
 
37
            pass
 
38
        else:
 
39
            self.connection.commit()
 
40
            import atexit
 
41
            atexit.register(os.unlink, SQLiteLockFile.testdb)
 
42
 
 
43
    def acquire(self, timeout=None):
 
44
        end_time = time.time()
 
45
        if timeout is not None and timeout > 0:
 
46
            end_time += timeout
 
47
 
 
48
        if timeout is None:
 
49
            wait = 0.1
 
50
        elif timeout <= 0:
 
51
            wait = 0
 
52
        else:
 
53
            wait = timeout / 10
 
54
 
 
55
        cursor = self.connection.cursor()
 
56
 
 
57
        while True:
 
58
            if not self.is_locked():
 
59
                # Not locked.  Try to lock it.
 
60
                cursor.execute("insert into locks"
 
61
                               "  (lock_file, unique_name)"
 
62
                               "  values"
 
63
                               "  (?, ?)",
 
64
                               (self.lock_file, self.unique_name))
 
65
                self.connection.commit()
 
66
 
 
67
                # Check to see if we are the only lock holder.
 
68
                cursor.execute("select * from locks"
 
69
                               "  where unique_name = ?",
 
70
                               (self.unique_name,))
 
71
                rows = cursor.fetchall()
 
72
                if len(rows) > 1:
 
73
                    # Nope.  Someone else got there.  Remove our lock.
 
74
                    cursor.execute("delete from locks"
 
75
                                   "  where unique_name = ?",
 
76
                                   (self.unique_name,))
 
77
                    self.connection.commit()
 
78
                else:
 
79
                    # Yup.  We're done, so go home.
 
80
                    return
 
81
            else:
 
82
                # Check to see if we are the only lock holder.
 
83
                cursor.execute("select * from locks"
 
84
                               "  where unique_name = ?",
 
85
                               (self.unique_name,))
 
86
                rows = cursor.fetchall()
 
87
                if len(rows) == 1:
 
88
                    # We're the locker, so go home.
 
89
                    return
 
90
                    
 
91
            # Maybe we should wait a bit longer.
 
92
            if timeout is not None and time.time() > end_time:
 
93
                if timeout > 0:
 
94
                    # No more waiting.
 
95
                    raise LockTimeout
 
96
                else:
 
97
                    # Someone else has the lock and we are impatient..
 
98
                    raise AlreadyLocked
 
99
 
 
100
            # Well, okay.  We'll give it a bit longer.
 
101
            time.sleep(wait)
 
102
 
 
103
    def release(self):
 
104
        if not self.is_locked():
 
105
            raise NotLocked
 
106
        if not self.i_am_locking():
 
107
            raise NotMyLock((self._who_is_locking(), self.unique_name))
 
108
        cursor = self.connection.cursor()
 
109
        cursor.execute("delete from locks"
 
110
                       "  where unique_name = ?",
 
111
                       (self.unique_name,))
 
112
        self.connection.commit()
 
113
 
 
114
    def _who_is_locking(self):
 
115
        cursor = self.connection.cursor()
 
116
        cursor.execute("select unique_name from locks"
 
117
                       "  where lock_file = ?",
 
118
                       (self.lock_file,))
 
119
        return cursor.fetchone()[0]
 
120
        
 
121
    def is_locked(self):
 
122
        cursor = self.connection.cursor()
 
123
        cursor.execute("select * from locks"
 
124
                       "  where lock_file = ?",
 
125
                       (self.lock_file,))
 
126
        rows = cursor.fetchall()
 
127
        return not not rows
 
128
 
 
129
    def i_am_locking(self):
 
130
        cursor = self.connection.cursor()
 
131
        cursor.execute("select * from locks"
 
132
                       "  where lock_file = ?"
 
133
                       "    and unique_name = ?",
 
134
                       (self.lock_file, self.unique_name))
 
135
        return not not cursor.fetchall()
 
136
 
 
137
    def break_lock(self):
 
138
        cursor = self.connection.cursor()
 
139
        cursor.execute("delete from locks"
 
140
                       "  where lock_file = ?",
 
141
                       (self.lock_file,))
 
142
        self.connection.commit()