mercurial/lock.py
author Matt Harbison <matt_harbison@yahoo.com>
Sun, 29 Dec 2019 20:51:44 -0500
changeset 44032 5ac0e6f19eb4
parent 43798 888bd39ed555
child 45527 9b16bb3b2349
permissions -rw-r--r--
ui: refactor `readconfig()` into a form that can consume resources The old form can't completely go away, because files outside of packages still need to be read. The name passed in here is a tuple of `package name, resource` as needed by the resource API. I like the idea of stating the config file is embedded in the executable by listing is as `exe!package.resource`. This would be consistent with how `debuginstall` points to the executable for the python executable, lib, and installed modules. While in practice the filesystem path is available from the backing ResourceReader when the resource is opened, it is a relative path on py2 and absolute on py3. Further, while this would show in the `hg config` output for each option if set as such here, it doesn't show in the `reading from...` line when `--debug` is used. The file isn't actually open where that prints, so there's no way I see to get that info there. So I opted for the simple prefix to distinguish resources from files. Differential Revision: https://phab.mercurial-scm.org/D7775
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
#
2859
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2579
diff changeset
     3
# Copyright 2005, 2006 Matt Mackall <mpm@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
25956
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     8
from __future__ import absolute_import
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     9
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
    10
import contextlib
25956
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    11
import errno
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
8113
87a1605979e4 add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8108
diff changeset
    16
import warnings
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
    17
35218
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
    18
from .i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
    19
from .pycompat import getattr
35218
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
    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
30941
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30940
diff changeset
    42
        except OSError as ex:
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30940
diff changeset
    43
            if ex.errno not in (errno.ENOENT, errno.EACCES, errno.ENOTDIR):
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30940
diff changeset
    44
                raise
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30940
diff changeset
    45
    return result
30940
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
    46
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
    47
36724
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    48
@contextlib.contextmanager
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    49
def _delayedinterrupt():
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    50
    """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
    51
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    52
    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
    53
    be interrupted.
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    54
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    55
    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
    56
    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
    57
    working.
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    58
    """
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    59
    assertedsigs = []
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    60
    blocked = False
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    61
    orighandlers = {}
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    62
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    63
    def raiseinterrupt(num):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
    64
        if num == getattr(signal, 'SIGINT', None) or num == getattr(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
    65
            signal, 'CTRL_C_EVENT', None
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
    66
        ):
36724
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    67
            raise KeyboardInterrupt
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    68
        else:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    69
            raise error.SignalInterrupt
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
    70
36724
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    71
    def catchterm(num, frame):
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    72
        if blocked:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    73
            assertedsigs.append(num)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    74
        else:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    75
            raiseinterrupt(num)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    76
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    77
    try:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    78
        # 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
    79
        # 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
    80
        for name in [
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    81
            b'CTRL_C_EVENT',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    82
            b'SIGINT',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    83
            b'SIGBREAK',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    84
            b'SIGHUP',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    85
            b'SIGTERM',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    86
        ]:
36724
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    87
            num = getattr(signal, name, None)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    88
            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
    89
                orighandlers[num] = signal.getsignal(num)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    90
        try:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    91
            for num in orighandlers:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    92
                signal.signal(num, catchterm)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    93
        except ValueError:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
    94
            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
    95
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    96
        blocked = True
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    97
        yield
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    98
    finally:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
    99
        # 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
   100
        # 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
   101
        # 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
   102
        blocked = False
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
   103
        try:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
   104
            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
   105
                signal.signal(num, handler)
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
   106
        except ValueError:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   107
            pass  # in a thread?
36724
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
   108
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
   109
    # 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
   110
    # 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
   111
    if assertedsigs:
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
   112
        raiseinterrupt(assertedsigs[0])
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
   113
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   114
35219
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35218
diff changeset
   115
def trylock(ui, vfs, lockname, timeout, warntimeout, *args, **kwargs):
35218
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
   116
    """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
   117
35219
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35218
diff changeset
   118
    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
   119
    the held lock while trying to acquires it."""
35218
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
   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: 38251
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: 38251
diff changeset
   128
            ) % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   129
                pycompat.bytestr(l.desc),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   130
                pycompat.bytestr(pid),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   131
                pycompat.bytestr(host),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   132
            )
