Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/lock.py @ 53040:cdd7bf612c7b stable tip
bundle-spec: properly format boolean parameter (issue6960)
This was breaking automatic clone bundle generation. This changeset fixes it and
add a test to catch it in the future.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 11 Mar 2025 02:29:42 +0100 |
parents | 0f2268783c11 |
children |
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 |
51901
f4733654f144
typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents:
51858
diff
changeset
|
8 from __future__ import annotations |
25956
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 |
30941
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30940
diff
changeset
|
12 import os |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
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 |
51303
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
16 import typing |
8113
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
17 import warnings |
161 | 18 |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
19 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
|
20 |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
21 from . import ( |
31384
d57aa655ce97
lock: encode result of gethostname into a bytestring
Augie Fackler <augie@google.com>
parents:
31363
diff
changeset
|
22 encoding, |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
23 error, |
30941
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30940
diff
changeset
|
24 pycompat, |
37848
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
25 util, |
37123
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36724
diff
changeset
|
26 ) |
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36724
diff
changeset
|
27 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
28 from .utils import procutil |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
29 |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
30 |
30940
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 |
30941
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30940
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:
30940
diff
changeset
|
36 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
|
37 """ |
35937
4b1c04082cdc
py3: replace "if ispy3" by encoding.strtolocal()
Yuya Nishihara <yuya@tcha.org>
parents:
35219
diff
changeset
|
38 result = encoding.strtolocal(socket.gethostname()) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
39 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
|
40 try: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
41 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
|
42 except (FileNotFoundError, PermissionError, NotADirectoryError): |
050dc8730858
py3: catch specific OSError subclasses instead of checking errno
Manuel Jacob <me@manueljacob.de>
parents:
49314
diff
changeset
|
43 pass |
30941
1f151a33af8e
lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents:
30940
diff
changeset
|
44 return result |
30940
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
45 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
46 |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
47 @contextlib.contextmanager |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
48 def _delayedinterrupt(): |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
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:
36686
diff
changeset
|
50 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
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:
36686
diff
changeset
|
52 be interrupted. |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
53 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
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:
36686
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:
36686
diff
changeset
|
56 working. |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
57 """ |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
58 assertedsigs = [] |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
59 blocked = False |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
60 orighandlers = {} |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
61 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
62 def raiseinterrupt(num): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
63 if num == getattr(signal, 'SIGINT', None) or num == getattr( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
64 signal, 'CTRL_C_EVENT', None |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
65 ): |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
66 raise KeyboardInterrupt |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
67 else: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
68 raise error.SignalInterrupt |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
69 |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
70 def catchterm(num, frame): |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
71 if blocked: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
72 assertedsigs.append(num) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
73 else: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
74 raiseinterrupt(num) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
75 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
76 try: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
77 # 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
|
78 # 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
|
79 for name in [ |
50618
5586076b8030
safehasattr: pass attribute name as string instead of bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
49318
diff
changeset
|
80 'CTRL_C_EVENT', |
5586076b8030
safehasattr: pass attribute name as string instead of bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
49318
diff
changeset
|
81 'SIGINT', |
5586076b8030
safehasattr: pass attribute name as string instead of bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
49318
diff
changeset
|
82 'SIGBREAK', |
5586076b8030
safehasattr: pass attribute name as string instead of bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
49318
diff
changeset
|
83 'SIGHUP', |
5586076b8030
safehasattr: pass attribute name as string instead of bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
49318
diff
changeset
|
84 'SIGTERM', |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
85 ]: |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
86 num = getattr(signal, name, None) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
87 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
|
88 orighandlers[num] = signal.getsignal(num) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
89 try: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
90 for num in orighandlers: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
91 signal.signal(num, catchterm) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
92 except ValueError: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
93 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
|
94 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
95 blocked = True |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
96 yield |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
97 finally: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
98 # 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
|
99 # 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
|
100 # 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
|
101 blocked = False |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
102 try: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
103 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
|
104 signal.signal(num, handler) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
105 except ValueError: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
106 pass # in a thread? |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
107 |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
108 # 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
|
109 # 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
|
110 if assertedsigs: |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
111 raiseinterrupt(assertedsigs[0]) |
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
112 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
113 |
52739
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
114 def steal_lock(ui, vfs, lockname, stolen_lock, *args, **kwargs) -> lock: |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
115 """return a new lock that "steal" the locking made by a source lock |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
116 |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
117 This is used during local clone when reloading a repository. If we could |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
118 remove the need for this during copy clone, we could remove this function. |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
119 """ |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
120 new_lock = lock(vfs, lockname, 0, *args, dolock=False, **kwargs) |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
121 |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
122 assert stolen_lock.f == new_lock.f |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
123 assert stolen_lock.held > 0 |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
124 assert new_lock.held == 0 |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
125 new_lock.held += 1 |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
126 stolen_lock.held = None |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
127 if new_lock.acquirefn is not None: |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
128 new_lock.acquirefn() |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
129 return new_lock |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
130 |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
131 |
52670
4cb75772818d
pyupgrade: drop the quoting around type annotations
Matt Harbison <matt_harbison@yahoo.com>
parents:
52665
diff
changeset
|
132 def trylock(ui, vfs, lockname, timeout, warntimeout, *args, **kwargs) -> lock: |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
133 """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
|
134 |
35219
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
135 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
|
136 the held lock while trying to acquires it.""" |
51448
9da3fcc5f70f
test-lock: use synchronisation file instead of sleep
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51303
diff
changeset
|
137 devel_wait_file = kwargs.pop("devel_wait_sync_file", None) |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
138 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
139 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
|
140 """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
|
141 # 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
|
142 if b':' in locker: |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
143 host, pid = locker.split(b":", 1) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
144 msg = _( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
145 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
|
146 ) % ( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
147 pycompat.bytestr(l.desc), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
148 pycompat.bytestr(pid), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
149 pycompat.bytestr(host), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
150 ) |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
151 else: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
152 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
|
153 l.desc, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
154 pycompat.bytestr(locker), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
155 ) |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
156 printer(msg) |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
157 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
158 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
|
159 |
35219
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
160 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
|
161 warningidx = 0 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
162 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
|
163 warningidx = -1 |
35219
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
164 elif warntimeout: |
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
165 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
|
166 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
167 delay = 0 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
168 while True: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
169 try: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
170 l._trylock() |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
171 break |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
172 except error.LockHeld as inst: |
51448
9da3fcc5f70f
test-lock: use synchronisation file instead of sleep
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51303
diff
changeset
|
173 if devel_wait_file is not None: |
9da3fcc5f70f
test-lock: use synchronisation file instead of sleep
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51303
diff
changeset
|
174 # create the file to signal we are waiting |
9da3fcc5f70f
test-lock: use synchronisation file instead of sleep
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51303
diff
changeset
|
175 with open(devel_wait_file, 'w'): |
9da3fcc5f70f
test-lock: use synchronisation file instead of sleep
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51303
diff
changeset
|
176 pass |
9da3fcc5f70f
test-lock: use synchronisation file instead of sleep
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
51303
diff
changeset
|
177 |
35219
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
178 if delay == debugidx: |
9153871d50e0
lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents:
35218
diff
changeset
|
179 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
|
180 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
|
181 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
|
182 if timeout <= delay: |
51303
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
183 assert isinstance(inst.filename, bytes) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
184 raise error.LockHeld( |
51303
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
185 errno.ETIMEDOUT, |
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
186 typing.cast(bytes, inst.filename), |
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
187 l.desc, |
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
188 inst.locker, |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
189 ) |
35218
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
190 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
|
191 delay += 1 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
192 |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
193 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
|
194 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
|
195 if 0 <= warningidx <= l.delay: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
196 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
|
197 else: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
198 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
|
199 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
|
200 l.acquirefn() |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
201 return l |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
202 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
203 |
49037
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48966
diff
changeset
|
204 class lock: |
45957
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45527
diff
changeset
|
205 """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
|
206 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
|
207 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
|
208 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
|
209 |
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
210 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
|
211 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
|
212 else under .hg/.""" |
9309
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
213 |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
214 # 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
|
215 |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
216 # 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
|
217 # 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
|
218 |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
219 # 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
|
220 # 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
|
221 |
4947
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
222 _host = None |
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
223 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
224 def __init__( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
225 self, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
226 vfs, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
227 fname, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
228 timeout=-1, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
229 releasefn=None, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
230 acquirefn=None, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
231 desc=None, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
232 signalsafe=True, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
233 dolock=True, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
234 ): |
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
|
235 self.vfs = vfs |
37659
575f59cdd8a1
lock: don't use 'file' as a variable name
Pulkit Goyal <7895pulkit@gmail.com>
parents:
37658
diff
changeset
|
236 self.f = fname |
161 | 237 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
|
238 self.timeout = timeout |
1530
abfab59fce79
add a releasefn keyword to lock.lock
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1062
diff
changeset
|
239 self.releasefn = releasefn |
26321
db4c192cb9b3
lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents:
26291
diff
changeset
|
240 self.acquirefn = acquirefn |
2016
ff5c9a92f556
fix backtrace printed when cannot get lock.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1877
diff
changeset
|
241 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
|
242 if signalsafe: |
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
243 self._maybedelayedinterrupt = _delayedinterrupt |
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
244 else: |
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
245 self._maybedelayedinterrupt = util.nullcontextmanager |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
246 self.postrelease = [] |
26383
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
247 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
|
248 if dolock: |
1b758105b5c7
lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents:
32088
diff
changeset
|
249 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
|
250 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
|
251 self.acquirefn() |
161 | 252 |
27797
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
253 def __enter__(self): |
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
254 return self |
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
255 |
054abf2377e8
lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
26498
diff
changeset
|
256 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
|
257 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
|
258 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
|
259 |
161 | 260 def __del__(self): |
52739
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
261 if self.held is None: |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
262 # lock has been stolen (during a local clone) and should never be |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
263 # touched again. |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
264 return |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
265 if self.held > 0: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
266 warnings.warn( |
43551
313e3a279828
cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents:
43089
diff
changeset
|
267 "use lock.release instead of del lock", |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
268 category=DeprecationWarning, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
269 stacklevel=2, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
270 ) |
8113
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
271 |
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
272 # 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
|
273 # 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
|
274 self.held = 1 |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
275 |
161 | 276 self.release() |
277 | |
26383
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
278 def _getpid(self): |
37123
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36724
diff
changeset
|
279 # 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
|
280 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
|
281 |
51858
460e80488cf0
typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16
Matt Harbison <matt_harbison@yahoo.com>
parents:
51448
diff
changeset
|
282 def lock(self) -> int: |
1787
e431344e604c
add a timeout when a lock is held (default 1024 sec)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1753
diff
changeset
|
283 timeout = self.timeout |
14494
1ffeeb91c55d
check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents:
13281
diff
changeset
|
284 while True: |
161 | 285 try: |
26082
b188f60bd955
lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents:
26081
diff
changeset
|
286 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
|
287 return self.timeout - timeout |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23032
diff
changeset
|
288 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
|
289 if timeout != 0: |
161 | 290 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
|
291 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
|
292 timeout -= 1 |
161 | 293 continue |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
294 raise error.LockHeld( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
295 errno.ETIMEDOUT, inst.filename, self.desc, inst.locker |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
296 ) |
515 | 297 |
51858
460e80488cf0
typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16
Matt Harbison <matt_harbison@yahoo.com>
parents:
51448
diff
changeset
|
298 def _trylock(self) -> None: |
52739
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
299 if self.held is None: |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
300 msg = "cannot acquire a lock after it was stolen" |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
301 raise error.ProgrammingError(msg) |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
302 if self.held > 0: |
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
303 self.held += 1 |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
304 return |
4947
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
305 if lock._host is None: |
30940
dc9f086c7691
lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents:
28959
diff
changeset
|
306 lock._host = _getlockprefix() |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
307 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
|
308 retry = 5 |
3b6e5914edd8
lock: loop a finite number of times in trylock (issue4787)
Matt Mackall <mpm@selenic.com>
parents:
25956
diff
changeset
|
309 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
|
310 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
|
311 try: |
37848
8c828beb7543
lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents:
37659
diff
changeset
|
312 with self._maybedelayedinterrupt(): |
36724
d77c3b023393
lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents:
36686
diff
changeset
|
313 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
|
314 self.held = 1 |
52665
24ee91ba9aa8
pyupgrade: drop usage of py3 aliases for `OSError`
Matt Harbison <matt_harbison@yahoo.com>
parents:
51901
diff
changeset
|
315 except OSError 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
|
316 if why.errno == errno.EEXIST: |
26387
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
317 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
|
318 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
|
319 continue |
e1938d6051da
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
31387
diff
changeset
|
320 |
26387
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
321 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
|
322 if locker is not None: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
323 raise error.LockHeld( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
324 errno.EAGAIN, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
325 self.vfs.join(self.f), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
326 self.desc, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
327 locker, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
328 ) |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
329 else: |
51303
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
330 assert isinstance(why.filename, bytes) |
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
331 assert isinstance(why.strerror, str) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
332 raise error.LockUnavailable( |
51303
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
333 why.errno, |
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
334 why.strerror, |
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
335 typing.cast(bytes, why.filename), |
81224afd938d
lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50952
diff
changeset
|
336 self.desc, |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
337 ) |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
338 |
32088
0d892d820a51
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
32087
diff
changeset
|
339 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
|
340 # 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
|
341 # by many processes" |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
342 raise error.LockHeld( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
343 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
|
344 ) |
32088
0d892d820a51
lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
32087
diff
changeset
|
345 |
26290
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
346 def _readlock(self): |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
347 """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
|
348 |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
349 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
|
350 for new-style locks. |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
351 """ |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
352 try: |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
353 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
|
354 except FileNotFoundError: |
2e726c934fcd
py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents:
49037
diff
changeset
|
355 return None |
26290
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
356 |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
357 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
|
358 if locker is None: |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
359 return False |
2579
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
360 try: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
361 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
|
362 except ValueError: |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
363 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
|
364 if host != lock._host: |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
365 return False |
161 | 366 try: |
2579
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
367 pid = int(pid) |
9685
a820cd39d415
lock: catch specific exceptions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9680
diff
changeset
|
368 except ValueError: |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
369 return False |
37123
a8a902d7176e
procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36724
diff
changeset
|
370 if procutil.testpid(pid): |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
371 return False |
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
372 return True |
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
373 |
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
374 def _testlock(self, locker): |
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
375 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
|
376 return locker |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
377 |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
378 # 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
|
379 # 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
|
380 try: |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
381 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
|
382 locker = self._readlock() |
039fbd14d4e2
lock: fix race in lock-breaking code
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43748
diff
changeset
|
383 if not self._lockshouldbebroken(locker): |
039fbd14d4e2
lock: fix race in lock-breaking code
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43748
diff
changeset
|
384 return locker |
43748
cd822413b9aa
lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
43551
diff
changeset
|
385 self.vfs.unlink(self.f) |
7640 | 386 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
|
387 return locker |
161 | 388 |
26291
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
389 def testlock(self): |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
390 """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
|
391 |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
392 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
|
393 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
|
394 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
|
395 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
|
396 |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
397 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
|
398 |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
399 """ |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
400 locker = self._readlock() |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
401 return self._testlock(locker) |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
402 |
43798
888bd39ed555
lock: pass "success" boolean to _afterlock callbacks
Kyle Lippincott <spectral@google.com>
parents:
43749
diff
changeset
|
403 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
|
404 """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
|
405 |
17537 | 406 If the lock has been acquired multiple times, the actual release is |
17510 | 407 delayed to the last release call.""" |
52739
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
408 if self.held is None: |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
409 msg = "cannot release a lock after it was stolen" |
0f2268783c11
clone: explicitly steal lock instead of assigning previous lock
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
52670
diff
changeset
|
410 raise error.ProgrammingError(msg) |
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
411 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
|
412 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
|
413 elif self.held == 1: |
161 | 414 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
|
415 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
|
416 # 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
|
417 return |
503
c6a2e41c8c60
Fix troubles with clone and exception handling
mpm@selenic.com
parents:
429
diff
changeset
|
418 try: |
23032
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
419 if self.releasefn: |
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
420 self.releasefn() |
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
421 finally: |
45527
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
422 try: |
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
423 self.vfs.unlink(self.f) |
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
424 except OSError: |
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
425 pass |
26474
431094a3b21f
lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26473
diff
changeset
|
426 # 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
|
427 # at all. |
45527
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
428 for callback in self.postrelease: |
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
429 callback(success) |
9b16bb3b2349
locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents:
43798
diff
changeset
|
430 # 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
|
431 self.postrelease = None |
161 | 432 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
38251
diff
changeset
|
433 |
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
434 def release(*locks): |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
435 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
|
436 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
|
437 lock.release() |