annotate mercurial/lock.py @ 35216:fcc96cf0983d

hgweb: adopt child nodes in ajaxScrollInit on /graph pages too ajaxScrollInit is a function that loads more elements (e.g. changelog entries) when browser window is scrolled down to the bottom of the page. It basically fetches the next page from the server as HTML, finds container element in that document and "adopts" (essentially, moves) all its child nodes to the container in the current document. Currently, hgweb doesn't render any changesets on /graph page (everything is done in JavaScript), so there are no children to adopt. But there will be soon, so let's create a reusable function that does it. Hardcoding #graphnodes selector is suboptimal, but graph code already does this in two other places.
author Anton Shestakov <av6@dwimlabs.net>
date Fri, 01 Dec 2017 14:17:20 +0800
parents 9153871d50e0
children 4b1c04082cdc
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 #
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
30921
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
12 import os
25956
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
13 import socket
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
14 import time
8113
87a1605979e4 add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8108
diff changeset
15 import warnings
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
16
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
17 from .i18n import _
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
18
25956
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
19 from . import (
31375
d57aa655ce97 lock: encode result of gethostname into a bytestring
Augie Fackler <augie@google.com>
parents: 31354
diff changeset
20 encoding,
25956
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
21 error,
30921
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
22 pycompat,
25956
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
23 util,
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
24 )
8cd30e9277ae lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
25
30920
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
26 def _getlockprefix():
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
27 """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
28
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
29 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
30 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
31 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
32 """
31378
2e48c776a874 lock: do not encode result of gethostname on Python 2
Yuya Nishihara <yuya@tcha.org>
parents: 31375
diff changeset
33 result = socket.gethostname()
2e48c776a874 lock: do not encode result of gethostname on Python 2
Yuya Nishihara <yuya@tcha.org>
parents: 31375
diff changeset
34 if pycompat.ispy3:
2e48c776a874 lock: do not encode result of gethostname on Python 2
Yuya Nishihara <yuya@tcha.org>
parents: 31375
diff changeset
35 result = result.encode(pycompat.sysstr(encoding.encoding), 'replace')
30921
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
36 if pycompat.sysplatform.startswith('linux'):
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
37 try:
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
38 result += '/%x' % os.stat('/proc/self/ns/pid').st_ino
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
39 except OSError as ex:
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
40 if ex.errno not in (errno.ENOENT, errno.EACCES, errno.ENOTDIR):
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
41 raise
1f151a33af8e lock: include Linux pid namespace identifier in prefix
Jun Wu <quark@fb.com>
parents: 30920
diff changeset
42 return result
30920
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
43
35209
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
44 def trylock(ui, vfs, lockname, timeout, warntimeout, *args, **kwargs):
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
45 """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
46
35209
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
47 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
48 the held lock while trying to acquires it."""
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
49
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
50 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
51 """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
52 # show more details for new-style locks
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
53 if ':' in locker:
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
54 host, pid = locker.split(":", 1)
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
55 msg = _("waiting for lock on %s held by process %r "
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
56 "on host %r\n") % (l.desc, pid, host)
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
57 else:
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
58 msg = _("waiting for lock on %s held by %r\n") % (l.desc, locker)
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
59 printer(msg)
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
60
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
61 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
62
35209
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
63 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
64 warningidx = 0
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
65 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
66 warningidx = -1
35209
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
67 elif warntimeout:
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
68 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
69
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
70 delay = 0
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
71 while True:
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
72 try:
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
73 l._trylock()
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
74 break
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
75 except error.LockHeld as inst:
35209
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
76 if delay == debugidx:
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
77 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
78 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
79 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
80 if timeout <= delay:
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
81 raise error.LockHeld(errno.ETIMEDOUT, inst.filename,
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
82 l.desc, inst.locker)
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
83 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
84 delay += 1
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
85
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
86 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
87 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
88 if 0 <= warningidx <= l.delay:
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
89 ui.warn(_("got lock after %s seconds\n") % l.delay)
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
90 else:
9153871d50e0 lock: allow to configure when the lock messages are displayed
Boris Feld <boris.feld@octobus.net>
parents: 35208
diff changeset
91 ui.debug("got lock after %s 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
92 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
93 l.acquirefn()
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
94 return l
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
95
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1530
diff changeset
96 class lock(object):
9309
cfdcb7a465af localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents: 8312
diff changeset
97 '''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
98 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
99 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
100 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
101
cfdcb7a465af localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents: 8312
diff changeset
102 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
103 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
104 else under .hg/.'''
cfdcb7a465af localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents: 8312
diff changeset
105
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
106 # 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
107
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
108 # 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
109 # 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
110
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
111 # 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
112 # 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
113
4947
3e25a6eb5c9a lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents: 3877
diff changeset
114 _host = None
3e25a6eb5c9a lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents: 3877
diff changeset
115
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26291
diff changeset
116 def __init__(self, vfs, file, timeout=-1, releasefn=None, acquirefn=None,
35208
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
117 desc=None, inheritchecker=None, parentlock=None,
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
118 dolock=True):
20091
abfe6a8e619b lock: take both vfs and lock file path relative to vfs to access via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19927
diff changeset
119 self.vfs = vfs
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
120 self.f = file
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
121 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
122 self.timeout = timeout
1530
abfab59fce79 add a releasefn keyword to lock.lock
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1062
diff changeset
123 self.releasefn = releasefn
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26291
diff changeset
124 self.acquirefn = acquirefn
2016
ff5c9a92f556 fix backtrace printed when cannot get lock.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1877
diff changeset
125 self.desc = desc
26498
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
126 self._inheritchecker = inheritchecker
26356
927fa07a2ba4 lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26321
diff changeset
127 self.parentlock = parentlock
927fa07a2ba4 lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26321
diff changeset
128 self._parentheld = False
927fa07a2ba4 lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26321
diff changeset
129 self._inherited = False
15589
cc24e4ed3e0c lock: change name of release chain
Matt Mackall <mpm@selenic.com>
parents: 15583
diff changeset
130 self.postrelease = []
26383
0fceb34806e1 lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents: 26359
diff changeset
131 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
132 if dolock:
1b758105b5c7 lock: add a trylock method handling the timeout and messaging logic
Boris Feld <boris.feld@octobus.net>
parents: 32088
diff changeset
133 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
134 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
135 self.acquirefn()
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
136
27797
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
137 def __enter__(self):
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
138 return self
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
139
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
140 def __exit__(self, exc_type, exc_value, exc_tb):
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
141 self.release()
054abf2377e8 lock: turn a lock into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents: 26498
diff changeset
142
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
143 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
144 if self.held:
8113
87a1605979e4 add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8108
diff changeset
145 warnings.warn("use lock.release instead of del lock",
87a1605979e4 add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8108
diff changeset
146 category=DeprecationWarning,
87a1605979e4 add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8108
diff changeset
147 stacklevel=2)
87a1605979e4 add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8108
diff changeset
148
8108
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
149 # 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
150 # 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
151 self.held = 1
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
152
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
153 self.release()
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
154
26383
0fceb34806e1 lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents: 26359
diff changeset
155 def _getpid(self):
28027
14033c5dd261 util: enable getpid to be replaced
timeless <timeless@mozdev.org>
parents: 27797
diff changeset
156 # wrapper around util.getpid() to make testing easier
14033c5dd261 util: enable getpid to be replaced
timeless <timeless@mozdev.org>
parents: 27797
diff changeset
157 return util.getpid()
26383
0fceb34806e1 lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents: 26359
diff changeset
158
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
159 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
160 timeout = self.timeout
14494
1ffeeb91c55d check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents: 13281
diff changeset
161 while True:
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
162 try:
26082
b188f60bd955 lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents: 26081
diff changeset
163 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
164 return self.timeout - timeout
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23032
diff changeset
165 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
166 if timeout != 0:
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
167 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
168 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
169 timeout -= 1
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
170 continue
7640
7197812e8d44 error: move lock errors
Matt Mackall <mpm@selenic.com>
parents: 4959
diff changeset
171 raise error.LockHeld(errno.ETIMEDOUT, inst.filename, self.desc,
7197812e8d44 error: move lock errors
Matt Mackall <mpm@selenic.com>
parents: 4959
diff changeset
172 inst.locker)
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 503
diff changeset
173
26082
b188f60bd955 lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents: 26081
diff changeset
174 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
175 if self.held:
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
176 self.held += 1
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
177 return
4947
3e25a6eb5c9a lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents: 3877
diff changeset
178 if lock._host is None:
30920
dc9f086c7691 lock: move lock._host calculation to a function
Jun Wu <quark@fb.com>
parents: 28959
diff changeset
179 lock._host = _getlockprefix()
31354
e6a2b625e0d9 lock: use %d to format integer into a bytestring
Augie Fackler <augie@google.com>
parents: 30921
diff changeset
180 lockname = '%s:%d' % (lock._host, self.pid)
26081
3b6e5914edd8 lock: loop a finite number of times in trylock (issue4787)
Matt Mackall <mpm@selenic.com>
parents: 25956
diff changeset
181 retry = 5
3b6e5914edd8 lock: loop a finite number of times in trylock (issue4787)
Matt Mackall <mpm@selenic.com>
parents: 25956
diff changeset
182 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
183 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
184 try:
20091
abfe6a8e619b lock: take both vfs and lock file path relative to vfs to access via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19927
diff changeset
185 self.vfs.makelock(lockname, self.f)
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
186 self.held = 1
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23032
diff changeset
187 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
188 if why.errno == errno.EEXIST:
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
189 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
190 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
191 continue
e1938d6051da lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 31378
diff changeset
192
26387
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
193 # 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
194 # 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
195 # 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
196 # but the lockfile to not be removed.
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
197 if locker == self.parentlock:
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
198 self._parentheld = True
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
199 self.held = 1
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
200 return
e16f80f89a29 lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents: 26383
diff changeset
201 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
202 if locker is not None:
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
203 raise error.LockHeld(errno.EAGAIN,
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
204 self.vfs.join(self.f), self.desc,
7640
7197812e8d44 error: move lock errors
Matt Mackall <mpm@selenic.com>
parents: 4959
diff changeset
205 locker)
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
206 else:
7640
7197812e8d44 error: move lock errors
Matt Mackall <mpm@selenic.com>
parents: 4959
diff changeset
207 raise error.LockUnavailable(why.errno, why.strerror,
7197812e8d44 error: move lock errors
Matt Mackall <mpm@selenic.com>
parents: 4959
diff changeset
208 why.filename, self.desc)
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
209
32088
0d892d820a51 lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32087
diff changeset
210 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
211 # 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
212 # by many processes"
0d892d820a51 lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32087
diff changeset
213 raise error.LockHeld(errno.EAGAIN,
0d892d820a51 lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32087
diff changeset
214 self.vfs.join(self.f), self.desc, "")
0d892d820a51 lock: avoid unintentional lock acquisition at failure of readlock
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32087
diff changeset
215
26290
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
216 def _readlock(self):
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
217 """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
218
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
219 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
220 for new-style locks.
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
221 """
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
222 try:
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
223 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
224 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
225 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
226 return None
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
227 raise
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
228
26291
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
229 def _testlock(self, locker):
26290
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
230 if locker is None:
9664d32bd6cb lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26082
diff changeset
231 return None
2579
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2016
diff changeset
232 try:
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2016
diff changeset
233 host, pid = locker.split(":", 1)
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2016
diff changeset
234 except ValueError:
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
235 return locker
4947
3e25a6eb5c9a lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents: 3877
diff changeset
236 if host != lock._host:
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
237 return locker
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
238 try:
2579
0875cda033fd use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2016
diff changeset
239 pid = int(pid)
9685
a820cd39d415 lock: catch specific exceptions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9680
diff changeset
240 except ValueError:
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
241 return locker
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
242 if util.testpid(pid):
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
243 return locker
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
244 # 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
245 # 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
246 try:
20091
abfe6a8e619b lock: take both vfs and lock file path relative to vfs to access via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19927
diff changeset
247 l = lock(self.vfs, self.f + '.break', timeout=0)
abfe6a8e619b lock: take both vfs and lock file path relative to vfs to access via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19927
diff changeset
248 self.vfs.unlink(self.f)
1877
d314a89fa4f1 change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1836
diff changeset
249 l.release()
7640
7197812e8d44 error: move lock errors
Matt Mackall <mpm@selenic.com>
parents: 4959
diff changeset
250 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
251 return locker
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
252
26291
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
253 def testlock(self):
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
254 """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
255
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
256 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
257 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
258 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
259 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
260
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
261 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
262
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
263 """
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
264 locker = self._readlock()
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
265 return self._testlock(locker)
1d33842c5b3e lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents: 26290
diff changeset
266
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
267 @contextlib.contextmanager
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
268 def inherit(self):
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
269 """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
270
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
271 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
272 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
273 -- 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
274 """
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
275 if not self.held:
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
276 raise error.LockInheritanceContractViolation(
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
277 'inherit can only be called while lock is held')
26357
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
278 if self._inherited:
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
279 raise error.LockInheritanceContractViolation(
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
280 'inherit cannot be called while lock is already inherited')
26498
e8564e04382d lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents: 26474
diff changeset
281 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
282 self._inheritchecker()
26357
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
283 if self.releasefn:
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
284 self.releasefn()
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
285 if self._parentheld:
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
286 lockname = self.parentlock
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
287 else:
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
288 lockname = '%s:%s' % (lock._host, self.pid)
6979a1369185 lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents: 26356
diff changeset
289 self._inherited = True
26473
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
290 try:
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
291 yield lockname
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
292 finally:
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
293 if self.acquirefn:
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
294 self.acquirefn()
5f94e64f182c lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents: 26387
diff changeset
295 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
296
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
297 def release(self):
15583
926a06f7a353 lock: add mechanism to register post release callback
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14494
diff changeset
298 """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
299
17537
31f32a96e1e3 Merge spelling fixes
Bryan O'Sullivan <bryano@fb.com>
parents: 17427 17510
diff changeset
300 If the lock has been acquired multiple times, the actual release is
17510
7c44b703657b spelling: release
timeless@mozdev.org
parents: 15589
diff changeset
301 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
302 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
303 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
304 elif self.held == 1:
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
305 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
306 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
307 # 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
308 return
503
c6a2e41c8c60 Fix troubles with clone and exception handling
mpm@selenic.com
parents: 429
diff changeset
309 try:
23032
f484be02bd35 lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents: 20380
diff changeset
310 if self.releasefn:
f484be02bd35 lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents: 20380
diff changeset
311 self.releasefn()
f484be02bd35 lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents: 20380
diff changeset
312 finally:
26359
c545d51c901e lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26358
diff changeset
313 if not self._parentheld:
c545d51c901e lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26358
diff changeset
314 try:
c545d51c901e lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26358
diff changeset
315 self.vfs.unlink(self.f)
c545d51c901e lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26358
diff changeset
316 except OSError:
c545d51c901e lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26358
diff changeset
317 pass
26474
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
318 # 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
319 # at all.
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
320 if not self._parentheld:
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
321 for callback in self.postrelease:
431094a3b21f lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents: 26473
diff changeset
322 callback()
28959
518c3e392f75 lock: clear postrelease hooks list after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
323 # 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
324 self.postrelease = None
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents:
diff changeset
325
8108
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
326 def release(*locks):
a26d33749bd8 made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 7640
diff changeset
327 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
328 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
329 lock.release()