File 4521-Fix-delivery-of-distributed-spawn_reply-signals.patch of Package erlang
From f2fe1e8838819e8ae6ab2f57a0b4c423827c70c9 Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Thu, 19 May 2022 18:06:26 +0200
Subject: [PATCH 1/2] Fix delivery of distributed spawn_reply signals
A spawn_reply signal from a remote node could be delayed and delivered
after other signals from the newly spawned process.
When this bug trigger the connection to the node where the process was
spawned might be taken down and the following error message might be
logged:
Missing 'spawn_reply' signal from the node <RemoteNode> detected
by <Pid> on the node <LocalNode>. The node <RemoteNode>; probably
suffers from the bug with ticket id OTP-17737.
This bug only affects processes which has enabled off_heap
message_queue_data when also parallel reception of signals has been
automatically enabled.
This bug was introduced in OTP 25.0, ERTS version 13.0.
---
erts/emulator/beam/erl_proc_sig_queue.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c
index 61bc163420..814c3fdd52 100644
--- a/erts/emulator/beam/erl_proc_sig_queue.c
+++ b/erts/emulator/beam/erl_proc_sig_queue.c
@@ -2521,6 +2521,8 @@ erts_proc_sig_send_dist_spawn_reply(Eterm node,
ErlHeapFragment *hfrag;
ErlOffHeap *ohp;
ErtsMessage *mp;
+ Eterm ordered_from;
+ int force_flush;
ASSERT(is_atom(node));
@@ -2593,8 +2595,22 @@ erts_proc_sig_send_dist_spawn_reply(Eterm node,
ERL_MESSAGE_FROM(mp) = node;
ERL_MESSAGE_TOKEN(mp) = token_copy;
- if (!proc_queue_signal(NULL, am_spawn_service, to, (ErtsSignal *)mp, 0,
- ERTS_SIG_Q_OP_DIST_SPAWN_REPLY)) {
+ /*
+ * Sent from spawn-service at node, but we need to order this
+ * signal against signals sent from the spawned process, so
+ * we need to pass the pid of the spawned process as from
+ * parameter or flush if connection was lost...
+ */
+ if (is_external_pid(result)) {
+ force_flush = 0;
+ ordered_from = result;
+ }
+ else {
+ force_flush = result == am_noconnection;
+ ordered_from = am_spawn_service;
+ }
+ if (!proc_queue_signal(NULL, ordered_from, to, (ErtsSignal *)mp,
+ force_flush, ERTS_SIG_Q_OP_DIST_SPAWN_REPLY)) {
mp->next = NULL;
mp->data.attached = ERTS_MSG_COMBINED_HFRAG;
ERL_MESSAGE_TERM(mp) = msg;
--
2.35.3