Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/lock.py @ 49413:b5c8524827d2 stable 6.2.2
dirstate-v2: no longer register the data-file during transaction
If the data file change during the transaction, we cannot truncate it.
The content of the file itself is fine as it will get backed up at the same time
as the docket.
Leaving the trailing data at the end of failed transaction is fine. The
dirstate-v2 format supports it. The dead data will simply we written over if
necessary.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 01 Sep 2022 15:49:14 +0200 |
parents | 050dc8730858 |
children | 5586076b8030 |
rev | line source |
---|---|
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 # |
46819
d4ba4d51f85f
contributor: change mentions of mpm to olivia
Rapha?l Gom?s <rgomes@octobus.net>
parents:
45957
diff
changeset
|
3 # Copyright 2005, 2006 Olivia Mackall <olivia@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 |
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
9 import contextlib |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
10 import errno |
30941
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30940
diff
changeset
|
11 import os |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
12 import signal |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
13 import socket |
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
14 import time |
8113
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
15 import warnings |
161 | 16 |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
17 from .i18n import _ |
43089
c59eb1560c44
py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43077
diff
changeset
|
18 from .pycompat import getattr |
35218
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 ( |
31384
d57aa655ce97
lock: encode result of gethostname into a bytestring
Augie Fackler <augie@google.com>
parents:
31363
diff
changeset
|
21 encoding, |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
22 error, |
30941
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30940
diff
changeset
|
23 pycompat, |
37848
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
24 util, |
37123
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36724
diff
changeset
|
25 ) |
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36724
diff
changeset
|
26 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
27 from .utils import procutil |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
28 |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
29 |
30940
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
30 def _getlockprefix(): |
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
31 """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
|
32 |
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
33 It's useful to detect "dead" processes and remove stale locks with |
30941
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30940
diff
changeset
|
34 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:
30940
diff
changeset
|
35 extra Linux-specific pid namespace identifier. |
30940
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
36 """ |
35937
4b1c04082cdc
py3: replace "if ispy3" by encoding.strtolocal()
Yuya Nishihara <yuya@tcha.org>
parents:
35219
diff
changeset
|
37 result = encoding.strtolocal(socket.gethostname()) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
38 if pycompat.sysplatform.startswith(b'linux'): |
30941
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30940
diff
changeset
|
39 try: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
40 result += b'/%x' % os.stat(b'/proc/self/ns/pid').st_ino |
49318
050dc8730858
py3: catch specific OSError subclasses instead of checking errno
Manuel Jacob <me@manueljacob.de>
parents:
49314
diff
changeset
|
41 except (FileNotFoundError, PermissionError, NotADirectoryError): |
050dc8730858
py3: catch specific OSError subclasses instead of checking errno
Manuel Jacob <me@manueljacob.de>
parents:
49314
diff
changeset
|
42 pass |
30941
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30940
diff
changeset
|
43 return result |
30940
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
44 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
45 |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
46 @contextlib.contextmanager |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
47 def _delayedinterrupt(): |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
48 """Block signal interrupt while doing something critical |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
49 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
50 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:
36686
diff
changeset
|
51 be interrupted. |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
52 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
53 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:
36686
diff
changeset
|
54 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:
36686
diff
changeset
|
55 working. |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
56 """ |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
57 assertedsigs = [] |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
58 blocked = False |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
59 orighandlers = {} |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
60 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
61 def raiseinterrupt(num): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
62 if num == getattr(signal, 'SIGINT', None) or num == getattr( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
63 signal, 'CTRL_C_EVENT', None |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
64 ): |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
65 raise KeyboardInterrupt |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
66 else: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
67 raise error.SignalInterrupt |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
68 |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
69 def catchterm(num, frame): |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
70 if blocked: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
71 assertedsigs.append(num) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
72 else: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
73 raiseinterrupt(num) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
74 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
75 try: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
76 # 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:
36686
diff
changeset
|
77 # interrupted between signal.signal() and orighandlers[] =. |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
78 for name in [ |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
79 b'CTRL_C_EVENT', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
80 b'SIGINT', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
81 b'SIGBREAK', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
82 b'SIGHUP', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
83 b'SIGTERM', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
84 ]: |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
85 num = getattr(signal, name, None) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
86 if num and num not in orighandlers: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
87 orighandlers[num] = signal.getsignal(num) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
88 try: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
89 for num in orighandlers: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
90 signal.signal(num, catchterm) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
91 except ValueError: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
92 pass # in a thread? no luck |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
93 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
94 blocked = True |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
95 yield |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
96 finally: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
97 # 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:
36686
diff
changeset
|
98 # 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:
36686
diff
changeset
|
99 # interrupted. so instead, make catchterm() raise interrupt. |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
100 blocked = False |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
101 try: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
102 for num, handler in orighandlers.items(): |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
103 signal.signal(num, handler) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
104 except ValueError: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
105 pass # in a thread? |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
106 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
107 # 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:
36686
diff
changeset
|
108 # interrupt occurred while re-raising the first one |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
109 if assertedsigs: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
110 raiseinterrupt(assertedsigs[0]) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
111 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
112 |
35219
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
113 def trylock(ui, vfs, lockname, timeout, warntimeout, *args, **kwargs): |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
114 """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
|
115 |
35219
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
116 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:
35218
diff
changeset
|
117 the held lock while trying to acquires it.""" |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
118 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
119 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
|
120 """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
|
121 # show more details for new-style locks |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
122 if b':' in locker: |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
123 host, pid = locker.split(b":", 1) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
124 msg = _( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
125 b"waiting for lock on %s held by process %r on host %r\n" |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
126 ) % ( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
127 pycompat.bytestr(l.desc), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
128 pycompat.bytestr(pid), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
129 pycompat.bytestr(host), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
130 ) |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
131 else: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
132 msg = _(b"waiting for lock on %s held by %r\n") % ( |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
133 l.desc, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
134 pycompat.bytestr(locker), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
135 ) |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
136 printer(msg) |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
137 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
138 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
|
139 |
35219
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
140 debugidx = 0 if (warntimeout and timeout) else -1 |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
141 warningidx = 0 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
142 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
|
143 warningidx = -1 |
35219
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
144 elif warntimeout: |
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
145 warningidx = warntimeout |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
146 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
147 delay = 0 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
148 while True: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
149 try: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
150 l._trylock() |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
151 break |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
152 except error.LockHeld as inst: |
35219
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
153 if delay == debugidx: |
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
154 printwarning(ui.debug, inst.locker) |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
155 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
|
156 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
|
157 if timeout <= delay: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
158 raise error.LockHeld( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
159 errno.ETIMEDOUT, inst.filename, l.desc, inst.locker |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
160 ) |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
161 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
|
162 delay += 1 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
163 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
164 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
|
165 if l.delay: |
35219
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
166 if 0 <= warningidx <= l.delay: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
167 ui.warn(_(b"got lock after %d seconds\n") % l.delay) |
35219
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
168 else: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
169 ui.debug(b"got lock after %d seconds\n" % l.delay) |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
170 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
|
171 l.acquirefn() |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
172 return l |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
173 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
174 |
49037
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48966
diff
changeset
|
175 class lock: |
45957
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45527
diff
changeset
|
176 """An advisory lock held by one process to control access to a set |
9309
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
177 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
|
178 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
|
179 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
|
180 |
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
181 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
|
182 store (.hg/store/) or localrepository.wlock() to lock everything |
45957
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45527
diff
changeset
|
183 else under .hg/.""" |
9309
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
184 |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
185 # 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
|
186 |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
187 # 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
|
188 # 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
|
189 |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
190 # 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
|
191 # 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
|
192 |
4947
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
193 _host = None |
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
194 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
195 def __init__( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
196 self, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
197 vfs, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
198 fname, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
199 timeout=-1, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
200 releasefn=None, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
201 acquirefn=None, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
202 desc=None, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
203 signalsafe=True, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
204 dolock=True, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
205 ): |
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
|
206 self.vfs = vfs |
37659
575f59cdd8a1
lock: don't use 'file' as a variable name
Pulkit Goyal <7895pulkit@gmail.com>
parents:
37658
diff
changeset
|
207 self.f = fname |
161 | 208 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
|
209 self.timeout = timeout |
1530
abfab59fce79
add a releasefn keyword to lock.lock
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1062
diff
changeset
|
210 self.releasefn = releasefn |
26321
db4c192cb9b3
lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents:
26291
diff
changeset
|
211 self.acquirefn = acquirefn |
2016
ff5c9a92f556
fix backtrace printed when cannot get lock.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1877
diff
changeset
|
212 self.desc = desc |
37848
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
213 if signalsafe: |
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
214 self._maybedelayedinterrupt = _delayedinterrupt |
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
215 else: |
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
216 self._maybedelayedinterrupt = util.nullcontextmanager |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
217 self.postrelease = [] |
26383
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
218 self.pid = self._getpid() |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
219 if dolock: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
220 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
|
221 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
|
222 self.acquirefn() |
161 | 223 |
27797
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
224 def __enter__(self): |
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
225 return self |
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
226 |
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
227 def __exit__(self, exc_type, exc_value, exc_tb): |
43798
888bd39ed555
lock: pass "success" boolean to _afterlock callbacks
Kyle Lippincott <spectral@google.com>
parents:
43749
diff
changeset
|
228 success = all(a is None for a in (exc_type, exc_value, exc_tb)) |
888bd39ed555
lock: pass "success" boolean to _afterlock callbacks
Kyle Lippincott <spectral@google.com>
parents:
43749
diff
changeset
|
229 self.release(success=success) |
27797
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
230 |
161 | 231 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
|
232 if self.held: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
233 warnings.warn( |
43551
313e3a279828
cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents:
43089
diff
changeset
|
234 "use lock.release instead of del lock", |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
235 category=DeprecationWarning, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
236 stacklevel=2, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
237 ) |
8113
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
238 |
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
239 # 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
|
240 # 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
|
241 self.held = 1 |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
242 |
161 | 243 self.release() |
244 | |
26383
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
245 def _getpid(self): |
37123
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36724
diff
changeset
|
246 # 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:
36724
diff
changeset
|
247 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
|
248 |
161 | 249 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
|
250 timeout = self.timeout |
14494
1ffeeb91c55d
check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents:
13281
diff
changeset
|
251 while True: |
161 | 252 try: |
26082
b188f60bd955
lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents:
26081
diff
changeset
|
253 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
|
254 return self.timeout - timeout |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23032
diff
changeset
|
255 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
|
256 if timeout != 0: |
161 | 257 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
|
258 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
|
259 timeout -= 1 |
161 | 260 continue |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
261 raise error.LockHeld( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
262 errno.ETIMEDOUT, inst.filename, self.desc, inst.locker |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
263 ) |
515 | 264 |
26082
b188f60bd955
lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents:
26081
diff
changeset
|
265 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
|
266 if self.held: |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
267 self.held += 1 |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
268 return |
4947
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
269 if lock._host is None: |
30940
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
270 lock._host = _getlockprefix() |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
271 lockname = b'%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
|
272 retry = 5 |
3b6e5914edd8
lock: loop a finite number of times in trylock (issue4787)
Matt Mackall <mpm@selenic.com>
parents:
25956
diff
changeset
|
273 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
|
274 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
|
275 try: |
37848
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
276 with self._maybedelayedinterrupt(): |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
277 self.vfs.makelock(lockname, self.f) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
278 self.held = 1 |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23032
diff
changeset
|
279 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
|
280 if why.errno == errno.EEXIST: |
26387
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
281 locker = self._readlock() |
32087
e1938d6051da
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
31387
diff
changeset
|
282 if locker is None: |
e1938d6051da
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
31387
diff
changeset
|
283 continue |
e1938d6051da
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
31387
diff
changeset
|
284 |
26387
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
285 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
|
286 if locker is not None: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
287 raise error.LockHeld( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
288 errno.EAGAIN, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
289 self.vfs.join(self.f), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
290 self.desc, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
291 locker, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
292 ) |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
293 else: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
294 raise error.LockUnavailable( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
295 why.errno, why.strerror, why.filename, self.desc |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
296 ) |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
297 |
32088
0d892d820a51
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
32087
diff
changeset
|
298 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
|
299 # 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
|
300 # by many processes" |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
301 raise error.LockHeld( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
302 errno.EAGAIN, self.vfs.join(self.f), self.desc, b"" |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
303 ) |
32088
0d892d820a51
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
32087
diff
changeset
|
304 |
26290
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
305 def _readlock(self): |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
306 """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
|
307 |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
308 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
|
309 for new-style locks. |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
310 """ |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
311 try: |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
312 return self.vfs.readlock(self.f) |
49314
2e726c934fcd
py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents:
49037
diff
changeset
|
313 except FileNotFoundError: |
2e726c934fcd
py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents:
49037
diff
changeset
|
314 return None |
26290
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
315 |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
316 def _lockshouldbebroken(self, locker): |
26290
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
317 if locker is None: |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
318 return False |
2579
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
319 try: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
320 host, pid = locker.split(b":", 1) |
2579
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
321 except ValueError: |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
322 return False |
4947
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
323 if host != lock._host: |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
324 return False |
161 | 325 try: |
2579
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
326 pid = int(pid) |
9685
a820cd39d415
lock: catch specific exceptions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9680
diff
changeset
|
327 except ValueError: |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
328 return False |
37123
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36724
diff
changeset
|
329 if procutil.testpid(pid): |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
330 return False |
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
331 return True |
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
332 |
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
333 def _testlock(self, locker): |
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
334 if not self._lockshouldbebroken(locker): |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
335 return locker |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
336 |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
337 # 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
|
338 # 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
|
339 try: |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
340 with lock(self.vfs, self.f + b'.break', timeout=0): |
43749
039fbd14d4e2
lock: fix race in lock-breaking code
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43748
diff
changeset
|
341 locker = self._readlock() |
039fbd14d4e2
lock: fix race in lock-breaking code
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43748
diff
changeset
|
342 if not self._lockshouldbebroken(locker): |
039fbd14d4e2
lock: fix race in lock-breaking code
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43748
diff
changeset
|
343 return locker |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
344 self.vfs.unlink(self.f) |
7640 | 345 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
|
346 return locker |
161 | 347 |
26291
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
348 def testlock(self): |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
349 """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
|
350 |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
351 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
|
352 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
|
353 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
|
354 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
|
355 |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
356 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
|
357 |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
358 """ |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
359 locker = self._readlock() |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
360 return self._testlock(locker) |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
361 |
43798
888bd39ed555
lock: pass "success" boolean to _afterlock callbacks
Kyle Lippincott <spectral@google.com>
parents:
43749
diff
changeset
|
362 def release(self, success=True): |
15583
926a06f7a353
lock: add mechanism to register post release callback
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
14494
diff
changeset
|
363 """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
|
364 |
17537 | 365 If the lock has been acquired multiple times, the actual release is |
17510 | 366 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
|
367 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
|
368 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
|
369 elif self.held == 1: |
161 | 370 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
|
371 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
|
372 # 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
|
373 return |
503
c6a2e41c8c60
Fix troubles with clone and exception handling
mpm@selenic.com
parents:
429
diff
changeset
|
374 try: |
23032
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
375 if self.releasefn: |
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
376 self.releasefn() |
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
377 finally: |
45527
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
378 try: |
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
379 self.vfs.unlink(self.f) |
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
380 except OSError: |
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
381 pass |
26474
431094a3b21f
lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26473
diff
changeset
|
382 # 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
|
383 # at all. |
45527
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
384 for callback in self.postrelease: |
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
385 callback(success) |
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
386 # Prevent double usage and help clear cycles. |
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
387 self.postrelease = None |
161 | 388 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
389 |
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
390 def release(*locks): |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
391 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
|
392 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
|
393 lock.release() |