Robert Brewer avatar Robert Brewer committed 13613ea

Backport of [2109] (Partial fix for #886 (Shutdown failures)).

Comments (0)

Files changed (1)

cherrypy/process/wspbus.py

     
     def exit(self):
         """Stop all services and prepare to exit the process."""
-        self.stop()
-        
-        self.state = states.EXITING
-        self.log('Bus EXITING')
-        self.publish('exit')
-        # This isn't strictly necessary, but it's better than seeing
-        # "Waiting for child threads to terminate..." and then nothing.
-        self.log('Bus EXITED')
+        try:
+            self.stop()
+            
+            self.state = states.EXITING
+            self.log('Bus EXITING')
+            self.publish('exit')
+            # This isn't strictly necessary, but it's better than seeing
+            # "Waiting for child threads to terminate..." and then nothing.
+            self.log('Bus EXITED')
+        except:
+            # This method is often called asynchronously (whether thread,
+            # signal handler, console handler, or atexit handler), so we
+            # can't just let exceptions propagate out unhandled.
+            # Assume it's been logged and just die.
+            os._exit(70) # EX_SOFTWARE
     
     def restart(self):
         """Restart the process (may close connections).
         self.publish('graceful')
     
     def block(self, interval=0.1):
-        """Wait for the EXITING state, KeyboardInterrupt or SystemExit."""
+        """Wait for the EXITING state, KeyboardInterrupt or SystemExit.
+        
+        This function is intended to be called only by the main thread.
+        After waiting for the EXITING state, it also waits for all threads
+        to terminate, and then calls os.execv if self.execv is True. This
+        design allows another thread to call bus.restart, yet have the main
+        thread perform the actual execv call (required on some platforms).
+        """
         try:
             self.wait(states.EXITING, interval=interval)
         except (KeyboardInterrupt, IOError):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.