!70 Fix reference leak when Thread is never joined
From: @tong_1001 Reviewed-by: Signed-off-by:
This commit is contained in:
commit
b7072f7f10
100
backport-Fix-reference-leak-when-Thread-is-never-joined.patch
Normal file
100
backport-Fix-reference-leak-when-Thread-is-never-joined.patch
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
From b30b25b26663fb6070b8ed86fe3a20dcb557d05d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Antoine Pitrou <antoine@python.org>
|
||||||
|
Date: Sat, 15 May 2021 11:51:20 +0200
|
||||||
|
Subject: [PATCH] [3.9] bpo-37788: Fix reference leak when Thread is never
|
||||||
|
joined (GH-26103) (GH-26142)
|
||||||
|
|
||||||
|
Reference:https://github.com/python/cpython/commit/b30b25b26663fb6070b8ed86fe3a20dcb557d05d
|
||||||
|
|
||||||
|
When a Thread is not joined after it has stopped, its lock may remain in the _shutdown_locks set until interpreter shutdown. If many threads are created this way, the _shutdown_locks set could therefore grow endlessly. To avoid such a situation, purge expired locks each time a new one is added or removed..
|
||||||
|
(cherry picked from commit c10c2ec7a0e06975e8010c56c9c3270f8ea322ec)
|
||||||
|
|
||||||
|
Co-authored-by: Antoine Pitrou <antoine@python.org>
|
||||||
|
|
||||||
|
Automerge-Triggered-By: GH:pitrou
|
||||||
|
---
|
||||||
|
Lib/test/test_threading.py | 8 ++++++++
|
||||||
|
Lib/threading.py | 19 ++++++++++++++++++-
|
||||||
|
.../2021-05-13-19-07-28.bpo-37788.adeFcf.rst | 1 +
|
||||||
|
3 files changed, 27 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Library/2021-05-13-19-07-28.bpo-37788.adeFcf.rst
|
||||||
|
|
||||||
|
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
|
||||||
|
index ac4e7a7..f2e427c 100644
|
||||||
|
--- a/Lib/test/test_threading.py
|
||||||
|
+++ b/Lib/test/test_threading.py
|
||||||
|
@@ -762,6 +762,14 @@ class ThreadTests(BaseTestCase):
|
||||||
|
# Daemon threads must never add it to _shutdown_locks.
|
||||||
|
self.assertNotIn(tstate_lock, threading._shutdown_locks)
|
||||||
|
|
||||||
|
+ def test_leak_without_join(self):
|
||||||
|
+ # bpo-37788: Test that a thread which is not joined explicitly
|
||||||
|
+ # does not leak. Test written for reference leak checks.
|
||||||
|
+ def noop(): pass
|
||||||
|
+ with support.wait_threads_exit():
|
||||||
|
+ threading.Thread(target=noop).start()
|
||||||
|
+ # Thread.join() is not called
|
||||||
|
+
|
||||||
|
|
||||||
|
class ThreadJoinOnShutdown(BaseTestCase):
|
||||||
|
|
||||||
|
diff --git a/Lib/threading.py b/Lib/threading.py
|
||||||
|
index 813dae2..f8f5954 100644
|
||||||
|
--- a/Lib/threading.py
|
||||||
|
+++ b/Lib/threading.py
|
||||||
|
@@ -739,12 +739,27 @@ _active_limbo_lock = _allocate_lock()
|
||||||
|
_active = {} # maps thread id to Thread object
|
||||||
|
_limbo = {}
|
||||||
|
_dangling = WeakSet()
|
||||||
|
+
|
||||||
|
# Set of Thread._tstate_lock locks of non-daemon threads used by _shutdown()
|
||||||
|
# to wait until all Python thread states get deleted:
|
||||||
|
# see Thread._set_tstate_lock().
|
||||||
|
_shutdown_locks_lock = _allocate_lock()
|
||||||
|
_shutdown_locks = set()
|
||||||
|
|
||||||
|
+def _maintain_shutdown_locks():
|
||||||
|
+ """
|
||||||
|
+ Drop any shutdown locks that don't correspond to running threads anymore.
|
||||||
|
+
|
||||||
|
+ Calling this from time to time avoids an ever-growing _shutdown_locks
|
||||||
|
+ set when Thread objects are not joined explicitly. See bpo-37788.
|
||||||
|
+
|
||||||
|
+ This must be called with _shutdown_locks_lock acquired.
|
||||||
|
+ """
|
||||||
|
+ # If a lock was released, the corresponding thread has exited
|
||||||
|
+ to_remove = [lock for lock in _shutdown_locks if not lock.locked()]
|
||||||
|
+ _shutdown_locks.difference_update(to_remove)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
# Main class for threads
|
||||||
|
|
||||||
|
class Thread:
|
||||||
|
@@ -910,6 +925,7 @@ class Thread:
|
||||||
|
|
||||||
|
if not self.daemon:
|
||||||
|
with _shutdown_locks_lock:
|
||||||
|
+ _maintain_shutdown_locks()
|
||||||
|
_shutdown_locks.add(self._tstate_lock)
|
||||||
|
|
||||||
|
def _bootstrap_inner(self):
|
||||||
|
@@ -965,7 +981,8 @@ class Thread:
|
||||||
|
self._tstate_lock = None
|
||||||
|
if not self.daemon:
|
||||||
|
with _shutdown_locks_lock:
|
||||||
|
- _shutdown_locks.discard(lock)
|
||||||
|
+ # Remove our lock and other released locks from _shutdown_locks
|
||||||
|
+ _maintain_shutdown_locks()
|
||||||
|
|
||||||
|
def _delete(self):
|
||||||
|
"Remove current thread from the dict of currently running threads."
|
||||||
|
diff --git a/Misc/NEWS.d/next/Library/2021-05-13-19-07-28.bpo-37788.adeFcf.rst b/Misc/NEWS.d/next/Library/2021-05-13-19-07-28.bpo-37788.adeFcf.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..0c33923
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Misc/NEWS.d/next/Library/2021-05-13-19-07-28.bpo-37788.adeFcf.rst
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+Fix a reference leak when a Thread object is never joined.
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
10
python3.spec
10
python3.spec
@ -3,7 +3,7 @@ Summary: Interpreter of the Python3 programming language
|
|||||||
URL: https://www.python.org/
|
URL: https://www.python.org/
|
||||||
|
|
||||||
Version: 3.8.5
|
Version: 3.8.5
|
||||||
Release: 9
|
Release: 10
|
||||||
License: Python
|
License: Python
|
||||||
|
|
||||||
%global branchversion 3.8
|
%global branchversion 3.8
|
||||||
@ -99,6 +99,7 @@ Patch252: CVE-2020-27619.patch
|
|||||||
Patch254: CVE-2021-3177.patch
|
Patch254: CVE-2021-3177.patch
|
||||||
Patch255: backport-CVE-2021-23336.patch
|
Patch255: backport-CVE-2021-23336.patch
|
||||||
Patch256: backport-Remove-thread-objects-which-finished-process-its-request.patch
|
Patch256: backport-Remove-thread-objects-which-finished-process-its-request.patch
|
||||||
|
Patch257: backport-Fix-reference-leak-when-Thread-is-never-joined.patch
|
||||||
|
|
||||||
Provides: python%{branchversion} = %{version}-%{release}
|
Provides: python%{branchversion} = %{version}-%{release}
|
||||||
Provides: python(abi) = %{branchversion}
|
Provides: python(abi) = %{branchversion}
|
||||||
@ -195,6 +196,7 @@ rm Lib/ensurepip/_bundled/*.whl
|
|||||||
%patch254 -p1
|
%patch254 -p1
|
||||||
%patch255 -p1
|
%patch255 -p1
|
||||||
%patch256 -p1
|
%patch256 -p1
|
||||||
|
%patch257 -p1
|
||||||
|
|
||||||
rm configure pyconfig.h.in
|
rm configure pyconfig.h.in
|
||||||
|
|
||||||
@ -802,6 +804,12 @@ export BEP_GTDLIST="$BEP_GTDLIST_TMP"
|
|||||||
%{_mandir}/*/*
|
%{_mandir}/*/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sun May 23 2021 shixuantong<shixuantong@huawei.com> - 3.8.5-10
|
||||||
|
- Type:bugfix
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:Fix reference leak when Thread is never joined
|
||||||
|
|
||||||
* Tue Apr 27 2021 BruceGW<gyl93216@163.com> - 3.8.5-9
|
* Tue Apr 27 2021 BruceGW<gyl93216@163.com> - 3.8.5-9
|
||||||
- Type:bugfix
|
- Type:bugfix
|
||||||
- ID:NA
|
- ID:NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user