annotate hgext/inotify/server.py @ 8787:9aca76502280

inotify: server: move split() out of server split() has nothing to do with the server logic, it does not need to be in the class. Move it on top, next to join() which does the opposite.
author Nicolas Dumazet <nicdumz.commits@gmail.com>
date Wed, 27 May 2009 00:29:11 +0900
parents 55af9be4efac
children 23730a475363
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 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
6 # This software may be used and distributed according to the terms of the
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
7 # GNU General Public License version 2, incorporated herein by reference.
6239
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
8787
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
29 def split(path):
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
30 c = path.rfind('/')
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
31 if c == -1:
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
32 return '', path
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
33 return path[:c], path[c+1:]
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
34
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
35 walk_ignored_errors = (errno.ENOENT, errno.ENAMETOOLONG)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
36
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
37 def walkrepodirs(repo):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
38 '''Iterate over all subdirectories of this repo.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
39 Exclude the .hg directory, any nested repos, and ignored dirs.'''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
40 rootslash = repo.root + os.sep
8322
3c6c21eb3416 inotify: inotify.server.walkrepodirs() simplify walking
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8321
diff changeset
41
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
42 def walkit(dirname, top):
8321
ec985dcfd7da inotify: inotify.server.walkrepodirs() simplify
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8320
diff changeset
43 fullpath = rootslash + dirname
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
44 try:
8321
ec985dcfd7da inotify: inotify.server.walkrepodirs() simplify
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8320
diff changeset
45 for name, kind in osutil.listdir(fullpath):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
46 if kind == stat.S_IFDIR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
47 if name == '.hg':
8323
589a82fb02a2 inotify: inotify.server.walk*() cleanup
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8322
diff changeset
48 if not top:
589a82fb02a2 inotify: inotify.server.walk*() cleanup
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8322
diff changeset
49 return
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
51 d = join(dirname, name)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 if repo.dirstate._ignore(d):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
53 continue
8322
3c6c21eb3416 inotify: inotify.server.walkrepodirs() simplify walking
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8321
diff changeset
54 for subdir in walkit(d, False):
3c6c21eb3416 inotify: inotify.server.walkrepodirs() simplify walking
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8321
diff changeset
55 yield subdir
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
56 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
57 if err.errno not in walk_ignored_errors:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
58 raise
8324
b923d599c309 inotify: inotify.server.walk*() remove unnecessary var
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8323
diff changeset
59 yield fullpath
8322
3c6c21eb3416 inotify: inotify.server.walkrepodirs() simplify walking
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8321
diff changeset
60
3c6c21eb3416 inotify: inotify.server.walkrepodirs() simplify walking
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8321
diff changeset
61 return walkit('', True)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
62
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
63 def walk(repo, root):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
64 '''Like os.walk, but only yields regular files.'''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
65
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
66 # This function is critical to performance during startup.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
67
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
68 rootslash = repo.root + os.sep
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
69
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
70 def walkit(root, reporoot):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
71 files, dirs = [], []
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
72
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
73 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
74 fullpath = rootslash + root
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
75 for name, kind in osutil.listdir(fullpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
76 if kind == stat.S_IFDIR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
77 if name == '.hg':
8325
f2559645643a inotify: inotify.server.walk() simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8324
diff changeset
78 if not reporoot:
8323
589a82fb02a2 inotify: inotify.server.walk*() cleanup
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8322
diff changeset
79 return
8325
f2559645643a inotify: inotify.server.walk() simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8324
diff changeset
80 else:
f2559645643a inotify: inotify.server.walk() simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8324
diff changeset
81 dirs.append(name)
8381
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
82 path = join(root, name)
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
83 if repo.dirstate._ignore(path):
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
84 continue
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
85 for result in walkit(path, False):
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
86 yield result
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
87 elif kind in (stat.S_IFREG, stat.S_IFLNK):
8334
0695288e8c37 inotify: inotify.server.walk() filetype is never used, do not yield it
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8325
diff changeset
88 files.append(name)
8324
b923d599c309 inotify: inotify.server.walk*() remove unnecessary var
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8323
diff changeset
89 yield fullpath, dirs, files
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
90
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
91 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
92 if err.errno not in walk_ignored_errors:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
93 raise
8320
a1305c1c8d8e inotify: inotify.server.walk() simplify algorithm
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8319
diff changeset
94
a1305c1c8d8e inotify: inotify.server.walk() simplify algorithm
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8319
diff changeset
95 return walkit(root, root == '')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
96
8786
55af9be4efac inotify: remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8610
diff changeset
97 def _explain_watch_limit(ui, repo):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
98 path = '/proc/sys/fs/inotify/max_user_watches'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
99 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
100 limit = int(file(path).read())
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
101 except IOError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
102 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
103 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
104 raise util.Abort(_('this system does not seem to '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
105 'support inotify'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
106 ui.warn(_('*** the current per-user limit on the number '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
107 'of inotify watches is %s\n') % limit)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
108 ui.warn(_('*** this limit is too low to watch every '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
109 'directory in this repository\n'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
110 ui.warn(_('*** counting directories: '))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
111 ndirs = len(list(walkrepodirs(repo)))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
112 ui.warn(_('found %d\n') % ndirs)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
113 newlimit = min(limit, 1024)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
114 while newlimit < ((limit + ndirs) * 1.1):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
115 newlimit *= 2
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
116 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
117 (limit, newlimit))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
118 ui.warn(_('*** echo %d > %s\n') % (newlimit, path))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
119 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
120 % repo.root)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
121
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
122 class pollable(object):
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
123 """
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
124 Interface to support polling.
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
125 The file descriptor returned by fileno() is registered to a polling
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
126 object.
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
127 Usage:
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
128 Every tick, check if an event has happened since the last tick:
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
129 * If yes, call handle_events
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
130 * If no, call handle_timeout
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
131 """
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
132 poll_events = select.POLLIN
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
133 def fileno(self):
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
134 raise NotImplementedError
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
135
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
136 def handle_events(self, events):
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
137 raise NotImplementedError
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
138
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
139 def handle_timeout(self):
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
140 raise NotImplementedError
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
141
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
142 def shutdown(self):
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
143 raise NotImplementedError
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
144
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
145 class repowatcher(pollable):
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
146 """
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
147 Watches inotify events
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
148 """
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
149 statuskeys = 'almr!?'
8383
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
150 mask = (
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
151 inotify.IN_ATTRIB |
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
152 inotify.IN_CREATE |
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
153 inotify.IN_DELETE |
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
154 inotify.IN_DELETE_SELF |
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
155 inotify.IN_MODIFY |
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
156 inotify.IN_MOVED_FROM |
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
157 inotify.IN_MOVED_TO |
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
158 inotify.IN_MOVE_SELF |
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
159 inotify.IN_ONLYDIR |
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
160 inotify.IN_UNMOUNT |
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
161 0)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
162
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
163 def __init__(self, ui, repo, master):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
164 self.ui = ui
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
165 self.repo = repo
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
166 self.wprefix = self.repo.wjoin('')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
167 self.timeout = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
168 self.master = master
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
169 try:
8385
1536501ade62 inotify: Coding Style: name classes in lowercase.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8384
diff changeset
170 self.watcher = watcher.watcher()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
171 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
172 raise util.Abort(_('inotify service not available: %s') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
173 err.strerror)
8385
1536501ade62 inotify: Coding Style: name classes in lowercase.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8384
diff changeset
174 self.threshold = watcher.threshold(self.watcher)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
175 self.registered = True
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
176 self.fileno = self.watcher.fileno
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
177
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
178 self.tree = {}
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
179 self.statcache = {}
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
180 self.statustrees = dict([(s, {}) for s in self.statuskeys])
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
181
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
182 self.watches = 0
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
183 self.last_event = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
184
8605
ed2d9bdbfad2 inotify: do not defer inotify events processing
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8604
diff changeset
185 self.lastevent = {}
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
186
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
187 self.ds_info = self.dirstate_info()
8604
578f2a0049cd inotify: do not recurse in handle_timeout(): call it explicitely, not in scan()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8600
diff changeset
188 self.handle_timeout()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
189 self.scan()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
190
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
191 def event_time(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
192 last = self.last_event
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
193 now = time.time()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
194 self.last_event = now
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
195
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
196 if last is None:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
197 return 'start'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
198 delta = now - last
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
199 if delta < 5:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
200 return '+%.3f' % delta
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
201 if delta < 50:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
202 return '+%.2f' % delta
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
203 return '+%.1f' % delta
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
204
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
205 def dirstate_info(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
206 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
207 st = os.lstat(self.repo.join('dirstate'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
208 return st.st_mtime, st.st_ino
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
209 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
210 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
211 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
212 return 0, 0
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 add_watch(self, path, mask):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
215 if not path:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
216 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
217 if self.watcher.path(path) is None:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
218 if self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
219 self.ui.note(_('watching %r\n') % path[len(self.wprefix):])
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
220 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
221 self.watcher.add(path, mask)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
222 self.watches += 1
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
223 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
224 if err.errno in (errno.ENOENT, errno.ENOTDIR):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
225 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
226 if err.errno != errno.ENOSPC:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
227 raise
8786
55af9be4efac inotify: remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8610
diff changeset
228 _explain_watch_limit(self.ui, self.repo)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
229
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
230 def setup(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
231 self.ui.note(_('watching directories under %r\n') % self.repo.root)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
232 self.add_watch(self.repo.path, inotify.IN_DELETE)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
233 self.check_dirstate()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
234
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
235 def wpath(self, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
236 path = evt.fullpath
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
237 if path == self.repo.root:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
238 return ''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
239 if path.startswith(self.wprefix):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
240 return path[len(self.wprefix):]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
241 raise 'wtf? ' + path
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
242
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
243 def dir(self, tree, path):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
244 if path:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
245 for name in path.split('/'):
8384
483d9b2103da inotify: dic.setdefault(k, d) ; v = dic[k] --> v = dic.setdefault(k, d)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8383
diff changeset
246 tree = tree.setdefault(name, {})
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
247 return tree
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
248
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
249 def lookup(self, path, tree):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
250 if path:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
251 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
252 for name in path.split('/'):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
253 tree = tree[name]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
254 except KeyError:
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
255 return 'x'
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
256 except TypeError:
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
257 return 'd'
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
258 return tree
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
259
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
260 def filestatus(self, fn, st):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
261 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
262 type_, mode, size, time = self.repo.dirstate._map[fn][:4]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
263 except KeyError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
264 type_ = '?'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
265 if type_ == 'n':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
266 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
267 if size == -1:
be81b4788115 inotify: fix confusion on files in lookup state
Matt Mackall <mpm@selenic.com>
parents: 6998
diff changeset
268 return 'l'
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
269 if size and (size != st_size or (mode ^ st_mode) & 0100):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
270 return 'm'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
271 if time != int(st_mtime):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
272 return 'l'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
273 return 'n'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
274 if type_ == '?' and self.repo.dirstate._ignore(fn):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
275 return 'i'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
276 return type_
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
277
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
278 def updatefile(self, wfn, osstat):
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
279 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
280 update the file entry of an existing file.
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
281
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
282 osstat: (mode, size, time) tuple, as returned by os.lstat(wfn)
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
283 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
284
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
285 self._updatestatus(wfn, self.filestatus(wfn, osstat))
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
286
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
287 def deletefile(self, wfn, oldstatus):
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
288 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
289 update the entry of a file which has been deleted.
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
290
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
291 oldstatus: char in statuskeys, status of the file before deletion
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
292 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
293 if oldstatus == 'r':
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
294 newstatus = 'r'
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
295 elif oldstatus in 'almn':
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
296 newstatus = '!'
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
297 else:
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
298 newstatus = None
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
299
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
300 self.statcache.pop(wfn, None)
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
301 self._updatestatus(wfn, newstatus)
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
302
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
303 def _updatestatus(self, wfn, newstatus):
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
304 '''
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
305 Update the stored status of a file or directory.
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
306
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
307 newstatus: - char in (statuskeys + 'ni'), new status to apply.
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
308 - or None, to stop tracking wfn
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
309 '''
8787
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
310 root, fn = split(wfn)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
311 d = self.dir(self.tree, root)
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
312
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
313 oldstatus = d.get(fn)
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
314 # oldstatus can be either:
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
315 # - None : fn is new
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
316 # - a char in statuskeys: fn is a (tracked) file
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
317 # - a dict: fn is a directory
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
318 isdir = isinstance(oldstatus, dict)
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
319
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
320 if self.ui.debugflag and oldstatus != newstatus:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
321 if isdir:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
322 self.ui.note(_('status: %r dir(%d) -> %s\n') %
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
323 (wfn, len(oldstatus), newstatus))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
324 else:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
325 self.ui.note(_('status: %r %s -> %s\n') %
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
326 (wfn, oldstatus, newstatus))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
327 if not isdir:
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
328 if oldstatus and oldstatus in self.statuskeys \
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
329 and oldstatus != newstatus:
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
330 del self.dir(self.statustrees[oldstatus], root)[fn]
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
331 if newstatus and newstatus != 'i':
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
332 d[fn] = newstatus
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
333 if newstatus in self.statuskeys:
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
334 dd = self.dir(self.statustrees[newstatus], root)
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
335 if oldstatus != newstatus or fn not in dd:
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
336 dd[fn] = newstatus
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
337 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
338 d.pop(fn, None)
7892
67e59a9886d5 Fixing issue1542, adding a relevant test
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7451
diff changeset
339
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
340
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
341 def check_deleted(self, key):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
342 # Files that had been deleted but were present in the dirstate
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
343 # may have vanished from the dirstate; we must clean them up.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
344 nuke = []
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
345 for wfn, ignore in self.walk(key, self.statustrees[key]):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
346 if wfn not in self.repo.dirstate:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
347 nuke.append(wfn)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
348 for wfn in nuke:
8787
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
349 root, fn = split(wfn)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
350 del self.dir(self.statustrees[key], root)[fn]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
351 del self.dir(self.tree, root)[fn]
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
352
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
353 def scan(self, topdir=''):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
354 ds = self.repo.dirstate._map.copy()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
355 self.add_watch(join(self.repo.root, topdir), self.mask)
8334
0695288e8c37 inotify: inotify.server.walk() filetype is never used, do not yield it
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8325
diff changeset
356 for root, dirs, files in walk(self.repo, topdir):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
357 for d in dirs:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
358 self.add_watch(join(root, d), self.mask)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
359 wroot = root[len(self.wprefix):]
8334
0695288e8c37 inotify: inotify.server.walk() filetype is never used, do not yield it
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8325
diff changeset
360 for fn in files:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
361 wfn = join(wroot, fn)
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
362 self.updatefile(wfn, self.getstat(wfn))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
363 ds.pop(wfn, None)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
364 wtopdir = topdir
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
365 if wtopdir and wtopdir[-1] != '/':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
366 wtopdir += '/'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
367 for wfn, state in ds.iteritems():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
368 if not wfn.startswith(wtopdir):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
369 continue
7302
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
370 try:
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
371 st = self.stat(wfn)
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
372 except OSError:
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
373 status = state[0]
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
374 self.deletefile(wfn, status)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
375 else:
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
376 self.updatefile(wfn, st)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
377 self.check_deleted('!')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
378 self.check_deleted('r')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
379
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
380 def check_dirstate(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
381 ds_info = self.dirstate_info()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
382 if ds_info == self.ds_info:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
383 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
384 self.ds_info = ds_info
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
385 if not self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
386 self.last_event = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
387 self.ui.note(_('%s dirstate reload\n') % self.event_time())
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
388 self.repo.dirstate.invalidate()
8604
578f2a0049cd inotify: do not recurse in handle_timeout(): call it explicitely, not in scan()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8600
diff changeset
389 self.handle_timeout()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
390 self.scan()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
391 self.ui.note(_('%s end dirstate reload\n') % self.event_time())
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
392
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
393 def walk(self, states, tree, prefix=''):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
394 # This is the "inner loop" when talking to the client.
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
395
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
396 for name, val in tree.iteritems():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
397 path = join(prefix, name)
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
398 try:
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
399 if val in states:
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
400 yield path, val
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
401 except TypeError:
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
402 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
403 yield p
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
404
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
405 def update_hgignore(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
406 # An update of the ignore file can potentially change the
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
407 # states of all unknown and ignored files.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
408
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
409 # 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
410 # changes their list of ignore files at run time, we'll
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
411 # potentially never see changes to them. We could get the
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
412 # client to report to us what ignore data they're using.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
413 # 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
414 # worms.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
415
7085
1fcc282e2c43 inotify: fixup rebuilding ignore
Matt Mackall <mpm@selenic.com>
parents: 7082
diff changeset
416 if '_ignore' in self.repo.dirstate.__dict__:
1fcc282e2c43 inotify: fixup rebuilding ignore
Matt Mackall <mpm@selenic.com>
parents: 7082
diff changeset
417 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
418 self.ui.note(_('rescanning due to .hgignore change\n'))
8604
578f2a0049cd inotify: do not recurse in handle_timeout(): call it explicitely, not in scan()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8600
diff changeset
419 self.handle_timeout()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
420 self.scan()
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
421
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
422 def getstat(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
423 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
424 return self.statcache[wpath]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
425 except KeyError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
426 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
427 return self.stat(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
428 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
429 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
430 raise
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
431
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
432 def stat(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
433 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
434 st = os.lstat(join(self.wprefix, wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
435 ret = st.st_mode, st.st_size, st.st_mtime
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
436 self.statcache[wpath] = ret
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
437 return ret
7280
810ca383da9c remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7220
diff changeset
438 except OSError:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
439 self.statcache.pop(wpath, None)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
440 raise
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
441
8606
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
442 def eventaction(code):
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
443 def decorator(f):
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
444 def wrapper(self, wpath):
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
445 if code == 'm' and wpath in self.lastevent and \
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
446 self.lastevent[wpath] in 'cm':
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
447 return
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
448 self.lastevent[wpath] = code
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
449 self.timeout = 250
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
450
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
451 f(self, wpath)
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
452
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
453 wrapper.func_name = f.func_name
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
454 return wrapper
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
455 return decorator
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
456
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
457 @eventaction('c')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
458 def created(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
459 if wpath == '.hgignore':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
460 self.update_hgignore()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
461 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
462 st = self.stat(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
463 if stat.S_ISREG(st[0]):
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
464 self.updatefile(wpath, st)
7280
810ca383da9c remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7220
diff changeset
465 except OSError:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
466 pass
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
467
8606
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
468 @eventaction('m')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
469 def modified(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
470 if wpath == '.hgignore':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
471 self.update_hgignore()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
472 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
473 st = self.stat(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
474 if stat.S_ISREG(st[0]):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
475 if self.repo.dirstate[wpath] in 'lmn':
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
476 self.updatefile(wpath, st)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
477 except OSError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
478 pass
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
479
8606
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
480 @eventaction('d')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
481 def deleted(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
482 if wpath == '.hgignore':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
483 self.update_hgignore()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
484 elif wpath.startswith('.hg/'):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
485 if wpath == '.hg/wlock':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
486 self.check_dirstate()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
487 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
488
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
489 self.deletefile(wpath, self.repo.dirstate[wpath])
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
490
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
491 def process_create(self, wpath, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
492 if self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
493 self.ui.note(_('%s event: created %s\n') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
494 (self.event_time(), wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
495
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
496 if evt.mask & inotify.IN_ISDIR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
497 self.scan(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
498 else:
8606
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
499 self.created(wpath)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
500
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
501 def process_delete(self, wpath, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
502 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
503 self.ui.note(_('%s event: deleted %s\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
504 (self.event_time(), wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
505
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
506 if evt.mask & inotify.IN_ISDIR:
8600
d46cdfcecaf1 inotify: proper fix for issue1542 (partially reverting 67e59a9886d5)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8599
diff changeset
507 tree = self.dir(self.tree, wpath).copy()
d46cdfcecaf1 inotify: proper fix for issue1542 (partially reverting 67e59a9886d5)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8599
diff changeset
508 for wfn, ignore in self.walk('?', tree):
d46cdfcecaf1 inotify: proper fix for issue1542 (partially reverting 67e59a9886d5)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8599
diff changeset
509 self.deletefile(join(wpath, wfn), '?')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
510 self.scan(wpath)
8600
d46cdfcecaf1 inotify: proper fix for issue1542 (partially reverting 67e59a9886d5)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8599
diff changeset
511 else:
8606
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
512 self.deleted(wpath)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
513
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
514 def process_modify(self, wpath, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
515 if self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
516 self.ui.note(_('%s event: modified %s\n') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
517 (self.event_time(), wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
518
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
519 if not (evt.mask & inotify.IN_ISDIR):
8606
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
520 self.modified(wpath)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
521
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
522 def process_unmount(self, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
523 self.ui.warn(_('filesystem containing %s was unmounted\n') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
524 evt.fullpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
525 sys.exit(0)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
526
8609
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
527 def handle_pollevents(self, events):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
528 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
529 self.ui.note(_('%s readable: %d bytes\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
530 (self.event_time(), self.threshold.readable()))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
531 if not self.threshold():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
532 if self.registered:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
533 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
534 self.ui.note(_('%s below threshold - unhooking\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
535 (self.event_time()))
8607
e17eba98c789 inotify: handle_event: do not use event and fd parameters.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8606
diff changeset
536 self.master.poll.unregister(self.fileno())
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
537 self.registered = False
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
538 self.timeout = 250
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
539 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
540 self.read_events()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
541
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
542 def read_events(self, bufsize=None):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
543 events = self.watcher.read(bufsize)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
544 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
545 self.ui.note(_('%s reading %d events\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
546 (self.event_time(), len(events)))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
547 for evt in events:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
548 wpath = self.wpath(evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
549 if evt.mask & inotify.IN_UNMOUNT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
550 self.process_unmount(wpath, evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
551 elif evt.mask & (inotify.IN_MODIFY | inotify.IN_ATTRIB):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
552 self.process_modify(wpath, evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
553 elif evt.mask & (inotify.IN_DELETE | inotify.IN_DELETE_SELF |
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
554 inotify.IN_MOVED_FROM):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
555 self.process_delete(wpath, evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
556 elif evt.mask & (inotify.IN_CREATE | inotify.IN_MOVED_TO):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
557 self.process_create(wpath, evt)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
558
8605
ed2d9bdbfad2 inotify: do not defer inotify events processing
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8604
diff changeset
559 self.lastevent.clear()
ed2d9bdbfad2 inotify: do not defer inotify events processing
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8604
diff changeset
560
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
561 def handle_timeout(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
562 if not self.registered:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
563 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
564 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
565 (self.event_time(), self.threshold.readable()))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
566 self.read_events(0)
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
567 self.master.poll.register(self, self.poll_events)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
568 self.registered = True
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
569
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
570 self.timeout = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
571
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
572 def shutdown(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
573 self.watcher.close()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
574
8555
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
575 def debug(self):
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
576 """
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
577 Returns a sorted list of relatives paths currently watched,
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
578 for debugging purposes.
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
579 """
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
580 return sorted(tuple[0][len(self.wprefix):] for tuple in self.watcher)
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
581
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
582 class server(pollable):
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
583 """
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
584 Listens for client queries on unix socket inotify.sock
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
585 """
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
586 def __init__(self, ui, repo, repowatcher, timeout):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
587 self.ui = ui
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
588 self.repo = repo
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
589 self.repowatcher = repowatcher
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
590 self.timeout = timeout
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
591 self.sock = socket.socket(socket.AF_UNIX)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
592 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
593 self.realsockpath = None
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
594 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
595 self.sock.bind(self.sockpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
596 except socket.error, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
597 if err[0] == errno.EADDRINUSE:
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
598 raise AlreadyStartedException(_('could not start server: %s')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
599 % err[1])
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
600 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
601 tempdir = tempfile.mkdtemp(prefix="hg-inotify-")
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
602 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
603 try:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
604 self.sock.bind(self.realsockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
605 os.symlink(self.realsockpath, self.sockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
606 except (OSError, socket.error), inst:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
607 try:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
608 os.unlink(self.realsockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
609 except:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
610 pass
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
611 os.rmdir(tempdir)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
612 if inst.errno == errno.EEXIST:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
613 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
614 % inst.strerror)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
615 raise
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
616 else:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
617 raise
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
618 self.sock.listen(5)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
619 self.fileno = self.sock.fileno
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
620
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
621 def handle_timeout(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
622 pass
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
623
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
624 def answer_stat_query(self, cs):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
625 names = cs.read().split('\0')
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
626
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
627 states = names.pop()
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 self.ui.note(_('answering query for %r\n') % states)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
630
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
631 if self.repowatcher.timeout:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
632 # 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
633 # rescan before responding, or we could give back a wrong
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
634 # answer.
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
635 self.repowatcher.handle_timeout()
6239
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 if not names:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
638 def genresult(states, tree):
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
639 for fn, state in self.repowatcher.walk(states, tree):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
640 yield fn
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
641 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
642 def genresult(states, tree):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
643 for fn in names:
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
644 l = self.repowatcher.lookup(fn, tree)
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
645 try:
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
646 if l in states:
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
647 yield fn
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
648 except TypeError:
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
649 for f, s in self.repowatcher.walk(states, l, fn):
7351
5ab0abf27dd9 Backed out changeset c5dbe86b0fee (issue1375)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7350
diff changeset
650 yield f
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
651
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
652 return ['\0'.join(r) for r in [
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
653 genresult('l', self.repowatcher.statustrees['l']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
654 genresult('m', self.repowatcher.statustrees['m']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
655 genresult('a', self.repowatcher.statustrees['a']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
656 genresult('r', self.repowatcher.statustrees['r']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
657 genresult('!', self.repowatcher.statustrees['!']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
658 '?' in states
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
659 and genresult('?', self.repowatcher.statustrees['?'])
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
660 or [],
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
661 [],
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
662 'c' in states and genresult('n', self.repowatcher.tree) or [],
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
663 ]]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
664
8555
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
665 def answer_dbug_query(self):
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
666 return ['\0'.join(self.repowatcher.debug())]
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
667
8609
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
668 def handle_pollevents(self, events):
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
669 for e in events:
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
670 self.handle_pollevent()
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
671
8608
228db070bfc4 inotify: rename handle_event to handle_pollevent to avoid confusion
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8607
diff changeset
672 def handle_pollevent(self):
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
673 sock, addr = self.sock.accept()
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
674
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
675 cs = common.recvcs(sock)
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
676 version = ord(cs.read(1))
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
677
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
678 if version != common.version:
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
679 self.ui.warn(_('received query from incompatible client '
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
680 'version %d\n') % version)
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
681 return
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
682
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
683 type = cs.read(4)
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
684
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
685 if type == 'STAT':
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
686 results = self.answer_stat_query(cs)
8555
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
687 elif type == 'DBUG':
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
688 results = self.answer_dbug_query()
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
689 else:
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
690 self.ui.warn(_('unrecognized query type: %s\n') % type)
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
691 return
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
692
6239
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 try:
8386
4aad982111b6 inotify: Abstract the layer format and sizes to a inotify.common dictionary
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8385
diff changeset
695 v = chr(common.version)
4aad982111b6 inotify: Abstract the layer format and sizes to a inotify.common dictionary
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8385
diff changeset
696
8553
e387ecd7a6ed inotify: change protocol so that different query types can be supported.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8386
diff changeset
697 sock.sendall(v + type + struct.pack(common.resphdrfmts[type],
e387ecd7a6ed inotify: change protocol so that different query types can be supported.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8386
diff changeset
698 *map(len, results)))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
699 sock.sendall(''.join(results))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
700 finally:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
701 sock.shutdown(socket.SHUT_WR)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
702 except socket.error, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
703 if err[0] != errno.EPIPE:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
704 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
705
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
706 def shutdown(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
707 self.sock.close()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
708 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
709 os.unlink(self.sockpath)
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
710 if self.realsockpath:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
711 os.unlink(self.realsockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
712 os.rmdir(os.path.dirname(self.realsockpath))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
713 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
714 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
715 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
716
8385
1536501ade62 inotify: Coding Style: name classes in lowercase.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8384
diff changeset
717 class master(object):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
718 def __init__(self, ui, repo, timeout=None):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
719 self.ui = ui
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
720 self.repo = repo
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
721 self.poll = select.poll()
8385
1536501ade62 inotify: Coding Style: name classes in lowercase.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8384
diff changeset
722 self.repowatcher = repowatcher(ui, repo, self)
1536501ade62 inotify: Coding Style: name classes in lowercase.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8384
diff changeset
723 self.server = server(ui, repo, self.repowatcher, timeout)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
724 self.table = {}
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
725 for obj in (self.repowatcher, self.server):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
726 fd = obj.fileno()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
727 self.table[fd] = obj
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
728 self.poll.register(fd, obj.poll_events)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
729
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
730 def register(self, fd, mask):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
731 self.poll.register(fd, mask)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
732
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
733 def shutdown(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
734 for obj in self.table.itervalues():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
735 obj.shutdown()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
736
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
737 def run(self):
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
738 self.repowatcher.setup()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
739 self.ui.note(_('finished setup\n'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
740 if os.getenv('TIME_STARTUP'):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
741 sys.exit(0)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
742 while True:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
743 timeout = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
744 timeobj = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
745 for obj in self.table.itervalues():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
746 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
747 timeout, timeobj = obj.timeout, obj
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
748 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
749 if self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
750 if timeout is None:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
751 self.ui.note(_('polling: no timeout\n'))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
752 else:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
753 self.ui.note(_('polling: %sms timeout\n') % timeout)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
754 events = self.poll.poll(timeout)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
755 except select.error, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
756 if err[0] == errno.EINTR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
757 continue
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
758 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
759 if events:
8609
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
760 by_fd = {}
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
761 for fd, event in events:
8609
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
762 by_fd.setdefault(fd, []).append(event)
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
763
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
764 for fd, events in by_fd.iteritems():
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
765 self.table[fd].handle_pollevents(events)
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
766
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
767 elif timeobj:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
768 timeobj.handle_timeout()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
769
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
770 def start(ui, repo):
7451
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
771 def closefds(ignore):
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
772 # (from python bug #1177468)
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
773 # close all inherited file descriptors
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
774 # 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
775 # 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
776 # 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
777 try:
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
778 os.urandom(4)
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
779 urandom_fd = getattr(os, '_urandomfd', None)
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
780 except AttributeError:
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
781 urandom_fd = None
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
782 ignore.append(urandom_fd)
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
783 for fd in range(3, 256):
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
784 if fd in ignore:
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
785 continue
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
786 try:
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
787 os.close(fd)
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
788 except OSError:
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
789 pass
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
790
8385
1536501ade62 inotify: Coding Style: name classes in lowercase.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8384
diff changeset
791 m = master(ui, repo)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
792 sys.stdout.flush()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
793 sys.stderr.flush()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
794
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
795 pid = os.fork()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
796 if pid:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
797 return pid
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
798
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
799 closefds([m.server.fileno(), m.repowatcher.fileno()])
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
800 os.setsid()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
801
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
802 fd = os.open('/dev/null', os.O_RDONLY)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
803 os.dup2(fd, 0)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
804 if fd > 0:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
805 os.close(fd)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
806
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
807 fd = os.open(ui.config('inotify', 'log', '/dev/null'),
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
808 os.O_RDWR | os.O_CREAT | os.O_TRUNC)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
809 os.dup2(fd, 1)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
810 os.dup2(fd, 2)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
811 if fd > 2:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
812 os.close(fd)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
813
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
814 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
815 m.run()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
816 finally:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
817 m.shutdown()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
818 os._exit(0)