Skip to content

Commit

Permalink
NonDaemonicSpawnProcess join, SIGINT if exiting
Browse files Browse the repository at this point in the history
Fix #1497
  • Loading branch information
albertz committed Jan 18, 2024
1 parent 5409798 commit 0d0c01d
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions returnn/util/multi_proc_non_daemonic_spawn.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

# noinspection PyProtectedMember
from multiprocessing.context import BaseContext, SpawnProcess
from multiprocessing.util import is_exiting


class NonDaemonicSpawnProcess(SpawnProcess):
Expand Down Expand Up @@ -63,6 +64,22 @@ def kill(self):

def join(self, timeout=None):
"""join"""
if is_exiting():
# Process._bootstrap (the subproc main logic) will do an early call to
# multiprocessing.util._exit_function, which terminates all daemon procs,
# and then joins all procs (daemon or non-daemon).
# As we are all non-daemonic here, it means it will call join()
# without having send SIGINT, SIGTERM, SIGKILL or anything to the proc
# -- so this will just hang.
# is_exiting() will be True exactly if this _exit_function was called.
# If the proc is still alive, send SIGINT now,
# just like our atexit handler would do.
# However, our atexit handler will only run at some later point,
# but then it is too late, as we would hang here now in the join().
try:
os.kill(self.ident, signal.SIGINT)
except ProcessLookupError:
pass
super().join(timeout=timeout)
self._close_cleanup()

Expand Down

0 comments on commit 0d0c01d

Please sign in to comment.