annotate hgext/inotify/server.py @ 7451:fca9947652ce

inotify: close most file descriptors when autostarting Otherwise, operations that autostart while talking to an SSH repository prevent SSH stderr from closing normally. This causes hangs at the end of hg clone or hg pull -u.
author Brendan Cully <brendan@kublai.com>
date Mon, 01 Dec 2008 13:38:26 -0800
parents b4ac1e2cd38c
children 67e59a9886d5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1 # server.py - inotify status server
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
2 #
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
3 # Copyright 2006, 2007, 2008 Bryan O'Sullivan <bos@serpentine.com>
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
4 # Copyright 2007, 2008 Brendan Cully <brendan@kublai.com>
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
5 #
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
6 # This software may be used and distributed according to the terms
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
7 # of the GNU General Public License, incorporated herein by reference.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
8
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
9 from mercurial.i18n import _
7420
b4ac1e2cd38c inotify: remove unused imports (thanks pyflakes)
Brendan Cully <brendan@kublai.com>
parents: 7351
diff changeset
10 from mercurial import osutil, util
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
11 import common
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
12 import errno, os, select, socket, stat, struct, sys, tempfile, time
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
13
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
14 try:
6994
bf727bab38b9 Use relative imports in inotify.server.
Brendan Cully <brendan@kublai.com>
parents: 6287
diff changeset
15 import linux as inotify
bf727bab38b9 Use relative imports in inotify.server.
Brendan Cully <brendan@kublai.com>
parents: 6287
diff changeset
16 from linux import watcher
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
17 except ImportError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
18 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
19
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
20 class AlreadyStartedException(Exception): pass
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
21
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
22 def join(a, b):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
23 if a:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
24 if a[-1] == '/':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
25 return a + b
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
26 return a + '/' + b
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
27 return b
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
28
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
29 walk_ignored_errors = (errno.ENOENT, errno.ENAMETOOLONG)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
30
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
31 def walkrepodirs(repo):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
32 '''Iterate over all subdirectories of this repo.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
33 Exclude the .hg directory, any nested repos, and ignored dirs.'''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
34 rootslash = repo.root + os.sep
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
35 def walkit(dirname, top):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
36 hginside = False
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
37 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
38 for name, kind in osutil.listdir(rootslash + dirname):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
39 if kind == stat.S_IFDIR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
40 if name == '.hg':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
41 hginside = True
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
42 if not top: break
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
43 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
44 d = join(dirname, name)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
45 if repo.dirstate._ignore(d):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
46 continue
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
47 for subdir, hginsub in walkit(d, False):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
48 if not hginsub:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
49 yield subdir, False
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
51 if err.errno not in walk_ignored_errors:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
53 yield rootslash + dirname, hginside
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
54 for dirname, hginside in walkit('', True):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
55 yield dirname
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
56
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
57 def walk(repo, root):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
58 '''Like os.walk, but only yields regular files.'''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
59
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
60 # This function is critical to performance during startup.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
61
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
62 reporoot = root == ''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
63 rootslash = repo.root + os.sep
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
64
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
65 def walkit(root, reporoot):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
66 files, dirs = [], []
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
67 hginside = False
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
68
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
69 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
70 fullpath = rootslash + root
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
71 for name, kind in osutil.listdir(fullpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
72 if kind == stat.S_IFDIR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
73 if name == '.hg':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
74 hginside = True
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
75 if reporoot:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
76 continue
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
77 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
78 break
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
79 dirs.append(name)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
80 elif kind in (stat.S_IFREG, stat.S_IFLNK):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
81 path = join(root, name)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
82 files.append((name, kind))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
83
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
84 yield hginside, fullpath, dirs, files
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
85
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
86 for subdir in dirs:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
87 path = join(root, subdir)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
88 if repo.dirstate._ignore(path):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
89 continue
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
90 for result in walkit(path, False):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
91 if not result[0]:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
92 yield result
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
93 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
94 if err.errno not in walk_ignored_errors:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
95 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
96 for result in walkit(root, reporoot):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
97 yield result[1:]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
98
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
99 def _explain_watch_limit(ui, repo, count):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
100 path = '/proc/sys/fs/inotify/max_user_watches'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
101 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
102 limit = int(file(path).read())
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
103 except IOError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
104 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
105 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
106 raise util.Abort(_('this system does not seem to '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
107 'support inotify'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
108 ui.warn(_('*** the current per-user limit on the number '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
109 'of inotify watches is %s\n') % limit)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
110 ui.warn(_('*** this limit is too low to watch every '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
111 'directory in this repository\n'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
112 ui.warn(_('*** counting directories: '))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
113 ndirs = len(list(walkrepodirs(repo)))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
114 ui.warn(_('found %d\n') % ndirs)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
115 newlimit = min(limit, 1024)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
116 while newlimit < ((limit + ndirs) * 1.1):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
117 newlimit *= 2
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
118 ui.warn(_('*** to raise the limit from %d to %d (run as root):\n') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
119 (limit, newlimit))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
120 ui.warn(_('*** echo %d > %s\n') % (newlimit, path))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
121 raise util.Abort(_('cannot watch %s until inotify watch limit is raised')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
122 % repo.root)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
123
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
124 class Watcher(object):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
125 poll_events = select.POLLIN
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
126 statuskeys = 'almr!?'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
127
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
128 def __init__(self, ui, repo, master):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
129 self.ui = ui
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
130 self.repo = repo
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
131 self.wprefix = self.repo.wjoin('')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
132 self.timeout = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
133 self.master = master
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
134 self.mask = (
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
135 inotify.IN_ATTRIB |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
136 inotify.IN_CREATE |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
137 inotify.IN_DELETE |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
138 inotify.IN_DELETE_SELF |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
139 inotify.IN_MODIFY |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
140 inotify.IN_MOVED_FROM |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
141 inotify.IN_MOVED_TO |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
142 inotify.IN_MOVE_SELF |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
143 inotify.IN_ONLYDIR |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
144 inotify.IN_UNMOUNT |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
145 0)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
146 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
147 self.watcher = watcher.Watcher()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
148 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
149 raise util.Abort(_('inotify service not available: %s') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
150 err.strerror)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
151 self.threshold = watcher.Threshold(self.watcher)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
152 self.registered = True
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
153 self.fileno = self.watcher.fileno
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
154
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
155 self.repo.dirstate.__class__.inotifyserver = True
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
156
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
157 self.tree = {}
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
158 self.statcache = {}
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
159 self.statustrees = dict([(s, {}) for s in self.statuskeys])
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
160
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
161 self.watches = 0
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
162 self.last_event = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
163
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
164 self.eventq = {}
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
165 self.deferred = 0
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
166
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
167 self.ds_info = self.dirstate_info()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
168 self.scan()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
169
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
170 def event_time(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
171 last = self.last_event
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
172 now = time.time()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
173 self.last_event = now
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
174
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
175 if last is None:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
176 return 'start'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
177 delta = now - last
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
178 if delta < 5:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
179 return '+%.3f' % delta
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
180 if delta < 50:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
181 return '+%.2f' % delta
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
182 return '+%.1f' % delta
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
183
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
184 def dirstate_info(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
185 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
186 st = os.lstat(self.repo.join('dirstate'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
187 return st.st_mtime, st.st_ino
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
188 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
189 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
190 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
191 return 0, 0
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
192
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
193 def add_watch(self, path, mask):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
194 if not path:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
195 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
196 if self.watcher.path(path) is None:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
197 if self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
198 self.ui.note(_('watching %r\n') % path[len(self.wprefix):])
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
199 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
200 self.watcher.add(path, mask)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
201 self.watches += 1
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
202 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
203 if err.errno in (errno.ENOENT, errno.ENOTDIR):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
204 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
205 if err.errno != errno.ENOSPC:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
206 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
207 _explain_watch_limit(self.ui, self.repo, self.watches)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
208
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
209 def setup(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
210 self.ui.note(_('watching directories under %r\n') % self.repo.root)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
211 self.add_watch(self.repo.path, inotify.IN_DELETE)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
212 self.check_dirstate()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
213
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
214 def wpath(self, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
215 path = evt.fullpath
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
216 if path == self.repo.root:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
217 return ''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
218 if path.startswith(self.wprefix):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
219 return path[len(self.wprefix):]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
220 raise 'wtf? ' + path
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
221
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
222 def dir(self, tree, path):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
223 if path:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
224 for name in path.split('/'):
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
225 tree.setdefault(name, {})
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
226 tree = tree[name]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
227 return tree
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
228
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
229 def lookup(self, path, tree):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
230 if path:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
231 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
232 for name in path.split('/'):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
233 tree = tree[name]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
234 except KeyError:
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
235 return 'x'
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
236 except TypeError:
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
237 return 'd'
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
238 return tree
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
240 def split(self, path):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
241 c = path.rfind('/')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
242 if c == -1:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
243 return '', path
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
244 return path[:c], path[c+1:]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
245
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
246 def filestatus(self, fn, st):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
247 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
248 type_, mode, size, time = self.repo.dirstate._map[fn][:4]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
249 except KeyError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
250 type_ = '?'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
251 if type_ == 'n':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
252 if not st:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
253 return '!'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
254 st_mode, st_size, st_mtime = st
7082
be81b4788115 inotify: fix confusion on files in lookup state
Matt Mackall <mpm@selenic.com>
parents: 6998
diff changeset
255 if size == -1:
be81b4788115 inotify: fix confusion on files in lookup state
Matt Mackall <mpm@selenic.com>
parents: 6998
diff changeset
256 return 'l'
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
257 if size and (size != st_size or (mode ^ st_mode) & 0100):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
258 return 'm'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
259 if time != int(st_mtime):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
260 return 'l'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
261 return 'n'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
262 if type_ in 'ma' and not st:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
263 return '!'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
264 if type_ == '?' and self.repo.dirstate._ignore(fn):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
265 return 'i'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
266 return type_
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
267
7086
4033195d455b inotify: avoid status getting out of sync
Matt Mackall <mpm@selenic.com>
parents: 7085
diff changeset
268 def updatestatus(self, wfn, st=None, status=None):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
269 if st:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
270 status = self.filestatus(wfn, st)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
271 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
272 self.statcache.pop(wfn, None)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
273 root, fn = self.split(wfn)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
274 d = self.dir(self.tree, root)
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
275 oldstatus = d.get(fn)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
276 isdir = False
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
277 if oldstatus:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
278 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
279 if not status:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
280 if oldstatus in 'almn':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
281 status = '!'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
282 elif oldstatus == 'r':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
283 status = 'r'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
284 except TypeError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
285 # oldstatus may be a dict left behind by a deleted
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
286 # directory
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
287 isdir = True
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
288 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
289 if oldstatus in self.statuskeys and oldstatus != status:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
290 del self.dir(self.statustrees[oldstatus], root)[fn]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
291 if self.ui.debugflag and oldstatus != status:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
292 if isdir:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
293 self.ui.note(_('status: %r dir(%d) -> %s\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
294 (wfn, len(oldstatus), status))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
295 else:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
296 self.ui.note(_('status: %r %s -> %s\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
297 (wfn, oldstatus, status))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
298 if not isdir:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
299 if status and status != 'i':
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
300 d[fn] = status
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
301 if status in self.statuskeys:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
302 dd = self.dir(self.statustrees[status], root)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
303 if oldstatus != status or fn not in dd:
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
304 dd[fn] = status
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
305 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
306 d.pop(fn, None)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
307
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
308 def check_deleted(self, key):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
309 # Files that had been deleted but were present in the dirstate
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
310 # may have vanished from the dirstate; we must clean them up.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
311 nuke = []
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
312 for wfn, ignore in self.walk(key, self.statustrees[key]):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
313 if wfn not in self.repo.dirstate:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
314 nuke.append(wfn)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
315 for wfn in nuke:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
316 root, fn = self.split(wfn)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
317 del self.dir(self.statustrees[key], root)[fn]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
318 del self.dir(self.tree, root)[fn]
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
319
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
320 def scan(self, topdir=''):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
321 self.handle_timeout()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
322 ds = self.repo.dirstate._map.copy()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
323 self.add_watch(join(self.repo.root, topdir), self.mask)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
324 for root, dirs, entries in walk(self.repo, topdir):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
325 for d in dirs:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
326 self.add_watch(join(root, d), self.mask)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
327 wroot = root[len(self.wprefix):]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
328 d = self.dir(self.tree, wroot)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
329 for fn, kind in entries:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
330 wfn = join(wroot, fn)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
331 self.updatestatus(wfn, self.getstat(wfn))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
332 ds.pop(wfn, None)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
333 wtopdir = topdir
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
334 if wtopdir and wtopdir[-1] != '/':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
335 wtopdir += '/'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
336 for wfn, state in ds.iteritems():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
337 if not wfn.startswith(wtopdir):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
338 continue
7302
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
339 try:
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
340 st = self.stat(wfn)
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
341 except OSError:
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
342 status = state[0]
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
343 self.updatestatus(wfn, None, status=status)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
344 else:
7086
4033195d455b inotify: avoid status getting out of sync
Matt Mackall <mpm@selenic.com>
parents: 7085
diff changeset
345 self.updatestatus(wfn, st)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
346 self.check_deleted('!')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
347 self.check_deleted('r')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
348
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
349 def check_dirstate(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
350 ds_info = self.dirstate_info()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
351 if ds_info == self.ds_info:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
352 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
353 self.ds_info = ds_info
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
354 if not self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
355 self.last_event = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
356 self.ui.note(_('%s dirstate reload\n') % self.event_time())
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
357 self.repo.dirstate.invalidate()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
358 self.scan()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
359 self.ui.note(_('%s end dirstate reload\n') % self.event_time())
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
360
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
361 def walk(self, states, tree, prefix=''):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
362 # This is the "inner loop" when talking to the client.
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
363
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
364 for name, val in tree.iteritems():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
365 path = join(prefix, name)
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
366 try:
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
367 if val in states:
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
368 yield path, val
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
369 except TypeError:
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
370 for p in self.walk(states, val, path):
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
371 yield p
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
372
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
373 def update_hgignore(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
374 # An update of the ignore file can potentially change the
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
375 # states of all unknown and ignored files.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
376
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
377 # XXX If the user has other ignore files outside the repo, or
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
378 # changes their list of ignore files at run time, we'll
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
379 # potentially never see changes to them. We could get the
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
380 # client to report to us what ignore data they're using.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
381 # But it's easier to do nothing than to open that can of
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
382 # worms.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
383
7085
1fcc282e2c43 inotify: fixup rebuilding ignore
Matt Mackall <mpm@selenic.com>
parents: 7082
diff changeset
384 if '_ignore' in self.repo.dirstate.__dict__:
1fcc282e2c43 inotify: fixup rebuilding ignore
Matt Mackall <mpm@selenic.com>
parents: 7082
diff changeset
385 delattr(self.repo.dirstate, '_ignore')
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
386 self.ui.note(_('rescanning due to .hgignore change\n'))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
387 self.scan()
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
388
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
389 def getstat(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
390 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
391 return self.statcache[wpath]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
392 except KeyError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
393 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
394 return self.stat(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
395 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
396 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
397 raise
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
398
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
399 def stat(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
400 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
401 st = os.lstat(join(self.wprefix, wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
402 ret = st.st_mode, st.st_size, st.st_mtime
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
403 self.statcache[wpath] = ret
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
404 return ret
7280
810ca383da9c remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7220
diff changeset
405 except OSError:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
406 self.statcache.pop(wpath, None)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
407 raise
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
408
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
409 def created(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
410 if wpath == '.hgignore':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
411 self.update_hgignore()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
412 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
413 st = self.stat(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
414 if stat.S_ISREG(st[0]):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
415 self.updatestatus(wpath, st)
7280
810ca383da9c remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7220
diff changeset
416 except OSError:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
417 pass
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
418
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
419 def modified(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
420 if wpath == '.hgignore':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
421 self.update_hgignore()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
422 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
423 st = self.stat(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
424 if stat.S_ISREG(st[0]):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
425 if self.repo.dirstate[wpath] in 'lmn':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
426 self.updatestatus(wpath, st)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
427 except OSError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
428 pass
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
429
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
430 def deleted(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
431 if wpath == '.hgignore':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
432 self.update_hgignore()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
433 elif wpath.startswith('.hg/'):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
434 if wpath == '.hg/wlock':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
435 self.check_dirstate()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
436 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
437
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
438 self.updatestatus(wpath, None)
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
439
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
440 def schedule_work(self, wpath, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
441 self.eventq.setdefault(wpath, [])
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
442 prev = self.eventq[wpath]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
443 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
444 if prev and evt == 'm' and prev[-1] in 'cm':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
445 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
446 self.eventq[wpath].append(evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
447 finally:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
448 self.deferred += 1
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
449 self.timeout = 250
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
450
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
451 def deferred_event(self, wpath, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
452 if evt == 'c':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
453 self.created(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
454 elif evt == 'm':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
455 self.modified(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
456 elif evt == 'd':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
457 self.deleted(wpath)
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
458
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
459 def process_create(self, wpath, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
460 if self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
461 self.ui.note(_('%s event: created %s\n') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
462 (self.event_time(), wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
463
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
464 if evt.mask & inotify.IN_ISDIR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
465 self.scan(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
466 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
467 self.schedule_work(wpath, 'c')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
468
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
469 def process_delete(self, wpath, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
470 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
471 self.ui.note(_('%s event: deleted %s\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
472 (self.event_time(), wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
473
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
474 if evt.mask & inotify.IN_ISDIR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
475 self.scan(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
476 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
477 self.schedule_work(wpath, 'd')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
478
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
479 def process_modify(self, wpath, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
480 if self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
481 self.ui.note(_('%s event: modified %s\n') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
482 (self.event_time(), wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
483
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
484 if not (evt.mask & inotify.IN_ISDIR):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
485 self.schedule_work(wpath, 'm')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
486
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
487 def process_unmount(self, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
488 self.ui.warn(_('filesystem containing %s was unmounted\n') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
489 evt.fullpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
490 sys.exit(0)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
491
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
492 def handle_event(self, fd, event):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
493 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
494 self.ui.note(_('%s readable: %d bytes\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
495 (self.event_time(), self.threshold.readable()))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
496 if not self.threshold():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
497 if self.registered:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
498 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
499 self.ui.note(_('%s below threshold - unhooking\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
500 (self.event_time()))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
501 self.master.poll.unregister(fd)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
502 self.registered = False
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
503 self.timeout = 250
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
504 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
505 self.read_events()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
506
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
507 def read_events(self, bufsize=None):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
508 events = self.watcher.read(bufsize)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
509 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
510 self.ui.note(_('%s reading %d events\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
511 (self.event_time(), len(events)))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
512 for evt in events:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
513 wpath = self.wpath(evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
514 if evt.mask & inotify.IN_UNMOUNT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
515 self.process_unmount(wpath, evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
516 elif evt.mask & (inotify.IN_MODIFY | inotify.IN_ATTRIB):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
517 self.process_modify(wpath, evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
518 elif evt.mask & (inotify.IN_DELETE | inotify.IN_DELETE_SELF |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
519 inotify.IN_MOVED_FROM):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
520 self.process_delete(wpath, evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
521 elif evt.mask & (inotify.IN_CREATE | inotify.IN_MOVED_TO):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
522 self.process_create(wpath, evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
523
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
524 def handle_timeout(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
525 if not self.registered:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
526 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
527 self.ui.note(_('%s hooking back up with %d bytes readable\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
528 (self.event_time(), self.threshold.readable()))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
529 self.read_events(0)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
530 self.master.poll.register(self, select.POLLIN)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
531 self.registered = True
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
532
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
533 if self.eventq:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
534 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
535 self.ui.note(_('%s processing %d deferred events as %d\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
536 (self.event_time(), self.deferred,
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
537 len(self.eventq)))
6762
f67d1468ac50 util: add sort helper
Matt Mackall <mpm@selenic.com>
parents: 6287
diff changeset
538 for wpath, evts in util.sort(self.eventq.items()):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
539 for evt in evts:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
540 self.deferred_event(wpath, evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
541 self.eventq.clear()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
542 self.deferred = 0
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
543 self.timeout = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
544
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
545 def shutdown(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
546 self.watcher.close()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
547
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
548 class Server(object):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
549 poll_events = select.POLLIN
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
550
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
551 def __init__(self, ui, repo, watcher, timeout):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
552 self.ui = ui
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
553 self.repo = repo
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
554 self.watcher = watcher
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
555 self.timeout = timeout
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
556 self.sock = socket.socket(socket.AF_UNIX)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
557 self.sockpath = self.repo.join('inotify.sock')
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
558 self.realsockpath = None
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
559 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
560 self.sock.bind(self.sockpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
561 except socket.error, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
562 if err[0] == errno.EADDRINUSE:
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
563 raise AlreadyStartedException(_('could not start server: %s')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
564 % err[1])
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
565 if err[0] == "AF_UNIX path too long":
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
566 tempdir = tempfile.mkdtemp(prefix="hg-inotify-")
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
567 self.realsockpath = os.path.join(tempdir, "inotify.sock")
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
568 try:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
569 self.sock.bind(self.realsockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
570 os.symlink(self.realsockpath, self.sockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
571 except (OSError, socket.error), inst:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
572 try:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
573 os.unlink(self.realsockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
574 except:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
575 pass
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
576 os.rmdir(tempdir)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
577 if inst.errno == errno.EEXIST:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
578 raise AlreadyStartedException(_('could not start server: %s')
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
579 % inst.strerror)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
580 raise
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
581 else:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
582 raise
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
583 self.sock.listen(5)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
584 self.fileno = self.sock.fileno
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
585
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
586 def handle_timeout(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
587 pass
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
588
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
589 def handle_event(self, fd, event):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
590 sock, addr = self.sock.accept()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
591
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
592 cs = common.recvcs(sock)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
593 version = ord(cs.read(1))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
594
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
595 sock.sendall(chr(common.version))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
596
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
597 if version != common.version:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
598 self.ui.warn(_('received query from incompatible client '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
599 'version %d\n') % version)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
600 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
601
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
602 names = cs.read().split('\0')
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
603
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
604 states = names.pop()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
605
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
606 self.ui.note(_('answering query for %r\n') % states)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
607
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
608 if self.watcher.timeout:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
609 # We got a query while a rescan is pending. Make sure we
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
610 # rescan before responding, or we could give back a wrong
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
611 # answer.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
612 self.watcher.handle_timeout()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
613
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
614 if not names:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
615 def genresult(states, tree):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
616 for fn, state in self.watcher.walk(states, tree):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
617 yield fn
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
618 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
619 def genresult(states, tree):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
620 for fn in names:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
621 l = self.watcher.lookup(fn, tree)
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
622 try:
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
623 if l in states:
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
624 yield fn
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
625 except TypeError:
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
626 for f, s in self.watcher.walk(states, l, fn):
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
627 yield f
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
628
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
629 results = ['\0'.join(r) for r in [
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
630 genresult('l', self.watcher.statustrees['l']),
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
631 genresult('m', self.watcher.statustrees['m']),
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
632 genresult('a', self.watcher.statustrees['a']),
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
633 genresult('r', self.watcher.statustrees['r']),
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
634 genresult('!', self.watcher.statustrees['!']),
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
635 '?' in states and genresult('?', self.watcher.statustrees['?']) or [],
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
636 [],
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
637 'c' in states and genresult('n', self.watcher.tree) or [],
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
638 ]]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
639
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
640 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
641 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
642 sock.sendall(struct.pack(common.resphdrfmt,
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
643 *map(len, results)))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
644 sock.sendall(''.join(results))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
645 finally:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
646 sock.shutdown(socket.SHUT_WR)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
647 except socket.error, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
648 if err[0] != errno.EPIPE:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
649 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
650
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
651 def shutdown(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
652 self.sock.close()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
653 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
654 os.unlink(self.sockpath)
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
655 if self.realsockpath:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
656 os.unlink(self.realsockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
657 os.rmdir(os.path.dirname(self.realsockpath))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
658 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
659 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
660 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
661
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
662 class Master(object):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
663 def __init__(self, ui, repo, timeout=None):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
664 self.ui = ui
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
665 self.repo = repo
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
666 self.poll = select.poll()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
667 self.watcher = Watcher(ui, repo, self)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
668 self.server = Server(ui, repo, self.watcher, timeout)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
669 self.table = {}
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
670 for obj in (self.watcher, self.server):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
671 fd = obj.fileno()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
672 self.table[fd] = obj
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
673 self.poll.register(fd, obj.poll_events)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
674
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
675 def register(self, fd, mask):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
676 self.poll.register(fd, mask)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
677
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
678 def shutdown(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
679 for obj in self.table.itervalues():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
680 obj.shutdown()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
681
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
682 def run(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
683 self.watcher.setup()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
684 self.ui.note(_('finished setup\n'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
685 if os.getenv('TIME_STARTUP'):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
686 sys.exit(0)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
687 while True:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
688 timeout = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
689 timeobj = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
690 for obj in self.table.itervalues():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
691 if obj.timeout is not None and (timeout is None or obj.timeout < timeout):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
692 timeout, timeobj = obj.timeout, obj
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
693 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
694 if self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
695 if timeout is None:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
696 self.ui.note(_('polling: no timeout\n'))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
697 else:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
698 self.ui.note(_('polling: %sms timeout\n') % timeout)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
699 events = self.poll.poll(timeout)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
700 except select.error, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
701 if err[0] == errno.EINTR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
702 continue
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
703 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
704 if events:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
705 for fd, event in events:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
706 self.table[fd].handle_event(fd, event)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
707 elif timeobj:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
708 timeobj.handle_timeout()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
709
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
710 def start(ui, repo):
7451
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
711 def closefds(ignore):
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
712 # (from python bug #1177468)
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
713 # close all inherited file descriptors
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
714 # Python 2.4.1 and later use /dev/urandom to seed the random module's RNG
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
715 # a file descriptor is kept internally as os._urandomfd (created on demand
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
716 # the first time os.urandom() is called), and should not be closed
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
717 try:
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
718 os.urandom(4)
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
719 urandom_fd = getattr(os, '_urandomfd', None)
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
720 except AttributeError:
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
721 urandom_fd = None
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
722 ignore.append(urandom_fd)
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
723 for fd in range(3, 256):
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
724 if fd in ignore:
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
725 continue
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
726 try:
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
727 os.close(fd)
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
728 except OSError:
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
729 pass
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
730
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
731 m = Master(ui, repo)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
732 sys.stdout.flush()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
733 sys.stderr.flush()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
734
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
735 pid = os.fork()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
736 if pid:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
737 return pid
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
738
7451
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
739 closefds([m.server.fileno(), m.watcher.fileno()])
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
740 os.setsid()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
741
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
742 fd = os.open('/dev/null', os.O_RDONLY)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
743 os.dup2(fd, 0)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
744 if fd > 0:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
745 os.close(fd)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
746
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
747 fd = os.open(ui.config('inotify', 'log', '/dev/null'),
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
748 os.O_RDWR | os.O_CREAT | os.O_TRUNC)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
749 os.dup2(fd, 1)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
750 os.dup2(fd, 2)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
751 if fd > 2:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
752 os.close(fd)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
753
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
754 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
755 m.run()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
756 finally:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
757 m.shutdown()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
758 os._exit(0)