[3.9] bpo-37193: Remove thread objects which finished process its req… · python/cpython@0e76157

@@ -628,6 +628,39 @@ def server_close(self):

628628

self.collect_children(blocking=self.block_on_close)

629629630630631+

class _Threads(list):

632+

"""

633+

Joinable list of all non-daemon threads.

634+

"""

635+

def append(self, thread):

636+

self.reap()

637+

if thread.daemon:

638+

return

639+

super().append(thread)

640+641+

def pop_all(self):

642+

self[:], result = [], self[:]

643+

return result

644+645+

def join(self):

646+

for thread in self.pop_all():

647+

thread.join()

648+649+

def reap(self):

650+

self[:] = (thread for thread in self if thread.is_alive())

651+652+653+

class _NoThreads:

654+

"""

655+

Degenerate version of _Threads.

656+

"""

657+

def append(self, thread):

658+

pass

659+660+

def join(self):

661+

pass

662+663+631664

class ThreadingMixIn:

632665

"""Mix-in class to handle each request in a new thread."""

633666

@@ -636,9 +669,9 @@ class ThreadingMixIn:

636669

daemon_threads = False

637670

# If true, server_close() waits until all non-daemonic threads terminate.

638671

block_on_close = True

639-

# For non-daemonic threads, list of threading.Threading objects

672+

# Threads object

640673

# used by server_close() to wait for all threads completion.

641-

_threads = None

674+

_threads = _NoThreads()

642675643676

def process_request_thread(self, request, client_address):

644677

"""Same as in BaseServer but as a thread.

@@ -655,23 +688,17 @@ def process_request_thread(self, request, client_address):

655688656689

def process_request(self, request, client_address):

657690

"""Start a new thread to process the request."""

691+

if self.block_on_close:

692+

vars(self).setdefault('_threads', _Threads())

658693

t = threading.Thread(target = self.process_request_thread,

659694

args = (request, client_address))

660695

t.daemon = self.daemon_threads

661-

if not t.daemon and self.block_on_close:

662-

if self._threads is None:

663-

self._threads = []

664-

self._threads.append(t)

696+

self._threads.append(t)

665697

t.start()

666698667699

def server_close(self):

668700

super().server_close()

669-

if self.block_on_close:

670-

threads = self._threads

671-

self._threads = None

672-

if threads:

673-

for thread in threads:

674-

thread.join()

701+

self._threads.join()

675702676703677704

if hasattr(os, "fork"):