annotate mercurial/lock.py @ 52164:e01e84e5e426

rust-revlog: add a Rust-only `InnerRevlog` This mirrors the Python `InnerRevlog` and will be used in a future patch to replace said Python implementation. This allows us to start doing more things in pure Rust, in particular reading and writing operations. A lot of changes have to be introduced all at once, it wouldn't be very useful to separate this patch IMO since all of them are either interlocked or only useful with the rest.
author Raphaël Gomès <rgomes@octobus.net>
date Thu, 10 Oct 2024 10:34:51 +0200
parents f4733654f144
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
2 #
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 45942
diff changeset
3 # Copyright 2005, 2006 Olivia Mackall <olivia@selenic.com>
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
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
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9858
diff changeset
6 # GNU General Public License version 2 or any later version.
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
7
51863
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 51815
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
30921
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
12 import os
36701
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
13 import signal
25956
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
14 import socket
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
15 import time
51286
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
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
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
18
35208
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 (
31375
d57aa655ce97 lock: encode result of gethostname into a bytestring
Augie Fackler <augie@google.com>
parents: 31354
diff changeset
22 encoding,
25956
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
23 error,
30921
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
24 pycompat,
38038
8c828beb7543 lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37659
diff changeset
25 util,
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36701
diff changeset
26 )
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36701
diff changeset
27
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
28 from .utils import procutil
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
29
25956
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
30
30920
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
31 def _getlockprefix():
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
32 """Return a string which is used to differentiate pid namespaces
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
33
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
34 It's useful to detect "dead" processes and remove stale locks with
30921
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
35 confidence. Typically it's just hostname. On modern linux, we include an
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
36 extra Linux-specific pid namespace identifier.
30920
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
37 """
35897
4b1c04082cdc py3: replace "if ispy3" by encoding.strtolocal()
Yuya Nishihara <yuya@tcha.org>
parents: 35209
diff changeset
38 result = encoding.strtolocal(socket.gethostname())
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'):
30921
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
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
49310
050dc8730858 py3: catch specific OSError subclasses instead of checking errno
Manuel Jacob <me@manueljacob.de>
parents: 49306
diff changeset
42 except (FileNotFoundError, PermissionError, NotADirectoryError):
050dc8730858 py3: catch specific OSError subclasses instead of checking errno
Manuel Jacob <me@manueljacob.de>
parents: 49306
diff changeset
43 pass
30921
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
44 return result
30920
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: 38239
diff changeset
46
36701
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
47 @contextlib.contextmanager
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
48 def _delayedinterrupt():
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
49 """Block signal interrupt while doing something critical
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
50
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
51 This makes sure that the code block wrapped by this context manager won't
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
52 be interrupted.
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
53
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
54 For Windows developers: It appears not possible to guard time.sleep()
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
55 from CTRL_C_EVENT, so please don't use time.sleep() to test if this is
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
56 working.
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
57 """
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
58 assertedsigs = []
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
59 blocked = False
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
60 orighandlers = {}
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
61
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
62 def raiseinterrupt(num):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
63 if num == getattr(signal, 'SIGINT', None) or num == getattr(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
64 signal, 'CTRL_C_EVENT', None
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
65 ):
36701
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
66 raise KeyboardInterrupt
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
67 else:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
68 raise error.SignalInterrupt
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
69
36701
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
70 def catchterm(num, frame):
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
71 if blocked:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
72 assertedsigs.append(num)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
73 else:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
74 raiseinterrupt(num)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
75
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
76 try:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
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: 36657
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 [
50587
5586076b8030 safehasattr: pass attribute name as string instead of bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49310
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: 49310
diff changeset
81 'SIGINT',
5586076b8030 safehasattr: pass attribute name as string instead of bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49310
diff changeset
82 'SIGBREAK',
5586076b8030 safehasattr: pass attribute name as string instead of bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49310
diff changeset
83 'SIGHUP',
5586076b8030 safehasattr: pass attribute name as string instead of bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49310
diff changeset
84 'SIGTERM',
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
85 ]:
36701
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
86 num = getattr(signal, name, None)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
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: 36657
diff changeset
88 orighandlers[num] = signal.getsignal(num)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
89 try:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
90 for num in orighandlers:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
91 signal.signal(num, catchterm)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
92 except ValueError:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
93 pass # in a thread? no luck
36701
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
94
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
95 blocked = True
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
96 yield
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
97 finally:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
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: 36657
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: 36657
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: 36657
diff changeset
101 blocked = False
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
102 try:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
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: 36657
diff changeset
104 signal.signal(num, handler)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
105 except ValueError:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
106 pass # in a thread?
36701
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
107
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
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: 36657
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: 36657
diff changeset
110 if assertedsigs:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
111 raiseinterrupt(assertedsigs[0])
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
112
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
113
51815
460e80488cf0 typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16
Matt Harbison <matt_harbison@yahoo.com>
parents: 51497
diff changeset
114 def trylock(ui, vfs, lockname, timeout, warntimeout, *args, **kwargs) -> "lock":
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
115 """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
116
35209
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
117 This function is responsible to issue warnings and or debug messages about
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
118 the held lock while trying to acquires it."""
51497
9da3fcc5f70f test-lock: use synchronisation file instead of sleep
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51286
diff changeset
119 devel_wait_file = kwargs.pop("devel_wait_sync_file", None)
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
120
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
121 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
122 """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
123 # 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
124 if b':' in locker:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
125 host, pid = locker.split(b":", 1)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
126 msg = _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
127 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: 38239
diff changeset
128 ) % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
129 pycompat.bytestr(l.desc),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
130 pycompat.bytestr(pid),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
131 pycompat.bytestr(host),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
132 )
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
133 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
134 msg = _(b"waiting for lock on %s held by %r\n") % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
135 l.desc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
136 pycompat.bytestr(locker),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
137 )
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
138 printer(msg)
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
139
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
140 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
141
35209
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
142 debugidx = 0 if (warntimeout and timeout) else -1
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
143 warningidx = 0
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
144 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
145 warningidx = -1
35209
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
146 elif warntimeout:
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
147 warningidx = warntimeout
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
148
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
149 delay = 0
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
150 while True:
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
151 try:
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
152 l._trylock()
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
153 break
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
154 except error.LockHeld as inst:
51497
9da3fcc5f70f test-lock: use synchronisation file instead of sleep
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51286
diff changeset
155 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: 51286
diff changeset
156 # 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: 51286
diff changeset
157 with open(devel_wait_file, 'w'):
9da3fcc5f70f test-lock: use synchronisation file instead of sleep
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51286
diff changeset
158 pass
9da3fcc5f70f test-lock: use synchronisation file instead of sleep
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51286
diff changeset
159
35209
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
160 if delay == debugidx:
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
161 printwarning(ui.debug, inst.locker)
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
162 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
163 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
164 if timeout <= delay:
51286
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
165 assert isinstance(inst.filename, bytes)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
166 raise error.LockHeld(
51286
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
167 errno.ETIMEDOUT,
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
168 typing.cast(bytes, inst.filename),
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
169 l.desc,
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
170 inst.locker,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
171 )
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
172 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
173 delay += 1
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
174
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
175 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
176 if l.delay:
35209
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
177 if 0 <= warningidx <= l.delay:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
178 ui.warn(_(b"got lock after %d seconds\n") % l.delay)
35209
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
179 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
180 ui.debug(b"got lock after %d seconds\n" % l.delay)
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
181 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
182 l.acquirefn()
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
183 return l
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
184
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
185
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
186 class lock:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45519
diff changeset
187 """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
188 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
189 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
190 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
191
cfdcb7a465af localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents: 8312
diff changeset
192 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
193 store (.hg/store/) or localrepository.wlock() to lock everything
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45519
diff changeset
194 else under .hg/."""
9309
cfdcb7a465af localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents: 8312
diff changeset
195
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
196 # 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
197
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
198 # 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
199 # 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
200
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
201 # 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
202 # 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
203
4947
3e25a6eb5c9a lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents: 3877
diff changeset
204 _host = None
3e25a6eb5c9a lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents: 3877
diff changeset
205
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
206 def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
207 self,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
208 vfs,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
209 fname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
210 timeout=-1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
211 releasefn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
212 acquirefn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
213 desc=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
214 signalsafe=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
215 dolock=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
216 ):
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
217 self.vfs = vfs
37659
575f59cdd8a1 lock: don't use 'file' as a variable name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 37658
diff changeset
218 self.f = fname
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
219 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
220 self.timeout = timeout
1530
abfab59fce79 add a releasefn keyword to lock.lock
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1062
diff changeset
221 self.releasefn = releasefn
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26291
diff changeset
222 self.acquirefn = acquirefn
2016
ff5c9a92f556 fix backtrace printed when cannot get lock.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
223 self.desc = desc
38038
8c828beb7543 lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37659
diff changeset
224 if signalsafe:
8c828beb7543 lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37659
diff changeset
225 self._maybedelayedinterrupt = _delayedinterrupt
8c828beb7543 lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37659
diff changeset
226 else:
8c828beb7543 lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37659
diff changeset
227 self._maybedelayedinterrupt = util.nullcontextmanager
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
228 self.postrelease = []
26383
0fceb34806e1 lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents: 26359
diff changeset
229 self.pid = self._getpid()
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
230 if dolock:
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
231 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
232 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
233 self.acquirefn()
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
234
27797
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
235 def __enter__(self):
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
236 return self
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
237
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
238 def __exit__(self, exc_type, exc_value, exc_tb):
43778
888bd39ed555 lock: pass "success" boolean to _afterlock callbacks
Kyle Lippincott <spectral@google.com>
parents: 43709
diff changeset
239 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: 43709
diff changeset
240 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
241
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
242 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
243 if self.held:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
244 warnings.warn(
43503
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
245 "use lock.release instead of del lock",
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
246 category=DeprecationWarning,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
247 stacklevel=2,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
248 )
8113
87a1605979e4 add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8108
diff changeset
249
8108
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
250 # 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
251 # 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
252 self.held = 1
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
253
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
254 self.release()
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
255
26383
0fceb34806e1 lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents: 26359
diff changeset
256 def _getpid(self):
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36701
diff changeset
257 # wrapper around procutil.getpid() to make testing easier
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36701
diff changeset
258 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
259
51815
460e80488cf0 typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16
Matt Harbison <matt_harbison@yahoo.com>
parents: 51497
diff changeset
260 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
261 timeout = self.timeout
14494
1ffeeb91c55d check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents: 13281
diff changeset
262 while True:
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
263 try:
26082
b188f60bd955 lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents: 26081
diff changeset
264 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
265 return self.timeout - timeout
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23032
diff changeset
266 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
267 if timeout != 0:
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
268 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
269 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
270 timeout -= 1
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
271 continue
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
272 raise error.LockHeld(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
273 errno.ETIMEDOUT, inst.filename, self.desc, inst.locker
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
274 )
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 503
diff changeset
275
51815
460e80488cf0 typing: lock in correct changes from pytype 2023.04.11 -> 2023.06.16
Matt Harbison <matt_harbison@yahoo.com>
parents: 51497
diff changeset
276 def _trylock(self) -> None:
8108
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
277 if self.held:
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
278 self.held += 1
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
279 return
4947
3e25a6eb5c9a lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents: 3877
diff changeset
280 if lock._host is None:
30920
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
281 lock._host = _getlockprefix()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
282 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
283 retry = 5
3b6e5914edd8 lock: loop a finite number of times in trylock (issue4787)
Matt Mackall <mpm@selenic.com>
parents: 25956
diff changeset
284 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
285 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
286 try:
38038
8c828beb7543 lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37659
diff changeset
287 with self._maybedelayedinterrupt():
36701
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
288 self.vfs.makelock(lockname, self.f)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36657
diff changeset
289 self.held = 1
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23032
diff changeset
290 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
291 if why.errno == errno.EEXIST:
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
292 locker = self._readlock()
32087
e1938d6051da lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 31378
diff changeset
293 if locker is None:
e1938d6051da lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 31378
diff changeset
294 continue
e1938d6051da lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 31378
diff changeset
295
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
296 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
297 if locker is not None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
298 raise error.LockHeld(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
299 errno.EAGAIN,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
300 self.vfs.join(self.f),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
301 self.desc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
302 locker,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
303 )
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
304 else:
51286
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
305 assert isinstance(why.filename, bytes)
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
306 assert isinstance(why.strerror, str)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
307 raise error.LockUnavailable(
51286
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
308 why.errno,
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
309 why.strerror,
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
310 typing.cast(bytes, why.filename),
81224afd938d lock: properly convert error to bytes
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
311 self.desc,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
312 )
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
313
32088
0d892d820a51 lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32087
diff changeset
314 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
315 # 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
316 # by many processes"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
317 raise error.LockHeld(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
318 errno.EAGAIN, self.vfs.join(self.f), self.desc, b""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
319 )
32088
0d892d820a51 lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32087
diff changeset
320
26290
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
321 def _readlock(self):
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
322 """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
323
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
324 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
325 for new-style locks.
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
326 """
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
327 try:
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
328 return self.vfs.readlock(self.f)
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
329 except FileNotFoundError:
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
330 return None
26290
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
331
43708
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
332 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
333 if locker is None:
43708
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
334 return False
2579
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2016
diff changeset
335 try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
336 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
337 except ValueError:
43708
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
338 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
339 if host != lock._host:
43708
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
340 return False
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
341 try:
2579
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2016
diff changeset
342 pid = int(pid)
9685
a820cd39d415 lock: catch specific exceptions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9680
diff changeset
343 except ValueError:
43708
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
344 return False
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36701
diff changeset
345 if procutil.testpid(pid):
43708
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
346 return False
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
347 return True
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
348
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
349 def _testlock(self, locker):
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
350 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
351 return locker
43708
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
352
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
353 # 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
354 # 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
355 try:
43708
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
356 with lock(self.vfs, self.f + b'.break', timeout=0):
43709
039fbd14d4e2 lock: fix race in lock-breaking code
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43708
diff changeset
357 locker = self._readlock()
039fbd14d4e2 lock: fix race in lock-breaking code
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43708
diff changeset
358 if not self._lockshouldbebroken(locker):
039fbd14d4e2 lock: fix race in lock-breaking code
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43708
diff changeset
359 return locker
43708
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43503
diff changeset
360 self.vfs.unlink(self.f)
7640
7197812e8d44 error: move lock errors
Matt Mackall <mpm@selenic.com>
parents: 4959
diff changeset
361 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
362 return locker
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
363
26291
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
364 def testlock(self):
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
365 """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
366
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
367 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
368 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
369 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
370 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
371
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
372 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
373
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
374 """
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
375 locker = self._readlock()
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
376 return self._testlock(locker)
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
377
43778
888bd39ed555 lock: pass "success" boolean to _afterlock callbacks
Kyle Lippincott <spectral@google.com>
parents: 43709
diff changeset
378 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
379 """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
380
17537
31f32a96e1e3 Merge spelling fixes
Bryan O'Sullivan <bryano@fb.com>
parents: 17427 17510
diff changeset
381 If the lock has been acquired multiple times, the actual release is
17510
7c44b703657b spelling: release
timeless@mozdev.org
parents: 15589
diff changeset
382 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
383 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
384 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
385 elif self.held == 1:
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
386 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
387 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
388 # 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
389 return
503
c6a2e41c8c60 Fix troubles with clone and exception handling
mpm@selenic.com
parents: 429
diff changeset
390 try:
23032
f484be02bd35 lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents: 20380
diff changeset
391 if self.releasefn:
f484be02bd35 lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents: 20380
diff changeset
392 self.releasefn()
f484be02bd35 lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents: 20380
diff changeset
393 finally:
45519
9b16bb3b2349 locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents: 43778
diff changeset
394 try:
9b16bb3b2349 locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents: 43778
diff changeset
395 self.vfs.unlink(self.f)
9b16bb3b2349 locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents: 43778
diff changeset
396 except OSError:
9b16bb3b2349 locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents: 43778
diff changeset
397 pass
26474
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
398 # 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
399 # at all.
45519
9b16bb3b2349 locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents: 43778
diff changeset
400 for callback in self.postrelease:
9b16bb3b2349 locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents: 43778
diff changeset
401 callback(success)
9b16bb3b2349 locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents: 43778
diff changeset
402 # Prevent double usage and help clear cycles.
9b16bb3b2349 locking: remove support for inheriting locks in subprocess
Martin von Zweigbergk <martinvonz@google.com>
parents: 43778
diff changeset
403 self.postrelease = None
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
404
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38239
diff changeset
405
8108
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
406 def release(*locks):
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
407 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
408 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
409 lock.release()