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

openSUSE Build Service is sponsored by