equal
deleted
inserted
replaced
7 |
7 |
8 from __future__ import absolute_import |
8 from __future__ import absolute_import |
9 |
9 |
10 import contextlib |
10 import contextlib |
11 import errno |
11 import errno |
|
12 import os |
12 import socket |
13 import socket |
13 import time |
14 import time |
14 import warnings |
15 import warnings |
15 |
16 |
16 from . import ( |
17 from . import ( |
17 error, |
18 error, |
|
19 pycompat, |
18 util, |
20 util, |
19 ) |
21 ) |
20 |
22 |
21 def _getlockprefix(): |
23 def _getlockprefix(): |
22 """Return a string which is used to differentiate pid namespaces |
24 """Return a string which is used to differentiate pid namespaces |
23 |
25 |
24 It's useful to detect "dead" processes and remove stale locks with |
26 It's useful to detect "dead" processes and remove stale locks with |
25 confidence. Typically it's just hostname. |
27 confidence. Typically it's just hostname. On modern linux, we include an |
|
28 extra Linux-specific pid namespace identifier. |
26 """ |
29 """ |
27 return socket.gethostname() |
30 result = socket.gethostname() |
|
31 if pycompat.sysplatform.startswith('linux'): |
|
32 try: |
|
33 result += '/%x' % os.stat('/proc/self/ns/pid').st_ino |
|
34 except OSError as ex: |
|
35 if ex.errno not in (errno.ENOENT, errno.EACCES, errno.ENOTDIR): |
|
36 raise |
|
37 return result |
28 |
38 |
29 class lock(object): |
39 class lock(object): |
30 '''An advisory lock held by one process to control access to a set |
40 '''An advisory lock held by one process to control access to a set |
31 of files. Non-cooperating processes or incorrectly written scripts |
41 of files. Non-cooperating processes or incorrectly written scripts |
32 can ignore Mercurial's locking scheme and stomp all over the |
42 can ignore Mercurial's locking scheme and stomp all over the |