35218
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: 38251
diff changeset
   135
                l.desc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   136
                pycompat.bytestr(locker),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   137
            )
35218
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
35219
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35218
diff changeset
   142
    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
   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
35219
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35218
diff changeset
   146
    elif warntimeout:
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35218
diff changeset
   147
        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
   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:
35219
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35218
diff changeset
   155
            if delay == debugidx:
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35218
diff changeset
   156
                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
   157
            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
   158
                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
   159
            if timeout <= delay:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   160
                raise error.LockHeld(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   161
                    errno.ETIMEDOUT, inst.filename, l.desc, inst.locker
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   162
                )
35218
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
   163
            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
   164
            delay += 1
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
   165
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
   166
    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
   167
    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
   168
        if 0 <= warningidx <= l.delay:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   169
            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
   170
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   171
            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
   172
    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
   173
        l.acquirefn()
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
   174
    return l
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
   175
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   176
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1530
diff changeset
   177
class lock(object):
9309
cfdcb7a465af localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents: 8312
diff changeset
   178
    '''An advisory lock held by one process to control access to a set
cfdcb7a465af localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents: 8312
diff changeset
   179
    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
   180
    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
   181
    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
   182
cfdcb7a465af localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents: 8312
diff changeset
   183
    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
   184
    store (.hg/store/) or localrepository.wlock() to lock everything
cfdcb7a465af localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents: 8312
diff changeset
   185
    else under .hg/.'''
cfdcb7a465af localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents: 8312
diff changeset
   186
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
   187
    # 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
   188
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
   189
    # 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
   190
    # 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
   191
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
   192
    # 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
   193
    # 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
   194
4947
3e25a6eb5c9a lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents: 3877
diff changeset
   195
    _host = None
3e25a6eb5c9a lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents: 3877
diff changeset
   196
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   197
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   198
        self,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   199
        vfs,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   200
        fname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   201
        timeout=-1,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   202
        releasefn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   203
        acquirefn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   204
        desc=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   205
        inheritchecker=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   206
        parentlock=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   207
        signalsafe=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   208
        dolock=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   209
    ):
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
   210
        self.vfs = vfs
37659
575f59cdd8a1 lock: don't use 'file' as a variable name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 37658
diff changeset
   211
        self.f = fname
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   212
        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
   213
        self.timeout = timeout
1530
abfab59fce79 add a releasefn keyword to lock.lock
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1062
diff changeset
   214
        self.releasefn = releasefn
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26291
diff changeset
   215
        self.acquirefn = acquirefn
2016
ff5c9a92f556 fix backtrace printed when cannot get lock.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
   216
        self.desc = desc
26498
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   217
        self._inheritchecker = inheritchecker
26356
927fa07a2ba4 lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26321
diff changeset
   218
        self.parentlock = parentlock
927fa07a2ba4 lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26321
diff changeset
   219
        self._parentheld = False
927fa07a2ba4 lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26321
diff changeset
   220
        self._inherited = False
37848
8c828beb7543 lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37659
diff changeset
   221
        if signalsafe:
8c828beb7543 lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37659
diff changeset
   222
            self._maybedelayedinterrupt = _delayedinterrupt
8c828beb7543 lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37659
diff changeset
   223
        else:
8c828beb7543 lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37659
diff changeset
   224
            self._maybedelayedinterrupt = util.nullcontextmanager
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   225
        self.postrelease = []
26383
0fceb34806e1 lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents: 26359
diff changeset
   226
        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
   227
        if dolock:
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
   228
            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
   229
            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
   230
                self.acquirefn()
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   231
27797
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
   232
    def __enter__(self):
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
   233
        return self
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
   234
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
   235
    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
   236
        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
   237
        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
   238
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   239
    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
   240
        if self.held:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   241
            warnings.warn(
43551
313e3a279828 cleanup: remove pointless r-prefixes on double-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
   242
                "use lock.release instead of del lock",
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   243
                category=DeprecationWarning,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   244
                stacklevel=2,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   245
            )
8113
87a1605979e4 add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8108
diff changeset
   246
8108
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
   247
            # 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
   248
            # 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
   249
            self.held = 1
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
   250
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   251
        self.release()
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   252
26383
0fceb34806e1 lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents: 26359
diff changeset
   253
    def _getpid(self):
