author | Martijn Pieters <mj@zopatista.com> |
Wed, 01 Aug 2018 16:05:41 +0200 | |
changeset 38797 | 8751d1e2a7ff |
parent 38239 | ead71b15efd5 |
child 43076 | 2372284d9457 |
permissions | -rw-r--r-- |
9309
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
1 |
# lock.py - simple advisory locking scheme for mercurial |
161 | 2 |
# |
2859 | 3 |
# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> |
161 | 4 |
# |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8113
diff
changeset
|
5 |
# This software may be used and distributed according to the terms of the |
10263 | 6 |
# GNU General Public License version 2 or any later version. |
161 | 7 |
|
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
8 |
from __future__ import absolute_import |
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
9 |
|
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
10 |
import contextlib |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
11 |
import errno |
30921
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30920
diff
changeset
|
12 |
import os |
36701
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
13 |
import signal |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
14 |
import socket |
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
15 |
import time |
8113
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
16 |
import warnings |
161 | 17 |
|
35208
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
18 |
from .i18n import _ |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
19 |
|
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
20 |
from . import ( |
31375
d57aa655ce97
lock: encode result of gethostname into a bytestring
Augie Fackler <augie@google.com>
parents:
31354
diff
changeset
|
21 |
encoding, |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
22 |
error, |
30921
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30920
diff
changeset
|
23 |
pycompat, |
38038
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
24 |
util, |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36701
diff
changeset
|
25 |
) |
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36701
diff
changeset
|
26 |
|
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36701
diff
changeset
|
27 |
from .utils import ( |
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36701
diff
changeset
|
28 |
procutil, |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
29 |
) |
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
30 |
|
30920
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
31 |
def _getlockprefix(): |
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
32 |
"""Return a string which is used to differentiate pid namespaces |
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
33 |
|
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
34 |
It's useful to detect "dead" processes and remove stale locks with |
30921
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30920
diff
changeset
|
35 |
confidence. Typically it's just hostname. On modern linux, we include an |
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30920
diff
changeset
|
36 |
extra Linux-specific pid namespace identifier. |
30920
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
37 |
""" |
35897
4b1c04082cdc
py3: replace "if ispy3" by encoding.strtolocal()
Yuya Nishihara <yuya@tcha.org>
parents:
35209
diff
changeset
|
38 |
result = encoding.strtolocal(socket.gethostname()) |
30921
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30920
diff
changeset
|
39 |
if pycompat.sysplatform.startswith('linux'): |
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30920
diff
changeset
|
40 |
try: |
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30920
diff
changeset
|
41 |
result += '/%x' % os.stat('/proc/self/ns/pid').st_ino |
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30920
diff
changeset
|
42 |
except OSError as ex: |
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30920
diff
changeset
|
43 |
if ex.errno not in (errno.ENOENT, errno.EACCES, errno.ENOTDIR): |
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30920
diff
changeset
|
44 |
raise |
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30920
diff
changeset
|
45 |
return result |
30920
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
46 |
|
36701
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
47 |
@contextlib.contextmanager |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
48 |
def _delayedinterrupt(): |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
49 |
"""Block signal interrupt while doing something critical |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
50 |
|
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
51 |
This makes sure that the code block wrapped by this context manager won't |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
52 |
be interrupted. |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
53 |
|
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
54 |
For Windows developers: It appears not possible to guard time.sleep() |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
55 |
from CTRL_C_EVENT, so please don't use time.sleep() to test if this is |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
56 |
working. |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
57 |
""" |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
58 |
assertedsigs = [] |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
59 |
blocked = False |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
60 |
orighandlers = {} |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
61 |
|
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
62 |
def raiseinterrupt(num): |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
63 |
if (num == getattr(signal, 'SIGINT', None) or |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
64 |
num == getattr(signal, 'CTRL_C_EVENT', None)): |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
65 |
raise KeyboardInterrupt |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
66 |
else: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
67 |
raise error.SignalInterrupt |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
68 |
def catchterm(num, frame): |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
69 |
if blocked: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
70 |
assertedsigs.append(num) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
71 |
else: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
72 |
raiseinterrupt(num) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
73 |
|
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
74 |
try: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
75 |
# save handlers first so they can be restored even if a setup is |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
76 |
# interrupted between signal.signal() and orighandlers[] =. |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
77 |
for name in ['CTRL_C_EVENT', 'SIGINT', 'SIGBREAK', 'SIGHUP', 'SIGTERM']: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
78 |
num = getattr(signal, name, None) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
79 |
if num and num not in orighandlers: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
80 |
orighandlers[num] = signal.getsignal(num) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
81 |
try: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
82 |
for num in orighandlers: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
83 |
signal.signal(num, catchterm) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
84 |
except ValueError: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
85 |
pass # in a thread? no luck |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
86 |
|
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
87 |
blocked = True |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
88 |
yield |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
89 |
finally: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
90 |
# no simple way to reliably restore all signal handlers because |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
91 |
# any loops, recursive function calls, except blocks, etc. can be |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
92 |
# interrupted. so instead, make catchterm() raise interrupt. |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
93 |
blocked = False |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
94 |
try: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
95 |
for num, handler in orighandlers.items(): |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
96 |
signal.signal(num, handler) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
97 |
except ValueError: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
98 |
pass # in a thread? |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
99 |
|
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
100 |
# re-raise interrupt exception if any, which may be shadowed by a new |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
101 |
# interrupt occurred while re-raising the first one |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
102 |
if assertedsigs: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
103 |
raiseinterrupt(assertedsigs[0]) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
104 |
|
35209
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35208
diff
changeset
|
105 |
def trylock(ui, vfs, lockname, timeout, warntimeout, *args, **kwargs): |
35208
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
106 |
"""return an acquired lock or raise an a LockHeld exception |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
107 |
|
35209
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35208
diff
changeset
|
108 |
This function is responsible to issue warnings and or debug messages about |
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35208
diff
changeset
|
109 |
the held lock while trying to acquires it.""" |
35208
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
110 |
|
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
111 |
def printwarning(printer, locker): |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
112 |
"""issue the usual "waiting on lock" message through any channel""" |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
113 |
# show more details for new-style locks |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
114 |
if ':' in locker: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
115 |
host, pid = locker.split(":", 1) |
36642
f6efb3c08c19
py3: fix formatting of lock error message
Yuya Nishihara <yuya@tcha.org>
parents:
36640
diff
changeset
|
116 |
msg = (_("waiting for lock on %s held by process %r on host %r\n") |
f6efb3c08c19
py3: fix formatting of lock error message
Yuya Nishihara <yuya@tcha.org>
parents:
36640
diff
changeset
|
117 |
% (pycompat.bytestr(l.desc), pycompat.bytestr(pid), |
f6efb3c08c19
py3: fix formatting of lock error message
Yuya Nishihara <yuya@tcha.org>
parents:
36640
diff
changeset
|
118 |
pycompat.bytestr(host))) |
35208
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
119 |
else: |
36642
f6efb3c08c19
py3: fix formatting of lock error message
Yuya Nishihara <yuya@tcha.org>
parents:
36640
diff
changeset
|
120 |
msg = (_("waiting for lock on %s held by %r\n") |
f6efb3c08c19
py3: fix formatting of lock error message
Yuya Nishihara <yuya@tcha.org>
parents:
36640
diff
changeset
|
121 |
% (l.desc, pycompat.bytestr(locker))) |
35208
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
122 |
printer(msg) |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
123 |
|
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
124 |
l = lock(vfs, lockname, 0, *args, dolock=False, **kwargs) |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
125 |
|
35209
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35208
diff
changeset
|
126 |
debugidx = 0 if (warntimeout and timeout) else -1 |
35208
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
127 |
warningidx = 0 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
128 |
if not timeout: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
129 |
warningidx = -1 |
35209
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35208
diff
changeset
|
130 |
elif warntimeout: |
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35208
diff
changeset
|
131 |
warningidx = warntimeout |
35208
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
132 |
|
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
133 |
delay = 0 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
134 |
while True: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
135 |
try: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
136 |
l._trylock() |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
137 |
break |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
138 |
except error.LockHeld as inst: |
35209
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35208
diff
changeset
|
139 |
if delay == debugidx: |
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35208
diff
changeset
|
140 |
printwarning(ui.debug, inst.locker) |
35208
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
141 |
if delay == warningidx: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
142 |
printwarning(ui.warn, inst.locker) |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
143 |
if timeout <= delay: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
144 |
raise error.LockHeld(errno.ETIMEDOUT, inst.filename, |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
145 |
l.desc, inst.locker) |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
146 |
time.sleep(1) |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
147 |
delay += 1 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
148 |
|
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
149 |
l.delay = delay |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
150 |
if l.delay: |
35209
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35208
diff
changeset
|
151 |
if 0 <= warningidx <= l.delay: |
36319
c303eda316be
lock: delay is numeric, use %d for formatting
Augie Fackler <augie@google.com>
parents:
35897
diff
changeset
|
152 |
ui.warn(_("got lock after %d seconds\n") % l.delay) |
35209
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35208
diff
changeset
|
153 |
else: |
36319
c303eda316be
lock: delay is numeric, use %d for formatting
Augie Fackler <augie@google.com>
parents:
35897
diff
changeset
|
154 |
ui.debug("got lock after %d seconds\n" % l.delay) |
35208
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
155 |
if l.acquirefn: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
156 |
l.acquirefn() |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
157 |
return l |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
158 |
|
1559
59b3639df0a9
Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents:
1530
diff
changeset
|
159 |
class lock(object): |
9309
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
160 |
'''An advisory lock held by one process to control access to a set |
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
161 |
of files. Non-cooperating processes or incorrectly written scripts |
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
162 |
can ignore Mercurial's locking scheme and stomp all over the |
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
163 |
repository, so don't do that. |
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
164 |
|
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
165 |
Typically used via localrepository.lock() to lock the repository |
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
166 |
store (.hg/store/) or localrepository.wlock() to lock everything |
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
167 |
else under .hg/.''' |
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
168 |
|
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
169 |
# lock is symlink on platforms that support it, file on others. |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
170 |
|
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
171 |
# symlink is used because create of directory entry and contents |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
172 |
# are atomic even over nfs. |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
173 |
|
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
174 |
# old-style lock: symlink to pid |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
175 |
# new-style lock: symlink to hostname:pid |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
176 |
|
4947
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
177 |
_host = None |
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
178 |
|
37659
575f59cdd8a1
lock: don't use 'file' as a variable name
Pulkit Goyal <7895pulkit@gmail.com>
parents:
37658
diff
changeset
|
179 |
def __init__(self, vfs, fname, timeout=-1, releasefn=None, acquirefn=None, |
35208
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
180 |
desc=None, inheritchecker=None, parentlock=None, |
38038
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
181 |
signalsafe=True, dolock=True): |
20091
abfe6a8e619b
lock: take both vfs and lock file path relative to vfs to access via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19927
diff
changeset
|
182 |
self.vfs = vfs |
37659
575f59cdd8a1
lock: don't use 'file' as a variable name
Pulkit Goyal <7895pulkit@gmail.com>
parents:
37658
diff
changeset
|
183 |
self.f = fname |
161 | 184 |
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
|
185 |
self.timeout = timeout |
1530
abfab59fce79
add a releasefn keyword to lock.lock
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1062
diff
changeset
|
186 |
self.releasefn = releasefn |
26321
db4c192cb9b3
lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents:
26291
diff
changeset
|
187 |
self.acquirefn = acquirefn |
2016
ff5c9a92f556
fix backtrace printed when cannot get lock.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1877
diff
changeset
|
188 |
self.desc = desc |
26498
e8564e04382d
lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents:
26474
diff
changeset
|
189 |
self._inheritchecker = inheritchecker |
26356
927fa07a2ba4
lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26321
diff
changeset
|
190 |
self.parentlock = parentlock |
927fa07a2ba4
lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26321
diff
changeset
|
191 |
self._parentheld = False |
927fa07a2ba4
lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26321
diff
changeset
|
192 |
self._inherited = False |
38038
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
193 |
if signalsafe: |
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
194 |
self._maybedelayedinterrupt = _delayedinterrupt |
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
195 |
else: |
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
196 |
self._maybedelayedinterrupt = util.nullcontextmanager |
15589
cc24e4ed3e0c
lock: change name of release chain
Matt Mackall <mpm@selenic.com>
parents:
15583
diff
changeset
|
197 |
self.postrelease = [] |
26383
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
198 |
self.pid = self._getpid() |
35208
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
199 |
if dolock: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
200 |
self.delay = self.lock() |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
201 |
if self.acquirefn: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
202 |
self.acquirefn() |
161 | 203 |
|
27797
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
204 |
def __enter__(self): |
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
205 |
return self |
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
206 |
|
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
207 |
def __exit__(self, exc_type, exc_value, exc_tb): |
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
208 |
self.release() |
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
209 |
|
161 | 210 |
def __del__(self): |
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
211 |
if self.held: |
37897
2efefde3af70
lock: pass sysstr to warnings module
Augie Fackler <augie@google.com>
parents:
37659
diff
changeset
|
212 |
warnings.warn(r"use lock.release instead of del lock", |
8113
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
213 |
category=DeprecationWarning, |
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
214 |
stacklevel=2) |
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
215 |
|
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
216 |
# ensure the lock will be removed |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
217 |
# even if recursive locking did occur |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
218 |
self.held = 1 |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
219 |
|
161 | 220 |
self.release() |
221 |
||
26383
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
222 |
def _getpid(self): |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36701
diff
changeset
|
223 |
# wrapper around procutil.getpid() to make testing easier |
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36701
diff
changeset
|
224 |
return procutil.getpid() |
26383
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
225 |
|
161 | 226 |
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
|
227 |
timeout = self.timeout |
14494
1ffeeb91c55d
check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents:
13281
diff
changeset
|
228 |
while True: |
161 | 229 |
try: |
26082
b188f60bd955
lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents:
26081
diff
changeset
|
230 |
self._trylock() |
20380
c697b70f295f
localrepo: give a sigh of relief when getting lock after waiting for it
Mads Kiilerich <madski@unity3d.com>
parents:
20091
diff
changeset
|
231 |
return self.timeout - timeout |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23032
diff
changeset
|
232 |
except error.LockHeld as 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
|
233 |
if timeout != 0: |
161 | 234 |
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
|
235 |
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
|
236 |
timeout -= 1 |
161 | 237 |
continue |
7640 | 238 |
raise error.LockHeld(errno.ETIMEDOUT, inst.filename, self.desc, |
239 |
inst.locker) |
|
515 | 240 |
|
26082
b188f60bd955
lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents:
26081
diff
changeset
|
241 |
def _trylock(self): |
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
242 |
if self.held: |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
243 |
self.held += 1 |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
244 |
return |
4947
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
245 |
if lock._host is None: |
30920
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
246 |
lock._host = _getlockprefix() |
31354
e6a2b625e0d9
lock: use %d to format integer into a bytestring
Augie Fackler <augie@google.com>
parents:
30921
diff
changeset
|
247 |
lockname = '%s:%d' % (lock._host, self.pid) |
26081
3b6e5914edd8
lock: loop a finite number of times in trylock (issue4787)
Matt Mackall <mpm@selenic.com>
parents:
25956
diff
changeset
|
248 |
retry = 5 |
3b6e5914edd8
lock: loop a finite number of times in trylock (issue4787)
Matt Mackall <mpm@selenic.com>
parents:
25956
diff
changeset
|
249 |
while not self.held and retry: |
3b6e5914edd8
lock: loop a finite number of times in trylock (issue4787)
Matt Mackall <mpm@selenic.com>
parents:
25956
diff
changeset
|
250 |
retry -= 1 |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
251 |
try: |
38038
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
252 |
with self._maybedelayedinterrupt(): |
36701
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
253 |
self.vfs.makelock(lockname, self.f) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36657
diff
changeset
|
254 |
self.held = 1 |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23032
diff
changeset
|
255 |
except (OSError, IOError) as why: |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
256 |
if why.errno == errno.EEXIST: |
26387
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
257 |
locker = self._readlock() |
32087
e1938d6051da
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
31378
diff
changeset
|
258 |
if locker is None: |
e1938d6051da
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
31378
diff
changeset
|
259 |
continue |
e1938d6051da
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
31378
diff
changeset
|
260 |
|
26387
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
261 |
# special case where a parent process holds the lock -- this |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
262 |
# is different from the pid being different because we do |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
263 |
# want the unlock and postrelease functions to be called, |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
264 |
# but the lockfile to not be removed. |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
265 |
if locker == self.parentlock: |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
266 |
self._parentheld = True |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
267 |
self.held = 1 |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
268 |
return |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
269 |
locker = self._testlock(locker) |
3686
4308f4cdc07b
Don't step into an endless loop when lock file is empty.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2859
diff
changeset
|
270 |
if locker is not None: |
36657
214f61abd865
py3: back out c77c925987d7 to store bytes filename in IOError
Yuya Nishihara <yuya@tcha.org>
parents:
36642
diff
changeset
|
271 |
raise error.LockHeld(errno.EAGAIN, |
214f61abd865
py3: back out c77c925987d7 to store bytes filename in IOError
Yuya Nishihara <yuya@tcha.org>
parents:
36642
diff
changeset
|
272 |
self.vfs.join(self.f), self.desc, |
214f61abd865
py3: back out c77c925987d7 to store bytes filename in IOError
Yuya Nishihara <yuya@tcha.org>
parents:
36642
diff
changeset
|
273 |
locker) |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
274 |
else: |
7640 | 275 |
raise error.LockUnavailable(why.errno, why.strerror, |
276 |
why.filename, self.desc) |
|
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
277 |
|
32088
0d892d820a51
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
32087
diff
changeset
|
278 |
if not self.held: |
0d892d820a51
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
32087
diff
changeset
|
279 |
# use empty locker to mean "busy for frequent lock/unlock |
0d892d820a51
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
32087
diff
changeset
|
280 |
# by many processes" |
0d892d820a51
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
32087
diff
changeset
|
281 |
raise error.LockHeld(errno.EAGAIN, |
36657
214f61abd865
py3: back out c77c925987d7 to store bytes filename in IOError
Yuya Nishihara <yuya@tcha.org>
parents:
36642
diff
changeset
|
282 |
self.vfs.join(self.f), self.desc, "") |
32088
0d892d820a51
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
32087
diff
changeset
|
283 |
|
26290
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
284 |
def _readlock(self): |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
285 |
"""read lock and return its value |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
286 |
|
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
287 |
Returns None if no lock exists, pid for old-style locks, and host:pid |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
288 |
for new-style locks. |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
289 |
""" |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
290 |
try: |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
291 |
return self.vfs.readlock(self.f) |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
292 |
except (OSError, IOError) as why: |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
293 |
if why.errno == errno.ENOENT: |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
294 |
return None |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
295 |
raise |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
296 |
|
26291
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
297 |
def _testlock(self, locker): |
26290
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
298 |
if locker is None: |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
299 |
return None |
2579
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
300 |
try: |
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
301 |
host, pid = locker.split(":", 1) |
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
302 |
except ValueError: |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
303 |
return locker |
4947
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
304 |
if host != lock._host: |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
305 |
return locker |
161 | 306 |
try: |
2579
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
307 |
pid = int(pid) |
9685
a820cd39d415
lock: catch specific exceptions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9680
diff
changeset
|
308 |
except ValueError: |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
309 |
return locker |
37120
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36701
diff
changeset
|
310 |
if procutil.testpid(pid): |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
311 |
return locker |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
312 |
# if locker dead, break lock. must do this with another lock |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
313 |
# held, or can race and break valid lock. |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
314 |
try: |
20091
abfe6a8e619b
lock: take both vfs and lock file path relative to vfs to access via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19927
diff
changeset
|
315 |
l = lock(self.vfs, self.f + '.break', timeout=0) |
abfe6a8e619b
lock: take both vfs and lock file path relative to vfs to access via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19927
diff
changeset
|
316 |
self.vfs.unlink(self.f) |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
317 |
l.release() |
7640 | 318 |
except error.LockError: |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
319 |
return locker |
161 | 320 |
|
26291
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
321 |
def testlock(self): |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
322 |
"""return id of locker if lock is valid, else None. |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
323 |
|
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
324 |
If old-style lock, we cannot tell what machine locker is on. |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
325 |
with new-style lock, if locker is on this machine, we can |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
326 |
see if locker is alive. If locker is on this machine but |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
327 |
not alive, we can safely break lock. |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
328 |
|
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
329 |
The lock file is only deleted when None is returned. |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
330 |
|
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
331 |
""" |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
332 |
locker = self._readlock() |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
333 |
return self._testlock(locker) |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
334 |
|
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
335 |
@contextlib.contextmanager |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
336 |
def inherit(self): |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
337 |
"""context for the lock to be inherited by a Mercurial subprocess. |
26357
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
338 |
|
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
339 |
Yields a string that will be recognized by the lock in the subprocess. |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
340 |
Communicating this string to the subprocess needs to be done separately |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
341 |
-- typically by an environment variable. |
26357
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
342 |
""" |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
343 |
if not self.held: |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
344 |
raise error.LockInheritanceContractViolation( |
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
345 |
'inherit can only be called while lock is held') |
26357
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
346 |
if self._inherited: |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
347 |
raise error.LockInheritanceContractViolation( |
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
348 |
'inherit cannot be called while lock is already inherited') |
26498
e8564e04382d
lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents:
26474
diff
changeset
|
349 |
if self._inheritchecker is not None: |
e8564e04382d
lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents:
26474
diff
changeset
|
350 |
self._inheritchecker() |
26357
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
351 |
if self.releasefn: |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
352 |
self.releasefn() |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
353 |
if self._parentheld: |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
354 |
lockname = self.parentlock |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
355 |
else: |
37658
34758397ad1b
py3: use b"%d" instead of str() to convert integers to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
37120
diff
changeset
|
356 |
lockname = b'%s:%d' % (lock._host, self.pid) |
26357
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
357 |
self._inherited = True |
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
358 |
try: |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
359 |
yield lockname |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
360 |
finally: |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
361 |
if self.acquirefn: |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
362 |
self.acquirefn() |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
363 |
self._inherited = False |
26358
de5a52e5eb9e
lock: add a method to reacquire the lock after subprocesses exit
Siddharth Agarwal <sid0@fb.com>
parents:
26357
diff
changeset
|
364 |
|
161 | 365 |
def release(self): |
15583
926a06f7a353
lock: add mechanism to register post release callback
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
14494
diff
changeset
|
366 |
"""release the lock and execute callback function if any |
926a06f7a353
lock: add mechanism to register post release callback
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
14494
diff
changeset
|
367 |
|
17537 | 368 |
If the lock has been acquired multiple times, the actual release is |
17510 | 369 |
delayed to the last release call.""" |
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
370 |
if self.held > 1: |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
371 |
self.held -= 1 |
9680
8cea86d73887
lock: use '==' instead of 'is' for integer equality ('is' may not work)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9309
diff
changeset
|
372 |
elif self.held == 1: |
161 | 373 |
self.held = 0 |
26383
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
374 |
if self._getpid() != self.pid: |
18907
af9fa8d4c939
lock: if we fork, ensure that only the parent releases
Bryan O'Sullivan <bryano@fb.com>
parents:
17683
diff
changeset
|
375 |
# we forked, and are not the parent |
af9fa8d4c939
lock: if we fork, ensure that only the parent releases
Bryan O'Sullivan <bryano@fb.com>
parents:
17683
diff
changeset
|
376 |
return |
503
c6a2e41c8c60
Fix troubles with clone and exception handling
mpm@selenic.com
parents:
429
diff
changeset
|
377 |
try: |
23032
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
378 |
if self.releasefn: |
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
379 |
self.releasefn() |
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
380 |
finally: |
26359
c545d51c901e
lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26358
diff
changeset
|
381 |
if not self._parentheld: |
c545d51c901e
lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26358
diff
changeset
|
382 |
try: |
c545d51c901e
lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26358
diff
changeset
|
383 |
self.vfs.unlink(self.f) |
c545d51c901e
lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26358
diff
changeset
|
384 |
except OSError: |
c545d51c901e
lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26358
diff
changeset
|
385 |
pass |
26474
431094a3b21f
lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26473
diff
changeset
|
386 |
# The postrelease functions typically assume the lock is not held |
431094a3b21f
lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26473
diff
changeset
|
387 |
# at all. |
431094a3b21f
lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26473
diff
changeset
|
388 |
if not self._parentheld: |
431094a3b21f
lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26473
diff
changeset
|
389 |
for callback in self.postrelease: |
431094a3b21f
lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26473
diff
changeset
|
390 |
callback() |
28959
518c3e392f75
lock: clear postrelease hooks list after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28027
diff
changeset
|
391 |
# Prevent double usage and help clear cycles. |
518c3e392f75
lock: clear postrelease hooks list after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28027
diff
changeset
|
392 |
self.postrelease = None |
161 | 393 |
|
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
394 |
def release(*locks): |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
395 |
for lock in locks: |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
396 |
if lock is not None: |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
397 |
lock.release() |