Make signal handling order predictable
Due to the unordered nature of sets, it is possible for signal
handlers like _gracefull_shutdown() to run first and clear the
_signal_handlers before other registered handlers have run.
This patch converts _signal_handlers from a set to a list and
then runs the handlers LIFO similar to how atexit functions are
run. Given that the handlers added in service.py are added after
clearing the signal_handlers, they are guaranteed to be the first
in the list and the last run.
Change-Id: Ief3ab2f56fa3d805296709e12e5f7a71560f7b6e
Closes-Bug: #2057809
Related-Bug: #2056366
Signed-off-by: Terry Wilson <twilson@redhat.com>
(cherry picked from commit d026081ca4
)
This commit is contained in:
parent
9ae4ac6519
commit
028809f769
@ -142,7 +142,7 @@ class SignalHandler(metaclass=Singleton):
|
||||
self.signals_to_name = dict(
|
||||
(sigval, name)
|
||||
for (name, sigval) in self._signals_by_name.items())
|
||||
self._signal_handlers = collections.defaultdict(set)
|
||||
self._signal_handlers = collections.defaultdict(list)
|
||||
self.clear()
|
||||
|
||||
def clear(self):
|
||||
@ -158,7 +158,7 @@ class SignalHandler(metaclass=Singleton):
|
||||
if not self.is_signal_supported(sig):
|
||||
return
|
||||
signo = self._signals_by_name[sig]
|
||||
self._signal_handlers[signo].add(handler)
|
||||
self._signal_handlers[signo].append(handler)
|
||||
signal.signal(signo, self._handle_signal)
|
||||
|
||||
def _handle_signal(self, signo, frame):
|
||||
@ -237,7 +237,7 @@ class SignalHandler(metaclass=Singleton):
|
||||
self.__hub_module_file = sys.modules[hub.__module__].__file__
|
||||
|
||||
def _handle_signal_cb(self, signo, frame):
|
||||
for handler in self._signal_handlers[signo]:
|
||||
for handler in reversed(self._signal_handlers[signo]):
|
||||
handler(signo, frame)
|
||||
|
||||
def is_signal_supported(self, sig_name):
|
||||
|
Loading…
Reference in New Issue
Block a user