Show More
@@ -1,119 +1,119 b'' | |||
|
1 | 1 | # state.py - fsmonitor persistent state |
|
2 | 2 | # |
|
3 | 3 | # Copyright 2013-2016 Facebook, Inc. |
|
4 | 4 | # |
|
5 | 5 | # This software may be used and distributed according to the terms of the |
|
6 | 6 | # GNU General Public License version 2 or any later version. |
|
7 | 7 | |
|
8 | 8 | from __future__ import absolute_import |
|
9 | 9 | |
|
10 | 10 | import errno |
|
11 | 11 | import os |
|
12 | 12 | import socket |
|
13 | 13 | import struct |
|
14 | 14 | |
|
15 | 15 | from mercurial.i18n import _ |
|
16 | 16 | from mercurial import pathutil |
|
17 | 17 | |
|
18 | 18 | _version = 4 |
|
19 | 19 | _versionformat = ">I" |
|
20 | 20 | |
|
21 | 21 | class state(object): |
|
22 | 22 | def __init__(self, repo): |
|
23 |
self._ |
|
|
23 | self._vfs = repo.vfs | |
|
24 | 24 | self._ui = repo.ui |
|
25 | 25 | self._rootdir = pathutil.normasprefix(repo.root) |
|
26 | 26 | self._lastclock = None |
|
27 | 27 | |
|
28 | 28 | self.mode = self._ui.config('fsmonitor', 'mode', default='on') |
|
29 | 29 | self.walk_on_invalidate = self._ui.configbool( |
|
30 | 30 | 'fsmonitor', 'walk_on_invalidate', False) |
|
31 | 31 | self.timeout = float(self._ui.config( |
|
32 | 32 | 'fsmonitor', 'timeout', default='2')) |
|
33 | 33 | |
|
34 | 34 | def get(self): |
|
35 | 35 | try: |
|
36 |
file = self._ |
|
|
36 | file = self._vfs('fsmonitor.state', 'rb') | |
|
37 | 37 | except IOError as inst: |
|
38 | 38 | if inst.errno != errno.ENOENT: |
|
39 | 39 | raise |
|
40 | 40 | return None, None, None |
|
41 | 41 | |
|
42 | 42 | versionbytes = file.read(4) |
|
43 | 43 | if len(versionbytes) < 4: |
|
44 | 44 | self._ui.log( |
|
45 | 45 | 'fsmonitor', 'fsmonitor: state file only has %d bytes, ' |
|
46 | 46 | 'nuking state\n' % len(versionbytes)) |
|
47 | 47 | self.invalidate() |
|
48 | 48 | return None, None, None |
|
49 | 49 | try: |
|
50 | 50 | diskversion = struct.unpack(_versionformat, versionbytes)[0] |
|
51 | 51 | if diskversion != _version: |
|
52 | 52 | # different version, nuke state and start over |
|
53 | 53 | self._ui.log( |
|
54 | 54 | 'fsmonitor', 'fsmonitor: version switch from %d to ' |
|
55 | 55 | '%d, nuking state\n' % (diskversion, _version)) |
|
56 | 56 | self.invalidate() |
|
57 | 57 | return None, None, None |
|
58 | 58 | |
|
59 | 59 | state = file.read().split('\0') |
|
60 | 60 | # state = hostname\0clock\0ignorehash\0 + list of files, each |
|
61 | 61 | # followed by a \0 |
|
62 | 62 | if len(state) < 3: |
|
63 | 63 | self._ui.log( |
|
64 | 64 | 'fsmonitor', 'fsmonitor: state file truncated (expected ' |
|
65 | 65 | '3 chunks, found %d), nuking state\n', len(state)) |
|
66 | 66 | self.invalidate() |
|
67 | 67 | return None, None, None |
|
68 | 68 | diskhostname = state[0] |
|
69 | 69 | hostname = socket.gethostname() |
|
70 | 70 | if diskhostname != hostname: |
|
71 | 71 | # file got moved to a different host |
|
72 | 72 | self._ui.log('fsmonitor', 'fsmonitor: stored hostname "%s" ' |
|
73 | 73 | 'different from current "%s", nuking state\n' % |
|
74 | 74 | (diskhostname, hostname)) |
|
75 | 75 | self.invalidate() |
|
76 | 76 | return None, None, None |
|
77 | 77 | |
|
78 | 78 | clock = state[1] |
|
79 | 79 | ignorehash = state[2] |
|
80 | 80 | # discard the value after the last \0 |
|
81 | 81 | notefiles = state[3:-1] |
|
82 | 82 | |
|
83 | 83 | finally: |
|
84 | 84 | file.close() |
|
85 | 85 | |
|
86 | 86 | return clock, ignorehash, notefiles |
|
87 | 87 | |
|
88 | 88 | def set(self, clock, ignorehash, notefiles): |
|
89 | 89 | if clock is None: |
|
90 | 90 | self.invalidate() |
|
91 | 91 | return |
|
92 | 92 | |
|
93 | 93 | try: |
|
94 |
file = self._ |
|
|
94 | file = self._vfs('fsmonitor.state', 'wb', atomictemp=True) | |
|
95 | 95 | except (IOError, OSError): |
|
96 | 96 | self._ui.warn(_("warning: unable to write out fsmonitor state\n")) |
|
97 | 97 | return |
|
98 | 98 | |
|
99 | 99 | with file: |
|
100 | 100 | file.write(struct.pack(_versionformat, _version)) |
|
101 | 101 | file.write(socket.gethostname() + '\0') |
|
102 | 102 | file.write(clock + '\0') |
|
103 | 103 | file.write(ignorehash + '\0') |
|
104 | 104 | if notefiles: |
|
105 | 105 | file.write('\0'.join(notefiles)) |
|
106 | 106 | file.write('\0') |
|
107 | 107 | |
|
108 | 108 | def invalidate(self): |
|
109 | 109 | try: |
|
110 | 110 | os.unlink(os.path.join(self._rootdir, '.hg', 'fsmonitor.state')) |
|
111 | 111 | except OSError as inst: |
|
112 | 112 | if inst.errno != errno.ENOENT: |
|
113 | 113 | raise |
|
114 | 114 | |
|
115 | 115 | def setlastclock(self, clock): |
|
116 | 116 | self._lastclock = clock |
|
117 | 117 | |
|
118 | 118 | def getlastclock(self): |
|
119 | 119 | return self._lastclock |
General Comments 0
You need to be logged in to leave comments.
Login now