37123
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36724
diff changeset
   254
        # 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
   255
        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
   256
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   257
    def lock(self):
1787
e431344e604c add a timeout when a lock is held (default 1024 sec)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1753
diff changeset
   258
        timeout = self.timeout
14494
1ffeeb91c55d check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents: 13281
diff changeset
   259
        while True:
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   260
            try:
26082
b188f60bd955 lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents: 26081
diff changeset
   261
                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
   262
                return self.timeout - timeout
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23032
diff changeset
   263
            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
   264
                if timeout != 0:
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   265
                    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
   266
                    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
   267
                        timeout -= 1
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   268
                    continue
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   269
                raise error.LockHeld(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   270
                    errno.ETIMEDOUT, inst.filename, self.desc, inst.locker
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   271
                )
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 503
diff changeset
   272
26082
b188f60bd955 lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents: 26081
diff changeset
   273
    def _trylock(self):
8108
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
   274
        if self.held:
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
   275
            self.held += 1
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
   276
            return
4947
3e25a6eb5c9a lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents: 3877
diff changeset
   277
        if lock._host is None:
30940
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
   278
            lock._host = _getlockprefix()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   279
        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
   280
        retry = 5
3b6e5914edd8 lock: loop a finite number of times in trylock (issue4787)
Matt Mackall <mpm@selenic.com>
parents: 25956
diff changeset
   281
        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
   282
            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
   283
            try:
37848
8c828beb7543 lock: add internal config to not replace signal handlers while locking
Yuya Nishihara <yuya@tcha.org>
parents: 37659
diff changeset
   284
                with self._maybedelayedinterrupt():
36724
d77c3b023393 lock: block signal interrupt while making a lock file
Yuya Nishihara <yuya@tcha.org>
parents: 36686
diff changeset
   285
                    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
   286
                    self.held = 1
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23032
diff changeset
   287
            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
   288
                if why.errno == errno.EEXIST:
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
   289
                    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
   290
                    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
   291
                        continue
e1938d6051da lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 31387
diff changeset
   292
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
   293
                    # special case where a parent process holds the lock -- this
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
   294
                    # is different from the pid being different because we do
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
   295
                    # want the unlock and postrelease functions to be called,
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
   296
                    # but the lockfile to not be removed.
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
   297
                    if locker == self.parentlock:
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
   298
                        self._parentheld = True
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
   299
                        self.held = 1
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
   300
                        return
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
   301
                    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
   302
                    if locker is not None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   303
                        raise error.LockHeld(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   304
                            errno.EAGAIN,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   305
                            self.vfs.join(self.f),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   306
                            self.desc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   307
                            locker,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   308
                        )
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
   309
                else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   310
                    raise error.LockUnavailable(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   311
                        why.errno, why.strerror, why.filename, self.desc
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
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: 38251
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: 38251
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)
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
   329
        except (OSError, IOError) as why:
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
   330
            if why.errno == errno.ENOENT:
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
   331
                return None
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
   332
            raise
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
   333
43748
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   334
    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
   335
        if locker is None:
43748
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   336
            return False
2579
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2016
diff changeset
   337
        try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   338
            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
   339
        except ValueError:
43748
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   340
            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
   341
        if host != lock._host:
43748
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   342
            return False
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   343
        try:
2579
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2016
diff changeset
   344
            pid = int(pid)
9685
a820cd39d415 lock: catch specific exceptions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9680
diff changeset
   345
        except ValueError:
43748
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   346
            return False
37123
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36724
diff changeset
   347
        if procutil.testpid(pid):
43748
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   348
            return False
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   349
        return True
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   350
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   351
    def _testlock(self, locker):
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   352
        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
   353
            return locker
43748
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   354
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
   355
        # 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
   356
        # 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
   357
        try:
43748
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   358
            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
   359
                locker = self._readlock()
039fbd14d4e2 lock: fix race in lock-breaking code
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43748
diff changeset
   360
                if not self._lockshouldbebroken(locker):
039fbd14d4e2 lock: fix race in lock-breaking code
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43748
diff changeset
   361
                    return locker
43748
cd822413b9aa lock: refactor in preparation for next commit
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 43551
diff changeset
   362
                self.vfs.unlink(self.f)
