From 31ec59790381c60af3074efd3d1c7201e0e22b06 Mon Sep 17 00:00:00 2001 From: Min RK Date: Fri, 7 May 2021 14:58:11 +0200 Subject: [PATCH] stop control thread before closing sockets on it (#659) closing sockets in-use by another thread is a recipe for SIGABRT skip `close(all_fds=True)` in favor of explicit cleanup of sockets --- ipykernel/control.py | 15 ++++++++++++--- ipykernel/kernelapp.py | 6 +++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ipykernel/control.py b/ipykernel/control.py index 7ac56b7f9..4ba21dff5 100644 --- a/ipykernel/control.py +++ b/ipykernel/control.py @@ -15,7 +15,16 @@ def __init__(self, **kwargs): self.pydev_do_not_trace = True self.is_pydev_daemon_thread = True - def run(self): + def run(self): self.io_loop.make_current() - self.io_loop.start() - self.io_loop.close(all_fds=True) + try: + self.io_loop.start() + finally: + self.io_loop.close() + + def stop(self): + """Stop the thread. + + This method is threadsafe. + """ + self.io_loop.add_callback(self.io_loop.stop) diff --git a/ipykernel/kernelapp.py b/ipykernel/kernelapp.py index 9771c34dc..f43baf2c0 100644 --- a/ipykernel/kernelapp.py +++ b/ipykernel/kernelapp.py @@ -346,6 +346,10 @@ def close(self): self.log.debug("Closing iopub channel") self.iopub_thread.stop() self.iopub_thread.close() + if self.control_thread and self.control_thread.is_alive(): + self.log.debug("Closing control thread") + self.control_thread.stop() + self.control_thread.join() if self.debugpy_socket and not self.debugpy_socket.closed: self.debugpy_socket.close() @@ -487,7 +491,7 @@ def init_kernel(self): control_stream=control_stream, debugpy_stream=debugpy_stream, debug_shell_socket=self.debug_shell_socket, - shell_stream=shell_stream, + shell_stream=shell_stream, control_thread=self.control_thread, iopub_thread=self.iopub_thread, iopub_socket=self.iopub_socket,