Forráskód Böngészése

- Invoking the 'reload' supervisorctl command could trigger a bug in
supervisord which caused it to crash. See
http://www.plope.com/software/collector/253 . Thanks to William
Dode for a bug report.

Chris McDonough 17 éve
szülő
commit
a809d1a997
2 módosított fájl, 21 hozzáadás és 0 törlés
  1. 5 0
      CHANGES.txt
  2. 16 0
      src/supervisor/options.py

+ 5 - 0
CHANGES.txt

@@ -38,6 +38,11 @@ Next Release
     space-separated list of file globs that will be included in
     supervisor's configuration.  Contributed by Ian Bicking.
 
+  - Invoking the 'reload' supervisorctl command could trigger a bug in
+    supervisord which caused it to crash.  See
+    http://www.plope.com/software/collector/253 .  Thanks to William
+    Dode for a bug report.
+
 3.0a3
 
   - Supervisorctl now reports a better error message when the main

+ 16 - 0
src/supervisor/options.py

@@ -902,6 +902,22 @@ class ServerOptions(Options):
     def close_httpservers(self):
         for config, server in self.httpservers:
             server.close()
+            map = self.get_socket_map()
+            # server._map is a reference to the asyncore socket_map
+            for dispatcher in map.values():
+                # For unknown reasons, sometimes an http_channel
+                # dispatcher in the socket map related to servers
+                # remains open *during a reload*.  If one of these
+                # exists at this point, we need to close it by hand
+                # (thus removing it from the asyncore.socket_map).  If
+                # we don't do this, 'cleanup_fds' will cause its file
+                # descriptor to be closed, but it will still remain in
+                # the socket_map, and eventually its file descriptor
+                # will be passed to # select(), which will bomb.  See
+                # also http://www.plope.com/software/collector/253
+                dispatcher_server = getattr(dispatcher, 'server', None)
+                if dispatcher_server is server:
+                    dispatcher.close()
 
     def close_logger(self):
         self.logger.close()