7640
7197812e8d44 error: move lock errors
Matt Mackall <mpm@selenic.com>
parents: 4959
diff changeset
   363
        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
   364
            return locker
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   365
26291
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
   366
    def testlock(self):
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
   367
        """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
   368
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
   369
        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
   370
        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
   371
        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
   372
        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
   373
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
   374
        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
   375
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
   376
        """
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
   377
        locker = self._readlock()
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
   378
        return self._testlock(locker)
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
   379
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   380
    @contextlib.contextmanager
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   381
    def inherit(self):
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   382
        """context for the lock to be inherited by a Mercurial subprocess.
26357
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   383
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   384
        Yields a string that will be recognized by the lock in the subprocess.
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   385
        Communicating this string to the subprocess needs to be done separately
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   386
        -- typically by an environment variable.
26357
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   387
        """
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   388
        if not self.held:
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   389
            raise error.LockInheritanceContractViolation(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   390
                b'inherit can only be called while lock is held'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   391
            )
26357
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   392
        if self._inherited:
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   393
            raise error.LockInheritanceContractViolation(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   394
                b'inherit cannot be called while lock is already inherited'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   395
            )
26498
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   396
        if self._inheritchecker is not None:
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
   397
            self._inheritchecker()
26357
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   398
        if self.releasefn:
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   399
            self.releasefn()
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   400
        if self._parentheld:
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   401
            lockname = self.parentlock
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   402
        else:
37658
34758397ad1b py3: use b"%d" instead of str() to convert integers to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 37123
diff changeset
   403
            lockname = b'%s:%d' % (lock._host, self.pid)
26357
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
   404
        self._inherited = True
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   405
        try:
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   406
            yield lockname
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   407
        finally:
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   408
            if self.acquirefn:
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   409
                self.acquirefn()
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
   410
            self._inherited = False
26358
de5a52e5eb9e lock: add a method to reacquire the lock after subprocesses exit
Siddharth Agarwal <sid0@fb.com>
parents: 26357
diff changeset
   411
43798
888bd39ed555 lock: pass "success" boolean to _afterlock callbacks
Kyle Lippincott <spectral@google.com>
parents: 43749
diff changeset
   412
    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
   413
        """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
   414
17537
31f32a96e1e3 Merge spelling fixes
Bryan O'Sullivan <bryano@fb.com>
parents: 17427 17510
diff changeset
   415
        If the lock has been acquired multiple times, the actual release is
17510
7c44b703657b spelling: release
timeless@mozdev.org
parents: 15589
diff changeset
   416
        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
   417
        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
   418
            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
   419
        elif self.held == 1:
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   420
            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
   421
            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
   422
                # 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
   423
                return
503
c6a2e41c8c60 Fix troubles with clone and exception handling
mpm@selenic.com
parents: 429
diff changeset
   424
            try:
23032
f484be02bd35 lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents: 20380
diff changeset
   425
                if self.releasefn:
f484be02bd35 lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents: 20380
diff changeset
   426
                    self.releasefn()
f484be02bd35 lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents: 20380
diff changeset
   427
            finally:
26359
c545d51c901e lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26358
diff changeset
   428
                if not self._parentheld:
c545d51c901e lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26358
diff changeset
   429
                    try:
c545d51c901e lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26358
diff changeset
   430
                        self.vfs.unlink(self.f)
c545d51c901e lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26358
diff changeset
   431
                    except OSError:
c545d51c901e lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26358
diff changeset
   432
                        pass
26474
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
   433
            # 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
   434
            # at all.
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
   435
            if not self._parentheld:
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
   436
                for callback in self.postrelease:
43798
888bd39ed555 lock: pass "success" boolean to _afterlock callbacks
Kyle Lippincott <spectral@google.com>
parents: 43749
diff changeset
   437
                    callback(success)
28959
518c3e392f75 lock: clear postrelease hooks list after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
   438
                # Prevent double usage and help clear cycles.
518c3e392f75 lock: clear postrelease hooks list after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
   439
                self.postrelease = None
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
   440
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 38251
diff changeset
   441
8108
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
   442
def release(*locks):
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
   443
    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
   444
        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
   445
            lock.release()