Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Doc/library/socketserver.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,13 @@ server classes.
only available on POSIX platforms that support :func:`~os.fork`.

:meth:`socketserver.ForkingMixIn.server_close` waits until all child
processes complete.
processes complete, except if
:attr:`socketserver.ForkingMixIn.block_on_close` attribute is false.

:meth:`socketserver.ThreadingMixIn.server_close` waits until all non-daemon
threads complete. Use daemonic threads by setting
threads complete, except if
:attr:`socketserver.ThreadingMixIn.block_on_close` attribute is false. Use
daemonic threads by setting
:data:`ThreadingMixIn.daemon_threads` to ``True`` to not wait until threads
complete.

Expand All @@ -128,6 +131,8 @@ server classes.
:meth:`socketserver.ForkingMixIn.server_close` and
:meth:`socketserver.ThreadingMixIn.server_close` now waits until all
child processes and non-daemonic threads complete.
Add a new :attr:`socketserver.ForkingMixIn.block_on_close` class
attribute to opt-in for the pre-3.7 behaviour.


.. class:: ForkingTCPServer
Expand Down
27 changes: 23 additions & 4 deletions Doc/whatsnew/3.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,18 @@ by default.
(Contributed by Christian Heimes in :issue:`28134`.)


socketserver
------------

:meth:`socketserver.ThreadingMixIn.server_close` now waits until all non-daemon
threads complete. :meth:`socketserver.ForkingMixIn.server_close` now waits
until all child processes complete.

Add a new :attr:`socketserver.ForkingMixIn.block_on_close` class attribute to
:class:`socketserver.ForkingMixIn` and :class:`socketserver.ThreadingMixIn`
classes. Set the class attribute to ``False`` to get the pre-3.7 behaviour.


sqlite3
-------

Expand Down Expand Up @@ -2156,10 +2168,17 @@ Changes in the Python API
and module are affected by this change. (Contributed by INADA Naoki and
Eugene Toder in :issue:`29463`.)

* :meth:`~socketserver.BaseServer.server_close` in
:class:`socketserver.ThreadingMixIn` and :class:`socketserver.ForkingMixIn`
now waits until all non-daemon threads complete.
(Contributed by Victor Stinner in :issue:`31233` and :issue:`31151`.)
* :meth:`socketserver.ThreadingMixIn.server_close` now waits until all
non-daemon threads complete. Set the new
:attr:`socketserver.ThreadingMixIn.block_on_close` class attribute to
``False`` to get the pre-3.7 behaviour.
(Contributed by Victor Stinner in :issue:`31233` and :issue:`33540`.)

* :meth:`socketserver.ForkingMixIn.server_close` now waits until all
child processes complete. Set the new
:attr:`socketserver.ForkingMixIn.block_on_close` class attribute to ``False``
to get the pre-3.7 behaviour.
(Contributed by Victor Stinner in :issue:`31151` and :issue:`33540`.)

* The :func:`locale.localeconv` function now temporarily sets the ``LC_CTYPE``
locale to the value of ``LC_NUMERIC`` in some cases.
Expand Down
17 changes: 11 additions & 6 deletions Lib/socketserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,8 @@ class ForkingMixIn:
timeout = 300
active_children = None
max_children = 40
# If true, server_close() waits until all child processes complete.
block_on_close = True

def collect_children(self, *, blocking=False):
"""Internal routine to wait for children that have exited."""
Expand Down Expand Up @@ -620,7 +622,7 @@ def process_request(self, request, client_address):

def server_close(self):
super().server_close()
self.collect_children(blocking=True)
self.collect_children(blocking=self.block_on_close)


class ThreadingMixIn:
Expand All @@ -629,6 +631,8 @@ class ThreadingMixIn:
# Decides how threads will act upon termination of the
# main process
daemon_threads = False
# If true, server_close() waits until all non-daemonic threads terminate.
block_on_close = True
# For non-daemonic threads, list of threading.Threading objects
# used by server_close() to wait for all threads completion.
_threads = None
Expand Down Expand Up @@ -659,11 +663,12 @@ def process_request(self, request, client_address):

def server_close(self):
super().server_close()
threads = self._threads
self._threads = None
if threads:
for thread in threads:
thread.join()
if self.block_on_close:
threads = self._threads
self._threads = None
if threads:
for thread in threads:
thread.join()


if hasattr(os, "fork"):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add a new ``block_on_close`` class attribute to ``ForkingMixIn`` and
``ThreadingMixIn`` classes of :mod:`socketserver`.