[Zope-Checkins] CVS: Zope/lib/python/Signals - SignalHandler.py:1.2.6.1 Signals.py:1.2.4.11

Chris McDonough chrism@zope.com
Sun, 24 Nov 2002 18:48:20 -0500


Update of /cvs-repository/Zope/lib/python/Signals
In directory cvs.zope.org:/tmp/cvs-serv11728

Modified Files:
      Tag: chrism-install-branch
	Signals.py 
Added Files:
      Tag: chrism-install-branch
	SignalHandler.py 
Log Message:
Merge with HEAD.


=== Added File Zope/lib/python/Signals/SignalHandler.py ===
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################

"""Signal handling dispatcher."""

__version__='$Revision: 1.2.6.1 $'[11:-2]

import sys, os
import signal, zLOG

class SignalHandler:

    def __init__(self):
        self.registry = {}

    def registerHandler(self, signum, handler):
        """Register a handler function that will be called when the process
           recieves the signal signum. The signum argument must be a signal
           constant such as SIGTERM. The handler argument must be a function
           or method that takes no arguments. Note that handlers will not
           be called on non-posix platforms."""
        if os.name != 'posix':
            return
        items = self.registry.get(signum)
        if items is None:
            items = self.registry[signum] = []
            signal.signal(signum, self.signalHandler)
            signame = get_signal_name(signum)
            zLOG.LOG('Z2', zLOG.BLATHER, "Installed sighandler for %s" % (
                      signame
                      ))
        items.insert(0, handler)

    def getRegisteredSignals(self):
        """Return a list of the signals that have handlers registered. This
           is used to pass the signals through to the ZDaemon code."""
        return self.registry.keys()

    def signalHandler(self, signum, frame):
        """Meta signal handler that dispatches to registered handlers."""
        signame = get_signal_name(signum)
        zLOG.LOG('Z2', zLOG.INFO , "Caught signal %s" % signame)

        for handler in self.registry.get(signum, []):
            # Never let a bad handler prevent the standard signal
            # handlers from running.
            try: handler()
            except SystemExit:
                # if we trap SystemExit, we can't restart
                raise
            except:
                zLOG.LOG('Z2', zLOG.WARNING,
                         'A handler for %s failed!' % signame,
                         error=sys.exc_info())

_signals = None

def get_signal_name(n):
    """Return the symbolic name for signal n.

    Returns 'unknown' if there is no SIG name bound to n in the signal
    module.
    """
    global _signals
    if _signals is None:
        _signals = {}
        for k, v in signal.__dict__.items():
            startswith = getattr(k, 'startswith', None)
            if startswith is None:
                continue
            if startswith('SIG') and not startswith('SIG_'):
                _signals[v] = k
    return _signals.get(n, 'unknown')

# The SignalHandler is actually a singleton.
SignalHandler = SignalHandler()


=== Zope/lib/python/Signals/Signals.py 1.2.4.10 => 1.2.4.11 ===
--- Zope/lib/python/Signals/Signals.py:1.2.4.10	Sun Nov  3 18:31:28 2002
+++ Zope/lib/python/Signals/Signals.py	Sun Nov 24 18:48:19 2002
@@ -17,23 +17,29 @@
 """
 __version__='$Revision$'[11:-2]
 
-from zdaemon.SignalHandler import SignalHandler
+from SignalHandler import SignalHandler
 import zLOG
 import sys
+import Lifetime
+
+def shutdownFastHandler():
+    """Shutdown cleanly on SIGTERM. This is registered first,
+       so it should be called after all other handlers."""
+    zLOG.LOG('Z2', zLOG.INFO , "Shutting down fast")
+    Lifetime.shutdown(0,fast=1)
+
 
 def shutdownHandler():
-    """Shutdown cleanly on SIGTERM, SIGINT. This is registered first,
+    """Shutdown cleanly on SIGINT. This is registered first,
        so it should be called after all other handlers."""
-    closeall()
     zLOG.LOG('Z2', zLOG.INFO , "Shutting down")
     sys.exit(0)
 
 def restartHandler():
     """Restart cleanly on SIGHUP. This is registered first, so it
        should be called after all other SIGHUP handlers."""
-    closeall()
     zLOG.LOG('Z2', zLOG.INFO , "Restarting")
-    sys.exit(1)
+    Lifetime.shutdown(1)
 
 def logfileReopenHandler():
     """Reopen log files on SIGUSR2. This is registered first, so it
@@ -65,19 +71,9 @@
                  'Call to pack failed!', error=sys.exc_info())
         
 
-def closeall():
-    """Helper method to close database connections.  This also used
-    to close network connections, but that hosed ZEO clients in some
-    instances, so we don't do that anymore"""
-    import Globals
-
-    zLOG.LOG('Z2', zLOG.INFO, "Closing all open ZODB databases")
-    for db in Globals.opened:
-        db.close()
-
 def registerZopeSignals():
     import signal
-    SignalHandler.registerHandler(signal.SIGTERM, shutdownHandler)
+    SignalHandler.registerHandler(signal.SIGTERM, shutdownFastHandler)
     SignalHandler.registerHandler(signal.SIGINT, shutdownHandler)
     SignalHandler.registerHandler(signal.SIGHUP, restartHandler)
     SignalHandler.registerHandler(signal.SIGUSR2, logfileReopenHandler)