Skip to content

Commit f142e85

Browse files
authored
bpo-31061: fix crash in asyncio speedup module (GH-2984)
(cherry picked from commit de34cbe)
1 parent 48fcc72 commit f142e85

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
@@ -92,6 +93,20 @@ def setUp(self):
9293
self.loop.set_task_factory(self.new_task)
9394
self.loop.create_future = lambda: self.new_future(self.loop)
9495

96+
def test_task_del_collect(self):
97+
class Evil:
98+
def __del__(self):
99+
gc.collect()
100+
101+
@asyncio.coroutine
102+
def run():
103+
return Evil()
104+
105+
self.loop.run_until_complete(
106+
asyncio.gather(*[
107+
self.new_task(self.loop, run()) for _ in range(100)
108+
], loop=self.loop))
109+
95110
def test_other_loop_future(self):
96111
other_loop = asyncio.new_event_loop()
97112
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
@@ -971,6 +971,8 @@ FutureObj_dealloc(PyObject *self)
971971
}
972972
}
973973

974+
PyObject_GC_UnTrack(self);
975+
974976
if (fut->fut_weakreflist != NULL) {
975977
PyObject_ClearWeakRefs(self);
976978
}
@@ -1845,6 +1847,8 @@ TaskObj_dealloc(PyObject *self)
18451847
}
18461848
}
18471849

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

0 commit comments

Comments
 (0)