Skip to content

Commit de34cbe

Browse files
thehesiodmethane
authored andcommitted
bpo-31061: fix crash in asyncio speedup module (GH-2966)
1 parent 47320a6 commit de34cbe

File tree

4 files changed

+32
-0
lines changed

4 files changed

+32
-0
lines changed

Lib/test/test_asyncio/test_futures.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Tests for futures.py."""
22

33
import concurrent.futures
4+
import gc
45
import re
56
import sys
67
import threading
@@ -19,9 +20,11 @@
1920
def _fakefunc(f):
2021
return f
2122

23+
2224
def first_cb():
2325
pass
2426

27+
2528
def last_cb():
2629
pass
2730

@@ -483,6 +486,15 @@ def test_future_iter_throw(self):
483486
Exception("elephant"), Exception("elephant"))
484487
self.assertRaises(TypeError, fi.throw, list)
485488

489+
def test_future_del_collect(self):
490+
class Evil:
491+
def __del__(self):
492+
gc.collect()
493+
494+
for i in range(100):
495+
fut = self._new_future(loop=self.loop)
496+
fut.set_result(Evil())
497+
486498

487499
@unittest.skipUnless(hasattr(futures, '_CFuture'),
488500
'requires the C _asyncio module')

Lib/test/test_asyncio/test_tasks.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import collections
44
import contextlib
55
import functools
6+
import gc
67
import io
78
import os
89
import re
@@ -91,6 +92,20 @@ def setUp(self):
9192
self.loop.set_task_factory(self.new_task)
9293
self.loop.create_future = lambda: self.new_future(self.loop)
9394

95+
def test_task_del_collect(self):
96+
class Evil:
97+
def __del__(self):
98+
gc.collect()
99+
100+
@asyncio.coroutine
101+
def run():
102+
return Evil()
103+
104+
self.loop.run_until_complete(
105+
asyncio.gather(*[
106+
self.new_task(self.loop, run()) for _ in range(100)
107+
], loop=self.loop))
108+
94109
def test_other_loop_future(self):
95110
other_loop = asyncio.new_event_loop()
96111
fut = self.new_future(other_loop)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a crash when using asyncio and threads.

Modules/_asynciomodule.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,8 @@ FutureObj_dealloc(PyObject *self)
972972
}
973973
}
974974

975+
PyObject_GC_UnTrack(self);
976+
975977
if (fut->fut_weakreflist != NULL) {
976978
PyObject_ClearWeakRefs(self);
977979
}
@@ -1846,6 +1848,8 @@ TaskObj_dealloc(PyObject *self)
18461848
}
18471849
}
18481850

1851+
PyObject_GC_UnTrack(self);
1852+
18491853
if (task->task_weakreflist != NULL) {
18501854
PyObject_ClearWeakRefs(self);
18511855
}

0 commit comments

Comments
 (0)