Content-Length: 452691 | pFad | http://github.com/python/cpython/pull/17323/commits/75e791f66e3c83f53084d0a0d0463b68d9d929f8

A6 bpo-38880: List interpreters associated with a channel end by LewisGaul · Pull Request #17323 · python/cpython · GitHub
Skip to content

bpo-38880: List interpreters associated with a channel end #17323

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Apr 29, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
ec5aa60
Attempt at implementing channel_list_interpreters()
LewisGaul Nov 12, 2019
ee78133
Fix some error cases
LewisGaul Nov 12, 2019
433a5b0
Fix issue with decreasing list items' references
LewisGaul Nov 12, 2019
64c1661
Fix issue with reference to interpreter
LewisGaul Nov 20, 2019
2c5c6df
Add ability to list interpreters on send or receive channels
LewisGaul Nov 20, 2019
7f439fa
Fix arg parsing in C code
LewisGaul Nov 20, 2019
d86ae97
Minor changes
LewisGaul Nov 20, 2019
c529c88
Add channel_list_interpreters() tests
Nov 21, 2019
168ebf3
Fix docstring
LewisGaul Nov 21, 2019
2a7b508
Improve naming in tests
LewisGaul Nov 21, 2019
4d6ac6e
Add macros for int64_t max etc
LewisGaul Nov 21, 2019
a44c2d2
Fix error handling
LewisGaul Nov 21, 2019
215300b
Expose _PyInterpreterState_LookUpID
LewisGaul Nov 21, 2019
9b124db
Fix bad git rebase (use _xxsubinterpreters module name)
LewisGaul Nov 21, 2019
76621c7
Remove decref of NULL
LewisGaul Nov 21, 2019
d4c51bf
Fix leftover broken code from nested loop
LewisGaul Nov 21, 2019
f3c2b34
Remove whitespace from tests
LewisGaul Nov 21, 2019
af10d1f
Add to Misc/ACKS
LewisGaul Nov 21, 2019
ac09b6c
Remove PY_INT64_T_MAX etc. and use stdint.h
LewisGaul Nov 22, 2019
8e69864
Remove whitespace
LewisGaul Nov 22, 2019
0546702
📜🤖 Added by blurb_it.
blurb-it[bot] Nov 22, 2019
ad511ef
Update news entry to remove mention of PEP 554
LewisGaul Nov 23, 2019
a1b7c3a
Remove unnecessary asserts
LewisGaul Nov 23, 2019
d9b3e27
Use single 'send' argument in channel_list_interpreters() API
LewisGaul Nov 23, 2019
f4990b0
Tidy up _channelends_list_interpreters() function
LewisGaul Nov 23, 2019
c7dbb04
Move variable declarations inline
LewisGaul Nov 23, 2019
6202ecd
Use _PyInterpreterID_New() instead of getting existing objects
LewisGaul Nov 23, 2019
a7cf61b
Merge branch 'list-channel-interps' of github.com:LewisGaul/cpython i…
LewisGaul Nov 23, 2019
357101f
Markups - remove check for number of open channels and improve test s…
LewisGaul Dec 14, 2019
faca1df
Add more listing subinterpreter tests
LewisGaul Jan 21, 2020
75e791f
Implementation rewrite upon Eric's suggestion. Just one testcase now …
LewisGaul Apr 18, 2020
79f5d35
Fix issue with ChannelClosedError not being raised when 'send' end of…
LewisGaul Apr 28, 2020
5481e82
Add testcase for listing associated interpreters with basic closed ch…
LewisGaul Apr 28, 2020
79be8a0
Fix a refleak.
ericsnowcurrently Apr 28, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implementation rewrite upon Eric's suggestion. Just one testcase now …
…failing
  • Loading branch information
LewisGaul committed Apr 18, 2020
commit 75e791f66e3c83f53084d0a0d0463b68d9d929f8
9 changes: 4 additions & 5 deletions Lib/test/test__xxsubinterpreters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1260,7 +1260,6 @@ def test_channel_list_interpreters_multiple(self):
self.assertEqual(set(send_interps), {interp0, interp1})
self.assertEqual(set(recv_interps), {interp2, interp3})

@unittest.skip("Failing due to handling of destroyed interpreters")
def test_channel_list_interpreters_destroyed(self):
"""Test listing channel interpreters with a destroyed interpreter."""
interp0 = interpreters.get_main()
Expand Down Expand Up @@ -1310,10 +1309,10 @@ def test_channel_list_interpreters_released(self):

# Release the main interpreter from the send end.
interpreters.channel_release(cid, send=True)
# Send end should raise an error for the main interpreter.
with self.assertRaises(interpreters.ChannelClosedError):
send_interps = interpreters.channel_list_interpreters(cid, send=True)
# Send end should have no associated interpreters.
send_interps = interpreters.channel_list_interpreters(cid, send=True)
recv_interps = interpreters.channel_list_interpreters(cid, send=False)
self.assertEqual(len(send_interps), 0)
self.assertEqual(len(recv_interps), 2)

