summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2014-02-13 11:48:54 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2014-02-13 11:48:54 (GMT)
commit15054c16c8a562bd06fde2369012530fa2cda0a1 (patch)
tree6d5bfdfa5590d326004d9e3113adbea62379facf
parente755fba2d11bc9ceb88d6bad176763b65a1524d3 (diff)
downloadcpython-15054c16c8a562bd06fde2369012530fa2cda0a1.zip
cpython-15054c16c8a562bd06fde2369012530fa2cda0a1.tar.gz
cpython-15054c16c8a562bd06fde2369012530fa2cda0a1.tar.bz2
Issue #20526, #19466: Revert changes of issue #19466 which introduces a
regression: don't clear anymore the state of Python threads early during the Python shutdown.
-rw-r--r--Lib/test/test_threading.py49
-rw-r--r--Misc/NEWS4
-rw-r--r--Python/pythonrun.c20
3 files changed, 9 insertions, 64 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index ad363582..7170f60 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -616,51 +616,6 @@ class ThreadTests(BaseTestCase):
t.join()
self.assertRaises(ValueError, bs.release)
- def test_locals_at_exit(self):
- # Issue #19466: thread locals must not be deleted before destructors
- # are called
- rc, out, err = assert_python_ok("-c", """if 1:
- import threading
-
- class Atexit:
- def __del__(self):
- print("thread_dict.atexit = %r" % thread_dict.atexit)
-
- thread_dict = threading.local()
- thread_dict.atexit = "atexit"
-
- atexit = Atexit()
- """)
- self.assertEqual(out.rstrip(), b"thread_dict.atexit = 'atexit'")
-
- def test_warnings_at_exit(self):
- # Issue #19466: try to call most destructors at Python shutdown before
- # destroying Python thread states
- filename = __file__
- rc, out, err = assert_python_ok("-Wd", "-c", """if 1:
- import time
- import threading
-
- def open_sleep():
- # a warning will be emitted when the open file will be
- # destroyed (without being explicitly closed) while the daemon
- # thread is destroyed
- fileobj = open(%a, 'rb')
- start_event.set()
- time.sleep(60.0)
-
- start_event = threading.Event()
-
- thread = threading.Thread(target=open_sleep)
- thread.daemon = True
- thread.start()
-
- # wait until the thread started
- start_event.wait()
- """ % filename)
- self.assertRegex(err.rstrip(),
- b"^sys:1: ResourceWarning: unclosed file ")
-
@cpython_only
def test_frame_tstate_tracing(self):
# Issue #14432: Crash when a generator is created in a C thread that is
@@ -786,10 +741,6 @@ class ThreadJoinOnShutdown(BaseTestCase):
import sys
import time
import threading
- import warnings
-
- # ignore "unclosed file ..." warnings
- warnings.filterwarnings('ignore', '', ResourceWarning)
thread_has_run = set()
diff --git a/Misc/NEWS b/Misc/NEWS
index 1eb509e..f44551a 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,10 @@ Release date: 2014-02-23
Core and Builtins
-----------------
+- Issue #20526: Revert changes of issue #19466 which introduces a regression:
+ don't clear anymore the state of Python threads early during the Python
+ shutdown.
+
- Issue #20595: Make getargs.c C89 compliant.
Library
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 34a291f..e9947e9 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -582,13 +582,11 @@ Py_Finalize(void)
_Py_Finalizing = tstate;
initialized = 0;
- /* Destroy the state of all threads except of the current thread: in
- practice, only daemon threads should still be alive. Clear frames of
- other threads to call objects destructor. Destructors will be called in
- the current Python thread. Since _Py_Finalizing has been set, no other
- Python threads can lock the GIL at this point (if they try, they will
- exit immediately). */
- _PyThreadState_DeleteExcept(tstate);
+ /* Flush stdout+stderr */
+ flush_std_files();
+
+ /* Disable signal handling */
+ PyOS_FiniInterrupts();
/* Collect garbage. This may call finalizers; it's nice to call these
* before all modules are destroyed.
@@ -603,7 +601,6 @@ Py_Finalize(void)
* XXX I haven't seen a real-life report of either of these.
*/
PyGC_Collect();
-
#ifdef COUNT_ALLOCS
/* With COUNT_ALLOCS, it helps to run GC multiple times:
each collection might release some types from the type
@@ -611,13 +608,6 @@ Py_Finalize(void)
while (PyGC_Collect() > 0)
/* nothing */;
#endif
-
- /* Flush stdout+stderr */
- flush_std_files();
-
- /* Disable signal handling */
- PyOS_FiniInterrupts();
-
/* Destroy all modules */
PyImport_Cleanup();