fix(v4.0.0): a waiting node goes on passing on and paying; KILL is not held by a stuck node
Found in the five-node test, each with a check that failed first: - A node with answers it could not give to two stuck senders began no text at all. It now holds back only text from a sender whose own answer is still with it. - KILL waited to tell a stuck node, and a typed line that broke it left the nodes after it untold. GONE is put with the messages waiting, as how text ended is, and goes when it can. - So that 'tell, then wait' still works, AWAIT does what (IDLE) does but for beginning text: it looks through the messages waiting, offers what is to be passed on and what is owed, and sleeps in the wait. A waiting node no longer keeps back what passes through it. - A node in the wait with an offer on a port that turns out to have nothing on it is woken and told so (which port: 2 * V4_PORTS + k); no error is raised on it. (GATE) makes it error 18; (IDLE) and AWAIT let the message go. Before, removing a node raised 'No one on that port' on the unrelated text of a neighbour that had something queued for it. make -C v4 test and sanitize at both widths, hosted-check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
353783726d
commit
ec817a8264
+14
-2
@@ -243,6 +243,14 @@ int v4_node_offer_taken(v4_node *n, unsigned k)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int v4_node_offer_gone(v4_node *n, unsigned k)
|
||||
{
|
||||
if (n->error_reg < 0 || n->fault_vector < 0 || n->stopped) return 0;
|
||||
if (!v4_node_in_wait(n) || k >= V4_PORTS || !(n->offers & (1u << k))) return 0;
|
||||
v4_node_port_give(n, 2u * V4_PORTS + k, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int v4_node_offer_as_write(v4_node *n)
|
||||
{
|
||||
unsigned k;
|
||||
@@ -280,8 +288,12 @@ unsigned v4_node_words_since_look(const v4_node *n)
|
||||
int v4_node_port_gone(v4_node *n, v4_cell code)
|
||||
{
|
||||
if (code == 0 || n->error_reg < 0 || n->fault_vector < 0 || n->stopped) return 0;
|
||||
if (n->asking) { n->asking = 0; if (n->offer_asked) { n->offer_asked = 0; n->reading = 0; n->waiting = 0; n->offers = 0; } }
|
||||
else if (v4_node_in_wait(n) && n->offers != 0) { n->reading = 0; n->waiting = 0; n->offers = 0; }
|
||||
if (n->asking && n->offer_asked) { /* what it wrote was an offer: it is told, not faulted */
|
||||
n->asking = 0; n->offer_asked = 0;
|
||||
v4_node_port_give(n, 2u * V4_PORTS + n->ask_port, 0);
|
||||
return 1;
|
||||
}
|
||||
if (n->asking) n->asking = 0;
|
||||
else if (n->reading && !n->given && n->read_port != V4_PORT_ANY) n->reading = 0;
|
||||
else return 0;
|
||||
v4_node_store(n, n->error_reg, code); /* raises it: P is the node's handler now */
|
||||
|
||||
Reference in New Issue
Block a user