Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit de34cbe

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

File tree

Expand file treeCollapse file tree

4 files changed

+32
-0
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+32
-0
lines changed

‎Lib/test/test_asyncio/test_futures.py

Copy file name to clipboardExpand all lines: Lib/test/test_asyncio/test_futures.py
+12Lines 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

Copy file name to clipboardExpand all lines: Lib/test/test_asyncio/test_tasks.py
+15Lines 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)
+1Lines 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

Copy file name to clipboardExpand all lines: Modules/_asynciomodule.c
+4Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.