mirror of
https://github.com/python/cpython.git
synced 2026-02-21 22:50:55 +00:00
gh-140652: Fix a crash in _interpchannels.list_all() after closing a channel (ПР-143743)
This commit is contained in:
parent
dd64e4260e
commit
3f50432e31
4 changed files with 48 additions and 7 deletions
|
|
@ -382,6 +382,38 @@ def test_sequential_ids(self):
|
|||
self.assertEqual(id3, int(id2) + 1)
|
||||
self.assertEqual(set(after) - set(before), {id1, id2, id3})
|
||||
|
||||
def test_channel_list_all_closed(self):
|
||||
id1 = _channels.create()
|
||||
id2 = _channels.create()
|
||||
id3 = _channels.create()
|
||||
before = _channels.list_all()
|
||||
expected = [info for info in before if info[0] != id2]
|
||||
_channels.close(id2, force=True)
|
||||
after = _channels.list_all()
|
||||
self.assertEqual(set(after), set(expected))
|
||||
self.assertEqual(len(after), len(before) - 1)
|
||||
|
||||
def test_channel_list_all_destroyed(self):
|
||||
id1 = _channels.create()
|
||||
id2 = _channels.create()
|
||||
id3 = _channels.create()
|
||||
before = _channels.list_all()
|
||||
expected = [info for info in before if info[0] != id2]
|
||||
_channels.destroy(id2)
|
||||
after = _channels.list_all()
|
||||
self.assertEqual(set(after), set(expected))
|
||||
self.assertEqual(len(after), len(before) - 1)
|
||||
|
||||
def test_channel_list_all_released(self):
|
||||
id1 = _channels.create()
|
||||
id2 = _channels.create()
|
||||
id3 = _channels.create()
|
||||
before = _channels.list_all()
|
||||
_channels.release(id2, send=True, recv=True)
|
||||
after = _channels.list_all()
|
||||
self.assertEqual(set(after), set(before))
|
||||
self.assertEqual(len(after), len(before))
|
||||
|
||||
def test_ids_global(self):
|
||||
id1 = _interpreters.create()
|
||||
out = _run_output(id1, dedent("""
|
||||
|
|
|
|||
|
|
@ -47,6 +47,12 @@ def test_list_all(self):
|
|||
after = set(channels.list_all())
|
||||
self.assertEqual(after, created)
|
||||
|
||||
def test_list_all_closed(self):
|
||||
created = [channels.create() for _ in range(3)]
|
||||
rch, sch = created.pop(1)
|
||||
rch.close()
|
||||
self.assertEqual(set(channels.list_all()), set(created))
|
||||
|
||||
def test_shareable(self):
|
||||
interp = interpreters.create()
|
||||
rch, sch = channels.create()
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Fix a crash in :func:`!_interpchannels.list_all` after closing a channel.
|
||||
|
|
@ -1644,14 +1644,16 @@ _channels_list_all(_channels *channels, int64_t *count)
|
|||
if (ids == NULL) {
|
||||
goto done;
|
||||
}
|
||||
_channelref *ref = channels->head;
|
||||
for (int64_t i=0; ref != NULL; ref = ref->next, i++) {
|
||||
ids[i] = (struct channel_id_and_info){
|
||||
.id = ref->cid,
|
||||
.defaults = ref->chan->defaults,
|
||||
};
|
||||
int64_t i = 0;
|
||||
for (_channelref *ref = channels->head; ref != NULL; ref = ref->next) {
|
||||
if (ref->chan != NULL) {
|
||||
ids[i++] = (struct channel_id_and_info){
|
||||
.id = ref->cid,
|
||||
.defaults = ref->chan->defaults,
|
||||
};
|
||||
}
|
||||
}
|
||||
*count = channels->numopen;
|
||||
*count = i;
|
||||
|
||||
cids = ids;
|
||||
done:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue