Mercurial > hg
annotate mercurial/lock.py @ 27412:14b184263846
record: fix hunk handling to remember the current function
author | timeless <timeless@mozdev.org> |
---|---|
date | Thu, 17 Dec 2015 20:13:29 +0000 |
parents | e8564e04382d |
children | 054abf2377e8 |
rev | line source |
---|---|
9309
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
1 # lock.py - simple advisory locking scheme for mercurial |
161 | 2 # |
2859 | 3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> |
161 | 4 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8113
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
161 | 7 |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
8 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 |
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
12 import os |
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
13 import socket |
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
14 import time |
8113
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
15 import warnings |
161 | 16 |
25956
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
17 from . import ( |
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
18 error, |
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
19 util, |
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
20 ) |
8cd30e9277ae
lock: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
21 |
1559
59b3639df0a9
Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents:
1530
diff
changeset
|
22 class lock(object): |
9309
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
23 '''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
|
24 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
|
25 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
|
26 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
|
27 |
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
28 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
|
29 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
|
30 else under .hg/.''' |
cfdcb7a465af
localrepo: document the locking scheme a little better
Greg Ward <greg-hg@gerg.ca>
parents:
8312
diff
changeset
|
31 |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
32 # 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
|
33 |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
34 # 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
|
35 # 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
|
36 |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
37 # 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
|
38 # 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
|
39 |
4947
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
40 _host = None |
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
41 |
26321
db4c192cb9b3
lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents:
26291
diff
changeset
|
42 def __init__(self, vfs, file, timeout=-1, releasefn=None, acquirefn=None, |
26498
e8564e04382d
lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents:
26474
diff
changeset
|
43 desc=None, inheritchecker=None, parentlock=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
|
44 self.vfs = vfs |
161 | 45 self.f = file |
46 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
|
47 self.timeout = timeout |
1530
abfab59fce79
add a releasefn keyword to lock.lock
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1062
diff
changeset
|
48 self.releasefn = releasefn |
26321
db4c192cb9b3
lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents:
26291
diff
changeset
|
49 self.acquirefn = acquirefn |
2016
ff5c9a92f556
fix backtrace printed when cannot get lock.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1877
diff
changeset
|
50 self.desc = desc |
26498
e8564e04382d
lock: add a way to prevent locks from being inherited
Siddharth Agarwal <sid0@fb.com>
parents:
26474
diff
changeset
|
51 self._inheritchecker = inheritchecker |
26356
927fa07a2ba4
lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26321
diff
changeset
|
52 self.parentlock = parentlock |
927fa07a2ba4
lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26321
diff
changeset
|
53 self._parentheld = False |
927fa07a2ba4
lock: introduce state to keep track of inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26321
diff
changeset
|
54 self._inherited = False |
15589
cc24e4ed3e0c
lock: change name of release chain
Matt Mackall <mpm@selenic.com>
parents:
15583
diff
changeset
|
55 self.postrelease = [] |
26383
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
56 self.pid = self._getpid() |
20380
c697b70f295f
localrepo: give a sigh of relief when getting lock after waiting for it
Mads Kiilerich <madski@unity3d.com>
parents:
20091
diff
changeset
|
57 self.delay = self.lock() |
26321
db4c192cb9b3
lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents:
26291
diff
changeset
|
58 if self.acquirefn: |
db4c192cb9b3
lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents:
26291
diff
changeset
|
59 self.acquirefn() |
161 | 60 |
61 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
|
62 if self.held: |
8113
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
63 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
|
64 category=DeprecationWarning, |
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
65 stacklevel=2) |
87a1605979e4
add a deprecation warning for gc based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
8108
diff
changeset
|
66 |
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
67 # 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
|
68 # 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
|
69 self.held = 1 |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
70 |
161 | 71 self.release() |
72 | |
26383
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
73 def _getpid(self): |
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
74 # wrapper around os.getpid() to make testing easier |
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
75 return os.getpid() |
0fceb34806e1
lock: add a wrapper to os.getpid() to make testing easier
Siddharth Agarwal <sid0@fb.com>
parents:
26359
diff
changeset
|
76 |
161 | 77 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
|
78 timeout = self.timeout |
14494
1ffeeb91c55d
check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents:
13281
diff
changeset
|
79 while True: |
161 | 80 try: |
26082
b188f60bd955
lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents:
26081
diff
changeset
|
81 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
|
82 return self.timeout - timeout |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23032
diff
changeset
|
83 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
|
84 if timeout != 0: |
161 | 85 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
|
86 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
|
87 timeout -= 1 |
161 | 88 continue |
7640 | 89 raise error.LockHeld(errno.ETIMEDOUT, inst.filename, self.desc, |
90 inst.locker) | |
515 | 91 |
26082
b188f60bd955
lock: make trylock private
Matt Mackall <mpm@selenic.com>
parents:
26081
diff
changeset
|
92 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
|
93 if self.held: |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
94 self.held += 1 |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
95 return |
4947
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
96 if lock._host is None: |
3e25a6eb5c9a
lock.py: cache hostname, but not pid, in case we fork
Bryan O'Sullivan <bos@serpentine.com>
parents:
3877
diff
changeset
|
97 lock._host = socket.gethostname() |
18907
af9fa8d4c939
lock: if we fork, ensure that only the parent releases
Bryan O'Sullivan <bryano@fb.com>
parents:
17683
diff
changeset
|
98 lockname = '%s:%s' % (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
|
99 retry = 5 |
3b6e5914edd8
lock: loop a finite number of times in trylock (issue4787)
Matt Mackall <mpm@selenic.com>
parents:
25956
diff
changeset
|
100 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
|
101 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
|
102 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
|
103 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
|
104 self.held = 1 |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23032
diff
changeset
|
105 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
|
106 if why.errno == errno.EEXIST: |
26387
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
107 locker = self._readlock() |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
108 # 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
|
109 # 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
|
110 # 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
|
111 # but the lockfile to not be removed. |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
112 if locker == self.parentlock: |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
113 self._parentheld = True |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
114 self.held = 1 |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
115 return |
e16f80f89a29
lock: recognize parent locks while acquiring
Siddharth Agarwal <sid0@fb.com>
parents:
26383
diff
changeset
|
116 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
|
117 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
|
118 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
|
119 self.vfs.join(self.f), self.desc, |
7640 | 120 locker) |
1877
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
121 else: |
7640 | 122 raise error.LockUnavailable(why.errno, why.strerror, |
123 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
|
124 |
26290
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
125 def _readlock(self): |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
126 """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
|
127 |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
128 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
|
129 for new-style locks. |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
130 """ |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
131 try: |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
132 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
|
133 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
|
134 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
|
135 return None |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
136 raise |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
137 |
26291
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
138 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
|
139 if locker is None: |
9664d32bd6cb
lock: factor code to read lock into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26082
diff
changeset
|
140 return None |
2579
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
141 try: |
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
142 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
|
143 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
|
144 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
|
145 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
|
146 return locker |
161 | 147 try: |
2579
0875cda033fd
use __contains__, index or split instead of str.find
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2016
diff
changeset
|
148 pid = int(pid) |
9685
a820cd39d415
lock: catch specific exceptions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9680
diff
changeset
|
149 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
|
150 return locker |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
151 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
|
152 return locker |
d314a89fa4f1
change lock format to let us detect and break stale locks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1836
diff
changeset
|
153 # 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
|
154 # 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
|
155 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
|
156 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
|
157 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
|
158 l.release() |
7640 | 159 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
|
160 return locker |
161 | 161 |
26291
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
162 def testlock(self): |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
163 """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
|
164 |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
165 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
|
166 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
|
167 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
|
168 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
|
169 |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
170 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
|
171 |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
172 """ |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
173 locker = self._readlock() |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
174 return self._testlock(locker) |
1d33842c5b3e
lock: factor out lock testing into a separate function
Siddharth Agarwal <sid0@fb.com>
parents:
26290
diff
changeset
|
175 |
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
176 @contextlib.contextmanager |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
177 def inherit(self): |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
178 """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
|
179 |
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
180 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
|
181 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
|
182 -- 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
|
183 """ |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
184 if not self.held: |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
185 raise error.LockInheritanceContractViolation( |
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
186 '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
|
187 if self._inherited: |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
188 raise error.LockInheritanceContractViolation( |
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
189 '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
|
190 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
|
191 self._inheritchecker() |
26357
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
192 if self.releasefn: |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
193 self.releasefn() |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
194 if self._parentheld: |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
195 lockname = self.parentlock |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
196 else: |
6979a1369185
lock: add a method to prepare the lock for inheritance
Siddharth Agarwal <sid0@fb.com>
parents:
26356
diff
changeset
|
197 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
|
198 self._inherited = True |
26473
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
199 try: |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
200 yield lockname |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
201 finally: |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
202 if self.acquirefn: |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
203 self.acquirefn() |
5f94e64f182c
lock: turn prepinherit/reacquire into a single context manager
Siddharth Agarwal <sid0@fb.com>
parents:
26387
diff
changeset
|
204 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
|
205 |
161 | 206 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
|
207 """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
|
208 |
17537 | 209 If the lock has been acquired multiple times, the actual release is |
17510 | 210 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
|
211 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
|
212 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
|
213 elif self.held == 1: |
161 | 214 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
|
215 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
|
216 # 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
|
217 return |
503
c6a2e41c8c60
Fix troubles with clone and exception handling
mpm@selenic.com
parents:
429
diff
changeset
|
218 try: |
23032
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
219 if self.releasefn: |
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
220 self.releasefn() |
f484be02bd35
lock: while releasing, unlink lockfile even if the release function throws
Siddharth Agarwal <sid0@fb.com>
parents:
20380
diff
changeset
|
221 finally: |
26359
c545d51c901e
lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26358
diff
changeset
|
222 if not self._parentheld: |
c545d51c901e
lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26358
diff
changeset
|
223 try: |
c545d51c901e
lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26358
diff
changeset
|
224 self.vfs.unlink(self.f) |
c545d51c901e
lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26358
diff
changeset
|
225 except OSError: |
c545d51c901e
lock.release: do not unlink inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26358
diff
changeset
|
226 pass |
26474
431094a3b21f
lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26473
diff
changeset
|
227 # 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
|
228 # at all. |
431094a3b21f
lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26473
diff
changeset
|
229 if not self._parentheld: |
431094a3b21f
lock.release: don't call postrelease functions for inherited locks
Siddharth Agarwal <sid0@fb.com>
parents:
26473
diff
changeset
|
230 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
|
231 callback() |
161 | 232 |
8108
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
233 def release(*locks): |
a26d33749bd8
made repo locks recursive and deprecate refcounting based lock releasing
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
7640
diff
changeset
|
234 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
|
235 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
|
236 lock.release() |