# Release one of the subinterpreters from the receive end.
Expand All @@ -1324,7 +1323,7 @@ def test_channel_list_interpreters_released(self):
# Receive end should have the released interpreter removed.
send_interps = interpreters.channel_list_interpreters(cid, send=True)
recv_interps = interpreters.channel_list_interpreters(cid, send=False)
self.assertEqual(len(send_interps), 1)
self.assertEqual(len(send_interps), 0)
self.assertEqual(recv_interps, [interp1])

def test_channel_list_interpreters_closed(self):
Expand Down
84 changes: 40 additions & 44 deletions Modules/_xxsubinterpretersmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ _channelend_find(_channelend *first, int64_t interp, _channelend **pprev)

typedef struct _channelassociations {
// Note that the list entries are never removed for interpreter
// for which the channel is closed. This should be a problem in
// for which the channel is closed. This should not be a problem in
// practice. Also, a channel isn't automatically closed when an
// interpreter is destroyed.
int64_t numsendopen;
Expand Down Expand Up @@ -627,27 +627,6 @@ _channelends_associate(_channelends *ends, int64_t interp, int send)
return 0;
}

static int64_t *
_channelends_list_interpreters(_channelends *ends, int64_t *count, int send)
{
int64_t numopen = send ? ends->numsendopen : ends->numrecvopen;

int64_t *ids = PyMem_NEW(int64_t, (Py_ssize_t)numopen);
if (ids == NULL) {
PyErr_NoMemory();
return NULL;
}

_channelend *ref = send ? ends->send : ends->recv;
for (int64_t i=0; ref != NULL; ref = ref->next, i++) {
ids[i] = ref->interp;
}

*count = numopen;

return ids;
}

static int
_channelends_is_open(_channelends *ends)
{
Expand Down Expand Up @@ -1409,6 +1388,21 @@ _channel_close(_channels *channels, int64_t id, int end, int force)
return _channels_close(channels, id, NULL, end, force);
}

static int
_channel_is_associated(_channels *channels, int64_t cid, int64_t interp,
int send)
{
_PyChannelState *chan = _channels_lookup(channels, cid, NULL);
if (chan == NULL) {
return -1;
}

_channelend *end = _channelend_find(send ? chan->ends->send : chan->ends->recv,
interp, NULL);

return (end != NULL && end->open);
}

/* ChannelID class */

static PyTypeObject ChannelIDtype;
Expand Down Expand Up @@ -2339,54 +2333,56 @@ PyDoc_STRVAR(channel_list_all_doc,
\n\
Return the list of all IDs for active channels.");


static PyObject *
channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {"cid", "send", NULL};
int64_t cid; /* Channel ID */
int send = 0; /* Send or receive end? */
PyObject *ret = NULL;
int64_t id;
PyObject *ids, *id_obj;
PyInterpreterState *interp;

if (!PyArg_ParseTupleAndKeywords(
args, kwds, "O&$p:channel_list_interpreters",
kwlist, channel_id_converter, &cid, &send)) {
return NULL;
}

_PyChannelState *chan = _channels_lookup(&_globals.channels, cid, NULL);
if (chan == NULL) {
return NULL;
}

int64_t count = 0; /* Number of interpreters */
int64_t *ids = _channelends_list_interpreters(chan->ends, &count, send);
ids = PyList_New(0);
if (ids == NULL) {
goto except;
}

ret = PyList_New((Py_ssize_t)count);
if (ret == NULL) {
goto except;
}

for (int64_t i=0; i < count; i++) {
PyObject *id_obj = _PyInterpreterID_New(ids[i]);
if (id_obj == NULL) {
interp = PyInterpreterState_Head();
while (interp != NULL) {
id = PyInterpreterState_GetID(interp);
assert(id >= 0);
int res = _channel_is_associated(&_globals.channels, cid, id, send);
if (res < 0) {
goto except;
}
PyList_SET_ITEM(ret, i, id_obj);
if (res) {
id_obj = _PyInterpreterState_GetIDObject(interp);
if (id_obj == NULL) {
goto except;
}
res = PyList_Insert(ids, 0, id_obj);
if (res < 0) {
goto except;
}
}
interp = PyInterpreterState_Next(interp);
}

goto finally;

except:
Py_XDECREF(ret);
ret = NULL;
Py_XDECREF(ids);
ids = NULL;

finally:
PyMem_Free(ids);
return ret;
return ids;
}

PyDoc_STRVAR(channel_list_interpreters_doc,
Expand Down








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/python/cpython/pull/17323/commits/75e791f66e3c83f53084d0a0d0463b68d9d929f8

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy