annotate hgext/inotify/linuxserver.py @ 10090:a3ad96ead8f0

inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate stat() is not reliable when several events happen quickly. Which means that if two hg actions occur in the same second, stat() result will not reflect the second change. And only _one_ invalidate() call was done. Also ignore the events that occur when wlock is held, since wlock release will trigger a full rescan anyway. Fixes 17 run-tests.py --inotify tests.
author Nicolas Dumazet <nicdumz.commits@gmail.com>
date Fri, 11 Dec 2009 15:58:09 +0900
parents 8fab31727037
children 0ce645cc3f20
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
1 # linuxserver.py - inotify status server for linux
6239
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 _
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
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
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
12 import server
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
13 import errno, os, select, stat, sys, time
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
14
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
15 try:
6994
bf727bab38b9 Use relative imports in inotify.server.
Brendan Cully <brendan@kublai.com>
parents: 6287
diff changeset
16 import linux as inotify
bf727bab38b9 Use relative imports in inotify.server.
Brendan Cully <brendan@kublai.com>
parents: 6287
diff changeset
17 from linux import watcher
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
18 except ImportError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
19 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
20
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
21 def walkrepodirs(dirstate, absroot):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
22 '''Iterate over all subdirectories of this repo.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
23 Exclude the .hg directory, any nested repos, and ignored dirs.'''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
24 def walkit(dirname, top):
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
25 fullpath = server.join(absroot, dirname)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
26 try:
8321
ec985dcfd7da inotify: inotify.server.walkrepodirs() simplify
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8320
diff changeset
27 for name, kind in osutil.listdir(fullpath):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
28 if kind == stat.S_IFDIR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
29 if name == '.hg':
8323
589a82fb02a2 inotify: inotify.server.walk*() cleanup
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8322
diff changeset
30 if not top:
589a82fb02a2 inotify: inotify.server.walk*() cleanup
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8322
diff changeset
31 return
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
32 else:
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
33 d = server.join(dirname, name)
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
34 if dirstate._ignore(d):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
35 continue
8322
3c6c21eb3416 inotify: inotify.server.walkrepodirs() simplify walking
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8321
diff changeset
36 for subdir in walkit(d, False):
3c6c21eb3416 inotify: inotify.server.walkrepodirs() simplify walking
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8321
diff changeset
37 yield subdir
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
38 except OSError, err:
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
39 if err.errno not in server.walk_ignored_errors:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
40 raise
8324
b923d599c309 inotify: inotify.server.walk*() remove unnecessary var
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8323
diff changeset
41 yield fullpath
8322
3c6c21eb3416 inotify: inotify.server.walkrepodirs() simplify walking
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8321
diff changeset
42
3c6c21eb3416 inotify: inotify.server.walkrepodirs() simplify walking
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8321
diff changeset
43 return walkit('', True)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
44
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
45 def _explain_watch_limit(ui, dirstate, rootabs):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
46 path = '/proc/sys/fs/inotify/max_user_watches'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
47 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
48 limit = int(file(path).read())
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
49 except IOError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
51 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 raise util.Abort(_('this system does not seem to '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
53 'support inotify'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
54 ui.warn(_('*** the current per-user limit on the number '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
55 'of inotify watches is %s\n') % limit)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
56 ui.warn(_('*** this limit is too low to watch every '
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
57 'directory in this repository\n'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
58 ui.warn(_('*** counting directories: '))
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
59 ndirs = len(list(walkrepodirs(dirstate, rootabs)))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
60 ui.warn(_('found %d\n') % ndirs)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
61 newlimit = min(limit, 1024)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
62 while newlimit < ((limit + ndirs) * 1.1):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
63 newlimit *= 2
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
64 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
65 (limit, newlimit))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
66 ui.warn(_('*** echo %d > %s\n') % (newlimit, path))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
67 raise util.Abort(_('cannot watch %s until inotify watch limit is raised')
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
68 % rootabs)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
69
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
70 class pollable(object):
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
71 """
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
72 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
73 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
74 object.
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
75 Usage:
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
76 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
77 * 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
78 * 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
79 """
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
80 poll_events = select.POLLIN
8792
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
81 instances = {}
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
82 poll = select.poll()
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
83
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
84 def fileno(self):
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
85 raise NotImplementedError
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
86
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
87 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
88 raise NotImplementedError
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
89
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
90 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
91 raise NotImplementedError
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
92
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
93 def shutdown(self):
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
94 raise NotImplementedError
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
95
8792
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
96 def register(self, timeout):
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
97 fd = self.fileno()
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
98
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
99 pollable.poll.register(fd, pollable.poll_events)
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
100 pollable.instances[fd] = self
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
101
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
102 self.registered = True
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
103 self.timeout = timeout
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
104
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
105 def unregister(self):
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
106 pollable.poll.unregister(self)
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
107 self.registered = False
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
108
8793
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
109 @classmethod
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
110 def run(cls):
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
111 while True:
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
112 timeout = None
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
113 timeobj = None
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
114 for obj in cls.instances.itervalues():
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
115 if obj.timeout is not None and (timeout is None or obj.timeout < timeout):
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
116 timeout, timeobj = obj.timeout, obj
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
117 try:
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
118 events = cls.poll.poll(timeout)
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
119 except select.error, err:
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
120 if err[0] == errno.EINTR:
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
121 continue
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
122 raise
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
123 if events:
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
124 by_fd = {}
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
125 for fd, event in events:
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
126 by_fd.setdefault(fd, []).append(event)
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
127
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
128 for fd, events in by_fd.iteritems():
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
129 cls.instances[fd].handle_pollevents(events)
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
130
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
131 elif timeobj:
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
132 timeobj.handle_timeout()
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
133
8791
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
134 def eventaction(code):
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
135 """
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
136 Decorator to help handle events in repowatcher
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
137 """
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
138 def decorator(f):
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
139 def wrapper(self, wpath):
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
140 if code == 'm' and wpath in self.lastevent and \
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
141 self.lastevent[wpath] in 'cm':
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
142 return
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
143 self.lastevent[wpath] = code
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
144 self.timeout = 250
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
145
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
146 f(self, wpath)
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
147
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
148 wrapper.func_name = f.func_name
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
149 return wrapper
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
150 return decorator
23730a475363 inotify.server: the decorator eventaction() shouldn't be a method of repowatcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8787
diff changeset
151
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
152 class repowatcher(server.repowatcher, pollable):
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
153 """
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
154 Watches inotify events
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
155 """
8383
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
156 mask = (
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_ATTRIB |
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_CREATE |
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_DELETE |
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_DELETE_SELF |
dcfdcb51ac5c inotify: make mask a class variable since it's instance-independant
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8382
diff changeset
161 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
162 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
163 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
164 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
165 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
166 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
167 0)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
168
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
169 def __init__(self, ui, dirstate, root):
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
170 server.repowatcher.__init__(self, ui, dirstate, root)
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
171
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
172 self.lastevent = {}
10090
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
173 self.dirty = False
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
174 try:
8385
1536501ade62 inotify: Coding Style: name classes in lowercase.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8384
diff changeset
175 self.watcher = watcher.watcher()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
176 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
177 raise util.Abort(_('inotify service not available: %s') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
178 err.strerror)
8385
1536501ade62 inotify: Coding Style: name classes in lowercase.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8384
diff changeset
179 self.threshold = watcher.threshold(self.watcher)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
180 self.fileno = self.watcher.fileno
8792
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
181 self.register(timeout=None)
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
182
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
183 self.handle_timeout()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
184 self.scan()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
185
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
186 def event_time(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
187 last = self.last_event
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
188 now = time.time()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
189 self.last_event = now
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 if last is None:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
192 return 'start'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
193 delta = now - last
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
194 if delta < 5:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
195 return '+%.3f' % delta
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
196 if delta < 50:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
197 return '+%.2f' % delta
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
198 return '+%.1f' % delta
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
199
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
200 def add_watch(self, path, mask):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
201 if not path:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
202 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
203 if self.watcher.path(path) is None:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
204 if self.ui.debugflag:
9349
56fb15ad8fb1 inotify: server: use wprefix everywhere, introduce prefixlen
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9348
diff changeset
205 self.ui.note(_('watching %r\n') % path[self.prefixlen:])
6239
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 self.watcher.add(path, mask)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
208 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
209 if err.errno in (errno.ENOENT, errno.ENOTDIR):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
210 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
211 if err.errno != errno.ENOSPC:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
212 raise
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
213 _explain_watch_limit(self.ui, self.dirstate, self.wprefix)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
214
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
215 def setup(self):
9349
56fb15ad8fb1 inotify: server: use wprefix everywhere, introduce prefixlen
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9348
diff changeset
216 self.ui.note(_('watching directories under %r\n') % self.wprefix)
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
217 self.add_watch(self.wprefix + '.hg', inotify.IN_DELETE)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
218
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
219 def scan(self, topdir=''):
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
220 ds = self.dirstate._map.copy()
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
221 self.add_watch(server.join(self.wprefix, topdir), self.mask)
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
222 for root, dirs, files in server.walk(self.dirstate, self.wprefix,
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
223 topdir):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
224 for d in dirs:
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
225 self.add_watch(server.join(root, d), self.mask)
9349
56fb15ad8fb1 inotify: server: use wprefix everywhere, introduce prefixlen
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9348
diff changeset
226 wroot = root[self.prefixlen:]
8334
0695288e8c37 inotify: inotify.server.walk() filetype is never used, do not yield it
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8325
diff changeset
227 for fn in files:
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
228 wfn = server.join(wroot, fn)
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
229 self.updatefile(wfn, self.getstat(wfn))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
230 ds.pop(wfn, None)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
231 wtopdir = topdir
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
232 if wtopdir and wtopdir[-1] != '/':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
233 wtopdir += '/'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
234 for wfn, state in ds.iteritems():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
235 if not wfn.startswith(wtopdir):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
236 continue
7302
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
237 try:
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
238 st = self.stat(wfn)
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
239 except OSError:
972737252d05 inotify: server raising an error when removing a file (issue1371)
Gerard Korsten <soonkia77@gmail.com>
parents: 7280
diff changeset
240 status = state[0]
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
241 self.deletefile(wfn, status)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
242 else:
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
243 self.updatefile(wfn, st)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
244 self.check_deleted('!')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
245 self.check_deleted('r')
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
246
8606
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
247 @eventaction('c')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
248 def created(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
249 if wpath == '.hgignore':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
250 self.update_hgignore()
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 st = self.stat(wpath)
10089
8fab31727037 inotify: follow new files if they are regular or a symlink.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9933
diff changeset
253 if stat.S_ISREG(st[0]) or stat.S_ISLNK(st[0]):
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
254 self.updatefile(wpath, st)
7280
810ca383da9c remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7220
diff changeset
255 except OSError:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
256 pass
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
257
8606
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
258 @eventaction('m')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
259 def modified(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
260 if wpath == '.hgignore':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
261 self.update_hgignore()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
262 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
263 st = self.stat(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
264 if stat.S_ISREG(st[0]):
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
265 if self.dirstate[wpath] in 'lmn':
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
266 self.updatefile(wpath, st)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
267 except OSError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
268 pass
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
269
8606
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
270 @eventaction('d')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
271 def deleted(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
272 if wpath == '.hgignore':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
273 self.update_hgignore()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
274 elif wpath.startswith('.hg/'):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
275 return
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
276
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
277 self.deletefile(wpath, self.dirstate[wpath])
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
278
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
279 def process_create(self, wpath, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
280 if self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
281 self.ui.note(_('%s event: created %s\n') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
282 (self.event_time(), wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
283
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
284 if evt.mask & inotify.IN_ISDIR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
285 self.scan(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
286 else:
8606
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
287 self.created(wpath)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
288
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
289 def process_delete(self, wpath, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
290 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
291 self.ui.note(_('%s event: deleted %s\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
292 (self.event_time(), wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
293
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
294 if evt.mask & inotify.IN_ISDIR:
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
295 tree = self.tree.dir(wpath)
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
296 todelete = [wfn for wfn, ignore in tree.walk('?')]
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
297 for fn in todelete:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
298 self.deletefile(fn, '?')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
299 self.scan(wpath)
8600
d46cdfcecaf1 inotify: proper fix for issue1542 (partially reverting 67e59a9886d5)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8599
diff changeset
300 else:
8606
1c5752dabf76 inotify: use a decorator instead of dispatching calls
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8605
diff changeset
301 self.deleted(wpath)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
302
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
303 def process_modify(self, wpath, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
304 if self.ui.debugflag:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
305 self.ui.note(_('%s event: modified %s\n') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
306 (self.event_time(), wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
307
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
308 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
309 self.modified(wpath)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
310
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
311 def process_unmount(self, evt):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
312 self.ui.warn(_('filesystem containing %s was unmounted\n') %
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
313 evt.fullpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
314 sys.exit(0)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
315
8609
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
316 def handle_pollevents(self, events):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
317 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
318 self.ui.note(_('%s readable: %d bytes\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
319 (self.event_time(), self.threshold.readable()))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
320 if not self.threshold():
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
321 if self.registered:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
322 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
323 self.ui.note(_('%s below threshold - unhooking\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
324 (self.event_time()))
8792
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
325 self.unregister()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
326 self.timeout = 250
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
327 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
328 self.read_events()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
329
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
330 def read_events(self, bufsize=None):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
331 events = self.watcher.read(bufsize)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
332 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
333 self.ui.note(_('%s reading %d events\n') %
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
334 (self.event_time(), len(events)))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
335 for evt in events:
8953
e1d119f450f0 inotify: server: remove wpath method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8952
diff changeset
336 assert evt.fullpath.startswith(self.wprefix)
9349
56fb15ad8fb1 inotify: server: use wprefix everywhere, introduce prefixlen
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9348
diff changeset
337 wpath = evt.fullpath[self.prefixlen:]
8953
e1d119f450f0 inotify: server: remove wpath method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8952
diff changeset
338
9117
a87bc6e2a907 inotify: server: explicitely ignore events in subdirs of .hg/ (issue1735)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9116
diff changeset
339 # paths have been normalized, wpath never ends with a '/'
a87bc6e2a907 inotify: server: explicitely ignore events in subdirs of .hg/ (issue1735)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9116
diff changeset
340
a87bc6e2a907 inotify: server: explicitely ignore events in subdirs of .hg/ (issue1735)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9116
diff changeset
341 if wpath.startswith('.hg/') and evt.mask & inotify.IN_ISDIR:
a87bc6e2a907 inotify: server: explicitely ignore events in subdirs of .hg/ (issue1735)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9116
diff changeset
342 # ignore subdirectories of .hg/ (merge, patches...)
a87bc6e2a907 inotify: server: explicitely ignore events in subdirs of .hg/ (issue1735)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9116
diff changeset
343 continue
10090
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
344 if wpath == ".hg/wlock":
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
345 if evt.mask & inotify.IN_DELETE:
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
346 self.dirstate.invalidate()
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
347 self.dirty = False
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
348 self.scan()
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
349 elif evt.mask & inotify.IN_CREATE:
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
350 self.dirty = True
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
351 else:
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
352 if self.dirty:
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
353 continue
9117
a87bc6e2a907 inotify: server: explicitely ignore events in subdirs of .hg/ (issue1735)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9116
diff changeset
354
10090
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
355 if evt.mask & inotify.IN_UNMOUNT:
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
356 self.process_unmount(wpath, evt)
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
357 elif evt.mask & (inotify.IN_MODIFY | inotify.IN_ATTRIB):
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
358 self.process_modify(wpath, evt)
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
359 elif evt.mask & (inotify.IN_DELETE | inotify.IN_DELETE_SELF |
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
360 inotify.IN_MOVED_FROM):
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
361 self.process_delete(wpath, evt)
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
362 elif evt.mask & (inotify.IN_CREATE | inotify.IN_MOVED_TO):
a3ad96ead8f0 inotify: do not rely on stat(.hg/dirstate) to invalidate our dirstate
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10089
diff changeset
363 self.process_create(wpath, evt)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
364
8605
ed2d9bdbfad2 inotify: do not defer inotify events processing
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8604
diff changeset
365 self.lastevent.clear()
ed2d9bdbfad2 inotify: do not defer inotify events processing
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8604
diff changeset
366
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
367 def handle_timeout(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
368 if not self.registered:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
369 if self.ui.debugflag:
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
370 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
371 (self.event_time(), self.threshold.readable()))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
372 self.read_events(0)
8792
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
373 self.register(timeout=None)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
374
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
375 self.timeout = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
376
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
377 def shutdown(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
378 self.watcher.close()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
379
8555
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
380 def debug(self):
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
381 """
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
382 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
383 for debugging purposes.
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
384 """
9349
56fb15ad8fb1 inotify: server: use wprefix everywhere, introduce prefixlen
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9348
diff changeset
385 return sorted(tuple[0][self.prefixlen:] for tuple in self.watcher)
8555
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
386
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
387 class socketlistener(server.socketlistener, pollable):
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
388 """
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
389 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
390 """
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
391 def __init__(self, ui, root, repowatcher, timeout):
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
392 server.socketlistener.__init__(self, ui, root, repowatcher, timeout)
8792
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
393 self.register(timeout=timeout)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
394
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
395 def handle_timeout(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
396 pass
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
397
8609
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
398 def handle_pollevents(self, events):
aeaa0bd9dc24 inotify: process all inotify events in one batch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8608
diff changeset
399 for e in events:
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
400 self.accept_connection()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
401
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
402 def shutdown(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
403 self.sock.close()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
404 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
405 os.unlink(self.sockpath)
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
406 if self.realsockpath:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
407 os.unlink(self.realsockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
408 os.rmdir(os.path.dirname(self.realsockpath))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
409 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
410 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
411 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
412
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
413 def answer_stat_query(self, cs):
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
414 if self.repowatcher.timeout:
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
415 # We got a query while a rescan is pending. Make sure we
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
416 # rescan before responding, or we could give back a wrong
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
417 # answer.
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
418 self.repowatcher.handle_timeout()
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
419 return server.socketlistener.answer_stat_query(self, cs)
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
420
8385
1536501ade62 inotify: Coding Style: name classes in lowercase.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8384
diff changeset
421 class master(object):
9351
206f7f4c5c2a inotify: client: no repo use
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9350
diff changeset
422 def __init__(self, ui, dirstate, root, timeout=None):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
423 self.ui = ui
9351
206f7f4c5c2a inotify: client: no repo use
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9350
diff changeset
424 self.repowatcher = repowatcher(ui, dirstate, root)
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
425 self.socketlistener = socketlistener(ui, root, self.repowatcher,
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
426 timeout)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
427
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
428 def shutdown(self):
8792
3e23b1d20837 inotify: refactor (un)register methods into pollable object
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8791
diff changeset
429 for obj in pollable.instances.itervalues():
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
430 obj.shutdown()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
431
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
432 def run(self):
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
433 self.repowatcher.setup()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
434 self.ui.note(_('finished setup\n'))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
435 if os.getenv('TIME_STARTUP'):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
436 sys.exit(0)
8793
9d0c521bce0e inotify: put the "while True: poll()" loop in pollable class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8792
diff changeset
437 pollable.run()