File 5392-Support-remote-parent-in-process_info-_-parent.patch of Package erlang
From df95635e96ae57f351a77924ea1f106bdae4153f Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Tue, 22 Mar 2022 02:53:33 +0100
Subject: [PATCH 2/2] Support remote parent in process_info(_, parent)
---
erts/doc/src/erlang.xml | 6 +++---
erts/emulator/beam/break.c | 3 ++-
erts/emulator/beam/erl_bif_info.c | 12 +++++++++++-
erts/emulator/beam/erl_gc.c | 9 +++++++++
erts/emulator/beam/erl_process.c | 21 ++++++++++++++++-----
erts/emulator/test/process_SUITE.erl | 20 +++++++++++++++++++-
6 files changed, 60 insertions(+), 11 deletions(-)
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index f6ed80fd63..fffe07e838 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -6672,9 +6672,9 @@ receive_replies(ReqId, N, Acc) ->
<item>
<p><c><anno>Pid</anno></c> is the identifier
of the parent process, the one that spawned current
- process. When the process does not have a local parent
- (e.g. <c>init</c>, or process is spawned remotely),
- <c>undefined</c> is returned.</p>
+ process. When the process does not have a parent
+ <c>undefined</c> is returned. Only the initial process
+ (<c>init</c>) on a node lacks a parent, though.</p>
</item>
<tag><c>{priority, <anno>Level</anno>}</c></tag>
<item>
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index e3a43e14f0..62b921c127 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -307,7 +307,8 @@ print_process_info(fmtfn_t to, void *to_arg, Process *p, ErtsProcLocks orig_lock
(Uint)p->current->arity);
}
- erts_print(to, to_arg, "Spawned by: %T\n", p->parent);
+ erts_print(to, to_arg, "Spawned by: %T\n",
+ p->parent == am_undefined ? NIL : p->parent);
if (locks & ERTS_PROC_LOCK_MAIN) {
erts_proc_lock(p, ERTS_PROC_LOCK_MSGQ);
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index b671b1315c..02660247cd 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -2030,7 +2030,17 @@ process_info_aux(Process *c_p,
break;
case ERTS_PI_IX_PARENT:
- res = rp->parent == NIL ? am_undefined : rp->parent;
+ if (is_immed(rp->parent)) {
+ ASSERT(is_internal_pid(rp->parent) || rp->parent == am_undefined);
+ res = rp->parent;
+ }
+ else {
+ Uint sz;
+ ASSERT(is_external_pid(rp->parent));
+ sz = size_object(rp->parent);
+ hp = erts_produce_heap(hfact, sz, reserve_size);
+ res = copy_struct(rp->parent, sz, &hp, hfact->off_heap);
+ }
break;
case ERTS_PI_IX_MAGIC_REF: {
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 20d55942e5..e35a4e2d46 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -2603,6 +2603,14 @@ setup_rootset(Process *p, Eterm *objv, int nobj, Rootset *rootset)
n++;
}
+ ASSERT(p->parent == am_undefined
+ || is_pid(follow_moved(p->parent, (Eterm) 0)));
+ if (is_not_immed(p->parent)) {
+ roots[n].v = &p->parent;
+ roots[n].sz = 1;
+ n++;
+ }
+
/*
* The process may be garbage-collected while it is terminating.
* fvalue contains the EXIT reason.
@@ -3425,6 +3433,7 @@ offset_one_rootset(Process *p, Sint heap_offs, Sint stack_offs,
offset_heap_ptr(&p->dt_utag, 1, offs, area, area_size);
#endif
offset_heap_ptr(&p->group_leader, 1, offs, area, area_size);
+ offset_heap_ptr(&p->parent, 1, offs, area, area_size);
offset_mqueue(p, offs, area, area_size);
offset_heap_ptr(p->stop, (STACK_START(p) - p->stop), offs, area, area_size);
offset_nstack(p, offs, area, area_size);
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index c75f67c0d7..8f95ac78f8 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -12299,9 +12299,20 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
DT_UTAG(p) = NIL;
DT_UTAG_FLAGS(p) = 0;
#endif
- p->parent = (!parent || parent->common.id == ERTS_INVALID_PID
- ? NIL
- : parent->common.id);
+
+ if (parent_id == ERTS_INVALID_PID) {
+ p->parent = am_undefined;
+ }
+ else if (is_internal_pid(parent_id)) {
+ p->parent = parent_id;
+ }
+ else {
+ Eterm sz, *hp;
+ ASSERT(is_external_pid(parent_id));
+ sz = size_object(parent_id);
+ hp = HAlloc(p, sz);
+ p->parent = copy_struct(parent_id, sz, &hp, &MSO(p));
+ }
INIT_HOLE_CHECK(p);
#ifdef DEBUG
@@ -12820,7 +12831,7 @@ void erts_init_empty_process(Process *p)
p->def_arg_reg[4] = 0;
p->def_arg_reg[5] = 0;
- p->parent = NIL;
+ p->parent = am_undefined;
p->static_flags = 0;
p->common.u.alive.started_interval = 0;
@@ -12875,7 +12886,7 @@ erts_debug_verify_clean_empty_process(Process* p)
ASSERT(p->i == NULL);
ASSERT(p->current == NULL);
- ASSERT(p->parent == NIL);
+ ASSERT(p->parent == am_undefined);
ASSERT(p->sig_inq.first == NULL);
ASSERT(p->sig_inq.len == 0);
--
2.34.1