mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
gh-110300: Fix Refleaks in test_interpreters and test__xxinterpchannels (gh-110318)
This commit is contained in:
parent
625ecbe92e
commit
269005e784
3 changed files with 30 additions and 10 deletions
|
@ -215,4 +215,5 @@ class SendChannel(_ChannelEnd):
|
|||
_channels.close(self._id, send=True)
|
||||
|
||||
|
||||
_channels._register_end_types(SendChannel, RecvChannel)
|
||||
# XXX This is causing leaks (gh-110318):
|
||||
#_channels._register_end_types(SendChannel, RecvChannel)
|
||||
|
|
|
@ -68,6 +68,17 @@ def _running(interp):
|
|||
|
||||
class TestBase(unittest.TestCase):
|
||||
|
||||
def pipe(self):
|
||||
def ensure_closed(fd):
|
||||
try:
|
||||
os.close(fd)
|
||||
except OSError:
|
||||
pass
|
||||
r, w = os.pipe()
|
||||
self.addCleanup(lambda: ensure_closed(r))
|
||||
self.addCleanup(lambda: ensure_closed(w))
|
||||
return r, w
|
||||
|
||||
def tearDown(self):
|
||||
clean_up_interpreters()
|
||||
|
||||
|
@ -262,7 +273,7 @@ class TestInterpreterIsRunning(TestBase):
|
|||
self.assertFalse(interp.is_running())
|
||||
|
||||
def test_finished(self):
|
||||
r, w = os.pipe()
|
||||
r, w = self.pipe()
|
||||
interp = interpreters.create()
|
||||
interp.run(f"""if True:
|
||||
import os
|
||||
|
@ -299,8 +310,8 @@ class TestInterpreterIsRunning(TestBase):
|
|||
interp.is_running()
|
||||
|
||||
def test_with_only_background_threads(self):
|
||||
r_interp, w_interp = os.pipe()
|
||||
r_thread, w_thread = os.pipe()
|
||||
r_interp, w_interp = self.pipe()
|
||||
r_thread, w_thread = self.pipe()
|
||||
|
||||
DONE = b'D'
|
||||
FINISHED = b'F'
|
||||
|
@ -425,8 +436,8 @@ class TestInterpreterClose(TestBase):
|
|||
self.assertTrue(interp.is_running())
|
||||
|
||||
def test_subthreads_still_running(self):
|
||||
r_interp, w_interp = os.pipe()
|
||||
r_thread, w_thread = os.pipe()
|
||||
r_interp, w_interp = self.pipe()
|
||||
r_thread, w_thread = self.pipe()
|
||||
|
||||
FINISHED = b'F'
|
||||
|
||||
|
@ -532,8 +543,8 @@ class TestInterpreterRun(TestBase):
|
|||
interp.run(b'print("spam")')
|
||||
|
||||
def test_with_background_threads_still_running(self):
|
||||
r_interp, w_interp = os.pipe()
|
||||
r_thread, w_thread = os.pipe()
|
||||
r_interp, w_interp = self.pipe()
|
||||
r_thread, w_thread = self.pipe()
|
||||
|
||||
RAN = b'R'
|
||||
DONE = b'D'
|
||||
|
@ -822,6 +833,7 @@ class TestChannels(TestBase):
|
|||
after = set(interpreters.list_all_channels())
|
||||
self.assertEqual(after, created)
|
||||
|
||||
@unittest.expectedFailure # See gh-110318:
|
||||
def test_shareable(self):
|
||||
rch, sch = interpreters.create_channel()
|
||||
|
||||
|
|
|
@ -1992,6 +1992,7 @@ _get_current_channel_end_type(int end)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
Py_DECREF(highlevel);
|
||||
if (end == CHANNEL_SEND) {
|
||||
cls = state->send_channel_type;
|
||||
}
|
||||
|
@ -2012,6 +2013,7 @@ _channel_end_from_xid(_PyCrossInterpreterData *data)
|
|||
}
|
||||
PyTypeObject *cls = _get_current_channel_end_type(cid->end);
|
||||
if (cls == NULL) {
|
||||
Py_DECREF(cid);
|
||||
return NULL;
|
||||
}
|
||||
PyObject *obj = PyObject_CallOneArg((PyObject *)cls, (PyObject *)cid);
|
||||
|
@ -2027,7 +2029,9 @@ _channel_end_shared(PyThreadState *tstate, PyObject *obj,
|
|||
if (cidobj == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (_channelid_shared(tstate, cidobj, data) < 0) {
|
||||
int res = _channelid_shared(tstate, cidobj, data);
|
||||
Py_DECREF(cidobj);
|
||||
if (res < 0) {
|
||||
return -1;
|
||||
}
|
||||
data->new_object = _channel_end_from_xid;
|
||||
|
@ -2464,7 +2468,10 @@ channel__channel_id(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
return NULL;
|
||||
}
|
||||
PyTypeObject *cls = state->ChannelIDType;
|
||||
assert(get_module_from_owned_type(cls) == self);
|
||||
|
||||
PyObject *mod = get_module_from_owned_type(cls);
|
||||
assert(mod == self);
|
||||
Py_DECREF(mod);
|
||||
|
||||
return _channelid_new(self, cls, args, kwds);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue