Skip to content

Commit ef85d34

Browse files
Add the counts for all ends.
1 parent 7ba2e8f commit ef85d34

File tree

1 file changed

+96
-13
lines changed

1 file changed

+96
-13
lines changed

Modules/_xxinterpchannelsmodule.c

Lines changed: 96 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,6 +2098,16 @@ struct channel_info {
20982098
struct {
20992099
// 1: closed; -1: closing
21002100
int closed;
2101+
struct {
2102+
Py_ssize_t nsend_only; // not released
2103+
Py_ssize_t nsend_only_released;
2104+
Py_ssize_t nrecv_only; // not released
2105+
Py_ssize_t nrecv_only_released;
2106+
Py_ssize_t nboth; // not released
2107+
Py_ssize_t nboth_released;
2108+
Py_ssize_t nboth_send_released;
2109+
Py_ssize_t nboth_recv_released;
2110+
} all;
21012111
struct {
21022112
// 1: associated; -1: released
21032113
int send;
@@ -2152,20 +2162,68 @@ _channel_get_info(_channels *channels, int64_t cid, struct channel_info *info)
21522162
// Get the number of queued objects.
21532163
info->count = chan->queue->count;
21542164

2155-
// Get the current ends status.
2156-
_channelend *send = _channelend_find(chan->ends->send, interpid, NULL);
2157-
if (send == NULL) {
2158-
info->status.cur.send = 0;
2159-
}
2160-
else {
2161-
info->status.cur.send = send->open ? 1 : -1;
2162-
}
2163-
_channelend *recv = _channelend_find(chan->ends->recv, interpid, NULL);
2164-
if (recv == NULL) {
2165-
info->status.cur.recv = 0;
2165+
// Get the ends statuses.
2166+
assert(info->status.cur.send == 0);
2167+
assert(info->status.cur.recv == 0);
2168+
_channelend *send = chan->ends->send;
2169+
while (send != NULL) {
2170+
if (send->interpid == interpid) {
2171+
info->status.cur.send = send->open ? 1 : -1;
2172+
}
2173+
2174+
if (send->open) {
2175+
info->status.all.nsend_only += 1;
2176+
}
2177+
else {
2178+
info->status.all.nsend_only_released += 1;
2179+
}
2180+
send = send->next;
21662181
}
2167-
else {
2168-
info->status.cur.recv = recv->open ? 1 : -1;
2182+
_channelend *recv = chan->ends->recv;
2183+
while (recv != NULL) {
2184+
if (recv->interpid == interpid) {
2185+
info->status.cur.recv = recv->open ? 1 : -1;
2186+
}
2187+
2188+
// XXX This is O(n*n). Why do we have 2 linked lists?
2189+
_channelend *send = chan->ends->send;
2190+
while (send != NULL) {
2191+
if (send->interpid == recv->interpid) {
2192+
break;
2193+
}
2194+
send = send->next;
2195+
}
2196+
if (send == NULL) {
2197+
if (recv->open) {
2198+
info->status.all.nrecv_only += 1;
2199+
}
2200+
else {
2201+
info->status.all.nrecv_only_released += 1;
2202+
}
2203+
}
2204+
else {
2205+
if (recv->open) {
2206+
if (send->open) {
2207+
info->status.all.nboth += 1;
2208+
info->status.all.nsend_only -= 1;
2209+
}
2210+
else {
2211+
info->status.all.nboth_recv_released += 1;
2212+
info->status.all.nsend_only_released -= 1;
2213+
}
2214+
}
2215+
else {
2216+
if (send->open) {
2217+
info->status.all.nboth_send_released += 1;
2218+
info->status.all.nsend_only -= 1;
2219+
}
2220+
else {
2221+
info->status.all.nboth_released += 1;
2222+
info->status.all.nsend_only_released -= 1;
2223+
}
2224+
}
2225+
}
2226+
recv = recv->next;
21692227
}
21702228

21712229
finally:
@@ -2183,6 +2241,23 @@ static PyStructSequence_Field channel_info_fields[] = {
21832241
{"closing", "send is closed, recv is non-empty"},
21842242
{"closed", "both ends are closed"},
21852243
{"count", "queued objects"},
2244+
2245+
{"num_interp_send", "interpreters bound to the send end"},
2246+
{"num_interp_send_released",
2247+
"interpreters bound to the send end and released"},
2248+
2249+
{"num_interp_recv", "interpreters bound to the send end"},
2250+
{"num_interp_recv_released",
2251+
"interpreters bound to the send end and released"},
2252+
2253+
{"num_interp_both", "interpreters bound to both ends"},
2254+
{"num_interp_both_released",
2255+
"interpreters bound to both ends and released_from_both"},
2256+
{"num_interp_both_send_released",
2257+
"interpreters bound to both ends and released_from_the send end"},
2258+
{"num_interp_both_recv_released",
2259+
"interpreters bound to both ends and released_from_the recv end"},
2260+
21862261
{"send_associated", "current interpreter is bound to the send end"},
21872262
{"send_released", "current interpreter *was* bound to the send end"},
21882263
{"recv_associated", "current interpreter is bound to the recv end"},
@@ -2228,6 +2303,14 @@ new_channel_info(PyObject *mod, struct channel_info *info)
22282303
SET_BOOL(info->status.closed == -1);
22292304
SET_BOOL(info->status.closed == 1);
22302305
SET_COUNT(info->count);
2306+
SET_COUNT(info->status.all.nsend_only);
2307+
SET_COUNT(info->status.all.nsend_only_released);
2308+
SET_COUNT(info->status.all.nrecv_only);
2309+
SET_COUNT(info->status.all.nrecv_only_released);
2310+
SET_COUNT(info->status.all.nboth);
2311+
SET_COUNT(info->status.all.nboth_released);
2312+
SET_COUNT(info->status.all.nboth_send_released);
2313+
SET_COUNT(info->status.all.nboth_recv_released);
22312314
SET_BOOL(info->status.cur.send == 1);
22322315
SET_BOOL(info->status.cur.send == -1);
22332316
SET_BOOL(info->status.cur.recv == 1);

0 commit comments

Comments
 (0)