inotify: refactor (un)register methods into pollable object
authorNicolas Dumazet <nicdumz.commits@gmail.com>
Thu, 21 May 2009 20:15:00 +0900
changeset 8792 3e23b1d20837
parent 8791 23730a475363
child 8793 9d0c521bce0e
inotify: refactor (un)register methods into pollable object repowatcher.master becomes unnecessary
hgext/inotify/server.py
--- a/hgext/inotify/server.py	Sat Jun 13 18:41:28 2009 +0200
+++ b/hgext/inotify/server.py	Thu May 21 20:15:00 2009 +0900
@@ -130,6 +130,9 @@
         * If no, call handle_timeout
     """
     poll_events = select.POLLIN
+    instances = {}
+    poll = select.poll()
+
     def fileno(self):
         raise NotImplementedError
 
@@ -142,6 +145,19 @@
     def shutdown(self):
         raise NotImplementedError
 
+    def register(self, timeout):
+        fd = self.fileno()
+
+        pollable.poll.register(fd, pollable.poll_events)
+        pollable.instances[fd] = self
+
+        self.registered = True
+        self.timeout = timeout
+
+    def unregister(self):
+        pollable.poll.unregister(self)
+        self.registered = False
+
 def eventaction(code):
     """
     Decorator to help handle events in repowatcher
@@ -178,19 +194,16 @@
         inotify.IN_UNMOUNT |
         0)
 
-    def __init__(self, ui, repo, master):
+    def __init__(self, ui, repo):
         self.ui = ui
         self.repo = repo
         self.wprefix = self.repo.wjoin('')
-        self.timeout = None
-        self.master = master
         try:
             self.watcher = watcher.watcher()
         except OSError, err:
             raise util.Abort(_('inotify service not available: %s') %
                              err.strerror)
         self.threshold = watcher.threshold(self.watcher)
-        self.registered = True
         self.fileno = self.watcher.fileno
 
         self.tree = {}
@@ -202,6 +215,8 @@
 
         self.lastevent = {}
 
+        self.register(timeout=None)
+
         self.ds_info = self.dirstate_info()
         self.handle_timeout()
         self.scan()
@@ -536,8 +551,7 @@
                 if self.ui.debugflag:
                     self.ui.note(_('%s below threshold - unhooking\n') %
                                  (self.event_time()))
-                self.master.poll.unregister(self.fileno())
-                self.registered = False
+                self.unregister()
                 self.timeout = 250
         else:
             self.read_events()
@@ -567,8 +581,7 @@
                 self.ui.note(_('%s hooking back up with %d bytes readable\n') %
                              (self.event_time(), self.threshold.readable()))
             self.read_events(0)
-            self.master.poll.register(self, self.poll_events)
-            self.registered = True
+            self.register(timeout=None)
 
         self.timeout = None
 
@@ -590,7 +603,6 @@
         self.ui = ui
         self.repo = repo
         self.repowatcher = repowatcher
-        self.timeout = timeout
         self.sock = socket.socket(socket.AF_UNIX)
         self.sockpath = self.repo.join('inotify.sock')
         self.realsockpath = None
@@ -620,6 +632,7 @@
                 raise
         self.sock.listen(5)
         self.fileno = self.sock.fileno
+        self.register(timeout=timeout)
 
     def handle_timeout(self):
         pass
@@ -721,20 +734,11 @@
     def __init__(self, ui, repo, timeout=None):
         self.ui = ui
         self.repo = repo
-        self.poll = select.poll()
-        self.repowatcher = repowatcher(ui, repo, self)
+        self.repowatcher = repowatcher(ui, repo)
         self.server = server(ui, repo, self.repowatcher, timeout)
-        self.table = {}
-        for obj in (self.repowatcher, self.server):
-            fd = obj.fileno()
-            self.table[fd] = obj
-            self.poll.register(fd, obj.poll_events)
-
-    def register(self, fd, mask):
-        self.poll.register(fd, mask)
 
     def shutdown(self):
-        for obj in self.table.itervalues():
+        for obj in pollable.instances.itervalues():
             obj.shutdown()
 
     def run(self):
@@ -745,7 +749,7 @@
         while True:
             timeout = None
             timeobj = None
-            for obj in self.table.itervalues():
+            for obj in pollable.instances.itervalues():
                 if obj.timeout is not None and (timeout is None or obj.timeout < timeout):
                     timeout, timeobj = obj.timeout, obj
             try:
@@ -754,7 +758,7 @@
                         self.ui.note(_('polling: no timeout\n'))
                     else:
                         self.ui.note(_('polling: %sms timeout\n') % timeout)
-                events = self.poll.poll(timeout)
+                events = pollable.poll.poll(timeout)
             except select.error, err:
                 if err[0] == errno.EINTR:
                     continue
@@ -765,7 +769,7 @@
                     by_fd.setdefault(fd, []).append(event)
 
                 for fd, events in by_fd.iteritems():
-                    self.table[fd].handle_pollevents(events)
+                    pollable.instances[fd].handle_pollevents(events)
 
             elif timeobj:
                 timeobj.handle_timeout()
@@ -799,7 +803,7 @@
     if pid:
         return pid
 
-    closefds([m.server.fileno(), m.repowatcher.fileno()])
+    closefds(pollable.instances.keys())
     os.setsid()
 
     fd = os.open('/dev/null', os.O_RDONLY)