diff --git a/lib/daemon.py b/lib/daemon.py
index b5fcb5d7850cf7593f57432028fb469fad6a93bd..6799395d99d7500c71025cc7114d33ee17c02491 100644
--- a/lib/daemon.py
+++ b/lib/daemon.py
@@ -44,71 +44,52 @@ class Mainloop(object):
     self._signal_wait = []
     self._poller = select.poll()
 
-  def Run(self, handle_sigchld=True, handle_sigterm=True, stop_on_empty=False):
+  @utils.SignalHandled([signal.SIGCHLD])
+  @utils.SignalHandled([signal.SIGTERM])
+  def Run(self, stop_on_empty=False, signal_handlers=None):
     """Runs the mainloop.
 
-    @type handle_sigchld: bool
-    @param handle_sigchld: Whether to install handler for SIGCHLD
-    @type handle_sigterm: bool
-    @param handle_sigterm: Whether to install handler for SIGTERM
     @type stop_on_empty: bool
     @param stop_on_empty: Whether to stop mainloop once all I/O waiters
                           unregistered
+    @type signal_handlers: dict
+    @param signal_handlers: signal->L{utils.SignalHandler} passed by decorator
 
     """
-    # Setup signal handlers
-    if handle_sigchld:
-      sigchld_handler = utils.SignalHandler([signal.SIGCHLD])
-    else:
-      sigchld_handler = None
-    try:
-      if handle_sigterm:
-        sigterm_handler = utils.SignalHandler([signal.SIGTERM])
-      else:
-        sigterm_handler = None
-
+    assert isinstance(signal_handlers, dict) and \
+           len(signal_handlers) > 0, \
+           "Broken SignalHandled decorator"
+    running = True
+    # Start actual main loop
+    while running:
+      # Stop if nothing is listening anymore
+      if stop_on_empty and not (self._io_wait):
+        break
+
+      # Wait for I/O events
       try:
-        running = True
-
-        # Start actual main loop
-        while running:
-          # Stop if nothing is listening anymore
-          if stop_on_empty and not (self._io_wait):
-            break
-
-          # Wait for I/O events
-          try:
-            io_events = self._poller.poll(None)
-          except select.error, err:
-            # EINTR can happen when signals are sent
-            if err.args and err.args[0] in (errno.EINTR,):
-              io_events = None
-            else:
-              raise
-
-          if io_events:
-            # Check for I/O events
-            for (evfd, evcond) in io_events:
-              owner = self._io_wait.get(evfd, None)
-              if owner:
-                owner.OnIO(evfd, evcond)
-
-          # Check whether signal was raised
-          if sigchld_handler and sigchld_handler.called:
-            self._CallSignalWaiters(signal.SIGCHLD)
-            sigchld_handler.Clear()
-
-          if sigterm_handler and sigterm_handler.called:
-            self._CallSignalWaiters(signal.SIGTERM)
-            running = False
-            sigterm_handler.Clear()
-      finally:
-        # Restore signal handlers
-        if sigterm_handler:
-          sigterm_handler.Reset()
-    finally:
-      if sigchld_handler:
-        sigchld_handler.Reset()
+        io_events = self._poller.poll(None)
+      except select.error, err:
+        # EINTR can happen when signals are sent
+        if err.args and err.args[0] in (errno.EINTR,):
+          io_events = None
+        else:
+          raise
+
+      if io_events:
+        # Check for I/O events
+        for (evfd, evcond) in io_events:
+          owner = self._io_wait.get(evfd, None)
+          if owner:
+            owner.OnIO(evfd, evcond)
+
+      # Check whether a signal was raised
+      for sig in signal_handlers:
+        handler = signal_handlers[sig]
+        if handler.called:
+          self._CallSignalWaiters(sig)
+          running = (sig != signal.SIGTERM)
+          handler.Clear()
 
   def _CallSignalWaiters(self, signum):
     """Calls all signal waiters for a certain signal.