Commits

Anonymous committed ca15390

Fixing the bug exposed by the unit test I just committed in : http://cherrypy.org/changeset/1815 . The fix is to catch SystemExit errors and if we have a pending exception cause by earlier errors, we ensure that the exit code is not zero. Additionally due to some better understandings of what fork does, we move fork further back in the startup process. However, fork has issues when threads are already open, so we shuffle around the default priorities of various plugins to ensure all threads are started after Daemonization.

Comments (0)

Files changed (2)

cherrypy/restsrv/plugins.py

                 old_umask = os.umask(umask)
                 self.bus.log('umask old: %03o, new: %03o' %
                                 (old_umask, umask))
-    start.priority = 70
+    start.priority = 75
 
 
 class Daemonizer(SimplePlugin):
         self.stderr = stderr
     
     def start(self):
+        # forking has issues with threads:
+        # http://www.opengroup.org/onlinepubs/000095399/functions/fork.html
+        # " ... The general problem with making fork() work in a multi-threaded world
+        #  is what to do with all of the threads. ... "
+        # So we check for active threads:
+        if threading.activeCount() != 1:
+            self.bus.log('There are more than one active threads. Daemonizing now may cause strange failures.')
+            self.bus.log(str(threading.enumerate()))
+
         # See http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
         # (or http://www.faqs.org/faqs/unix-faq/programmer/faq/ section 1.7)
         # and http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012
         os.dup2(se.fileno(), sys.stderr.fileno())
         
         self.bus.log('Daemonized to PID: %s' % os.getpid())
-    start.priority = 10
+    start.priority = 65
 
 
 class PIDFile(SimplePlugin):
             self.thread.setName(threadname)
             self.thread.start()
             self.bus.log("Started thread %r." % threadname)
+    start.priority = 70
     
     def stop(self):
         """Stop our callback's perpetual timer thread."""
         """Start our own perpetual timer thread for self.run."""
         self.mtimes = {}
         Monitor.start(self)
+    start.priority = 70 
     
     def run(self):
         """Reload the process if registered files have been modified."""

cherrypy/restsrv/wspbus.py

         for priority, listener in items:
             try:
                 output.append(listener(*args, **kwargs))
-            except (KeyboardInterrupt, SystemExit):
+            except KeyboardInterrupt:
                 raise
+            except SystemExit, e:
+                # If we have previous errors ensure the exit code is non-zero
+                if exc and e.code == 0:
+                    e.code = 1
+                raise 
             except:
                 self.log("Error in %r listener %r" % (channel, listener),
                          traceback=True)