mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-31061: fix crash in asyncio speedup module (GH-2966)
This commit is contained in:
parent
47320a652e
commit
de34cbe9cd
4 changed files with 32 additions and 0 deletions
|
@ -1,6 +1,7 @@
|
||||||
"""Tests for futures.py."""
|
"""Tests for futures.py."""
|
||||||
|
|
||||||
import concurrent.futures
|
import concurrent.futures
|
||||||
|
import gc
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
@ -19,9 +20,11 @@ except ImportError:
|
||||||
def _fakefunc(f):
|
def _fakefunc(f):
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
|
||||||
def first_cb():
|
def first_cb():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def last_cb():
|
def last_cb():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -483,6 +486,15 @@ class BaseFutureTests:
|
||||||
Exception("elephant"), Exception("elephant"))
|
Exception("elephant"), Exception("elephant"))
|
||||||
self.assertRaises(TypeError, fi.throw, list)
|
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'),
|
@unittest.skipUnless(hasattr(futures, '_CFuture'),
|
||||||
'requires the C _asyncio module')
|
'requires the C _asyncio module')
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import collections
|
import collections
|
||||||
import contextlib
|
import contextlib
|
||||||
import functools
|
import functools
|
||||||
|
import gc
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -91,6 +92,20 @@ class BaseTaskTests:
|
||||||
self.loop.set_task_factory(self.new_task)
|
self.loop.set_task_factory(self.new_task)
|
||||||
self.loop.create_future = lambda: self.new_future(self.loop)
|
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):
|
def test_other_loop_future(self):
|
||||||
other_loop = asyncio.new_event_loop()
|
other_loop = asyncio.new_event_loop()
|
||||||
fut = self.new_future(other_loop)
|
fut = self.new_future(other_loop)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fixed a crash when using asyncio and threads.
|
|
@ -972,6 +972,8 @@ FutureObj_dealloc(PyObject *self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject_GC_UnTrack(self);
|
||||||
|
|
||||||
if (fut->fut_weakreflist != NULL) {
|
if (fut->fut_weakreflist != NULL) {
|
||||||
PyObject_ClearWeakRefs(self);
|
PyObject_ClearWeakRefs(self);
|
||||||
}
|
}
|
||||||
|
@ -1846,6 +1848,8 @@ TaskObj_dealloc(PyObject *self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject_GC_UnTrack(self);
|
||||||
|
|
||||||
if (task->task_weakreflist != NULL) {
|
if (task->task_weakreflist != NULL) {
|
||||||
PyObject_ClearWeakRefs(self);
|
PyObject_ClearWeakRefs(self);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue