bpo-31233: socketserver.ThreadingMixIn.server_close() (#3523)
socketserver.ThreadingMixIn now keeps a list of non-daemonic threads
to wait until all these threads complete in server_close().
Reenable test_logging skipped tests.
Fix SocketHandlerTest.tearDown(): close the socket handler before
stopping the server, so the server can join threads.
diff --git a/Lib/socketserver.py b/Lib/socketserver.py
index 721eb50..1ae7bef 100644
--- a/Lib/socketserver.py
+++ b/Lib/socketserver.py
@@ -629,6 +629,9 @@
# Decides how threads will act upon termination of the
# main process
daemon_threads = False
+ # For non-daemonic threads, list of threading.Threading objects
+ # used by server_close() to wait for all threads completion.
+ _threads = None
def process_request_thread(self, request, client_address):
"""Same as in BaseServer but as a thread.
@@ -648,8 +651,20 @@
t = threading.Thread(target = self.process_request_thread,
args = (request, client_address))
t.daemon = self.daemon_threads
+ if not t.daemon:
+ if self._threads is None:
+ self._threads = []
+ self._threads.append(t)
t.start()
+ def server_close(self):
+ super().server_close()
+ threads = self._threads
+ self._threads = None
+ if threads:
+ for thread in threads:
+ thread.join()
+
if hasattr(os, "fork"):
class ForkingUDPServer(ForkingMixIn, UDPServer): pass