mercurial/lock.py
author Vadim Gelfer <vadim.gelfer@gmail.com>
Sun, 26 Feb 2006 20:53:37 -0800
changeset 1899 888d298ddb91
parent 1787 e431344e604c
child 1836 cd5c1db2132a
permissions -rw-r--r--
many small changes to templater. get string code to parse escapes. uses eval now, should parse strings itself soon. let caller check if fragment is defined using "in". make templatepath take optional file name.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
     1
# lock.py - simple locking scheme for mercurial
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
     2
#
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
     3
# Copyright 2005 Matt Mackall <mpm@selenic.com>
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
     4
#
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
     7
1753
e6e70450edb9 Raise a different exception when the lock is not available
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
     8
import errno, os, time
422
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 161
diff changeset
     9
import util
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    10
1753
e6e70450edb9 Raise a different exception when the lock is not available
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
    11
class LockException(Exception):
e6e70450edb9 Raise a different exception when the lock is not available
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
    12
    pass
e6e70450edb9 Raise a different exception when the lock is not available
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
    13
class LockHeld(LockException):
e6e70450edb9 Raise a different exception when the lock is not available
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
    14
    pass
e6e70450edb9 Raise a different exception when the lock is not available
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
    15
class LockUnavailable(LockException):
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    16
    pass
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    17
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1530
diff changeset
    18
class lock(object):
1787
e431344e604c add a timeout when a lock is held (default 1024 sec)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1753
diff changeset
    19
    def __init__(self, file, timeout=-1, releasefn=None):
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    20
        self.f = file
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    21
        self.held = 0
1787
e431344e604c add a timeout when a lock is held (default 1024 sec)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1753
diff changeset
    22
        self.timeout = timeout
1530
abfab59fce79 add a releasefn keyword to lock.lock
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1062
diff changeset
    23
        self.releasefn = releasefn
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    24
        self.lock()
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    25
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    26
    def __del__(self):
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    27
        self.release()
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    28
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    29
    def lock(self):
1787
e431344e604c add a timeout when a lock is held (default 1024 sec)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1753
diff changeset
    30
        timeout = self.timeout
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    31
        while 1:
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    32
            try:
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    33
                self.trylock()
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    34
                return 1
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    35
            except LockHeld, inst:
1787
e431344e604c add a timeout when a lock is held (default 1024 sec)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1753
diff changeset
    36
                if timeout != 0:
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    37
                    time.sleep(1)
1787
e431344e604c add a timeout when a lock is held (default 1024 sec)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1753
diff changeset
    38
                    if timeout > 0:
e431344e604c add a timeout when a lock is held (default 1024 sec)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1753
diff changeset
    39
                        timeout -= 1
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    40
                    continue
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    41
                raise inst
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 503
diff changeset
    42
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    43
    def trylock(self):
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    44
        pid = os.getpid()
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    45
        try:
422
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 161
diff changeset
    46
            util.makelock(str(pid), self.f)
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    47
            self.held = 1
1753
e6e70450edb9 Raise a different exception when the lock is not available
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
    48
        except (OSError, IOError), why:
e6e70450edb9 Raise a different exception when the lock is not available
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
    49
            if why.errno == errno.EEXIST:
e6e70450edb9 Raise a different exception when the lock is not available
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
    50
                raise LockHeld(util.readlock(self.f))
e6e70450edb9 Raise a different exception when the lock is not available
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
    51
            else:
e6e70450edb9 Raise a different exception when the lock is not available
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1559
diff changeset
    52
                raise LockUnavailable(why)
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    53
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    54
    def release(self):
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    55
        if self.held:
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    56
            self.held = 0
1530
abfab59fce79 add a releasefn keyword to lock.lock
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1062
diff changeset
    57
            if self.releasefn:
abfab59fce79 add a releasefn keyword to lock.lock
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1062
diff changeset
    58
                self.releasefn()
503
c6a2e41c8c60 Fix troubles with clone and exception handling
mpm@selenic.com
parents: 429
diff changeset
    59
            try:
c6a2e41c8c60 Fix troubles with clone and exception handling
mpm@selenic.com
parents: 429
diff changeset
    60
                os.unlink(self.f)
c6a2e41c8c60 Fix troubles with clone and exception handling
mpm@selenic.com
parents: 429
diff changeset
    61
            except: pass
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    62