[Python-checkins] bpo-31061: fix crash in asyncio speedup module (GH-2966)

INADA Naoki webhook-mailer at python.org
Wed Aug 2 02:31:10 EDT 2017


https://github.com/python/cpython/commit/de34cbe9cdaaf7b85fed86f99c2fd071e1a7b1d2
commit: de34cbe9cdaaf7b85fed86f99c2fd071e1a7b1d2
branch: master
author: Alexander Mohr <thehesiod at users.noreply.github.com>
committer: INADA Naoki <methane at users.noreply.github.com>
date: 2017-08-02T15:31:07+09:00
summary:

bpo-31061: fix crash in asyncio speedup module (GH-2966)

files:
A Misc/NEWS.d/next/Library/2017-08-01-09-32-58.bpo-31061.husAYX.rst
M Lib/test/test_asyncio/test_futures.py
M Lib/test/test_asyncio/test_tasks.py
M Modules/_asynciomodule.c

diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py
index ce657fc1b6a..ebedfec7fa3 100644
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -1,6 +1,7 @@
 """Tests for futures.py."""
 
 import concurrent.futures
+import gc
 import re
 import sys
 import threading
@@ -19,9 +20,11 @@
 def _fakefunc(f):
     return f
 
+
 def first_cb():
     pass
 
+
 def last_cb():
     pass
 
@@ -483,6 +486,15 @@ def test_future_iter_throw(self):
                           Exception("elephant"), Exception("elephant"))
         self.assertRaises(TypeError, fi.throw, list)
 
+    def test_future_del_collect(self):
+        class Evil:
+            def __del__(self):
+                gc.collect()
+
+        for i in range(100):
+            fut = self._new_future(loop=self.loop)
+            fut.set_result(Evil())
+
 
 @unittest.skipUnless(hasattr(futures, '_CFuture'),
                      'requires the C _asyncio module')
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index 686387f4f21..36082ec7c6a 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -3,6 +3,7 @@
 import collections
 import contextlib
 import functools
+import gc
 import io
 import os
 import re
@@ -91,6 +92,20 @@ def setUp(self):
         self.loop.set_task_factory(self.new_task)
         self.loop.create_future = lambda: self.new_future(self.loop)
 
+    def test_task_del_collect(self):
+        class Evil:
+            def __del__(self):
+                gc.collect()
+
+        @asyncio.coroutine
+        def run():
+            return Evil()
+
+        self.loop.run_until_complete(
+            asyncio.gather(*[
+                self.new_task(self.loop, run()) for _ in range(100)
+            ], loop=self.loop))
+
     def test_other_loop_future(self):
         other_loop = asyncio.new_event_loop()
         fut = self.new_future(other_loop)
diff --git a/Misc/NEWS.d/next/Library/2017-08-01-09-32-58.bpo-31061.husAYX.rst b/Misc/NEWS.d/next/Library/2017-08-01-09-32-58.bpo-31061.husAYX.rst
new file mode 100644
index 00000000000..650e5f95f94
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-08-01-09-32-58.bpo-31061.husAYX.rst
@@ -0,0 +1 @@
+Fixed a crash when using asyncio and threads.
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index b998a04e623..d4b313480e9 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -972,6 +972,8 @@ FutureObj_dealloc(PyObject *self)
         }
     }
 
+    PyObject_GC_UnTrack(self);
+
     if (fut->fut_weakreflist != NULL) {
         PyObject_ClearWeakRefs(self);
     }
@@ -1846,6 +1848,8 @@ TaskObj_dealloc(PyObject *self)
         }
     }
 
+    PyObject_GC_UnTrack(self);
+
     if (task->task_weakreflist != NULL) {
         PyObject_ClearWeakRefs(self);
     }



More information about the Python-checkins mailing list