File 3441-Adjustments-for-the-net_ticker_spawn_options-kernel-.patch of Package erlang

From 9c2648e7983285f7f61964e973b7bd8063d1d1bd Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Sat, 12 Feb 2022 22:19:17 +0100
Subject: [PATCH 1/3] Adjustments for the net_ticker_spawn_options kernel
 parameter

---
 erts/doc/src/alt_dist.xml                     | 28 ++++++++++--
 lib/kernel/doc/src/kernel_app.xml             | 45 ++++++++++++-------
 .../erl_uds_dist/src/erl_uds_dist.erl         | 16 +------
 .../gen_tcp_dist/src/gen_tcp_dist.erl         |  4 +-
 lib/kernel/src/dist_util.erl                  | 20 ++++++++-
 lib/kernel/src/inet_tcp_dist.erl              | 13 +-----
 lib/kernel/test/erl_distribution_SUITE.erl    | 43 ++++++++++++++----
 lib/ssl/src/inet_tls_dist.erl                 | 11 +----
 lib/ssl/src/ssl.app.src                       |  2 +-
 9 files changed, 116 insertions(+), 66 deletions(-)

diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml
index febfd8b130..c5ece5b456 100644
--- a/erts/doc/src/alt_dist.xml
+++ b/erts/doc/src/alt_dist.xml
@@ -314,8 +314,18 @@
 	    <c>accept_connection/5</c> should spawn a process that will
 	    perform the Erlang distribution handshake for the connection.
 	    If the handshake successfully completes it should continue to
-	    function as a connection supervisor. This process
-	    should preferably execute on <c>max</c> priority.
+	    function as a connection supervisor. This process should
+            preferably execute on <c>max</c> priority and should be linked
+            to the caller. The <c>dist_util:net_ticker_spawn_options()</c>
+            function can be called to get spawn options suitable for this process
+            which can be passed directly to
+            <seemfa marker="erts:erlang#spawn_opt/4"><c>erlang:spawn_opt/4</c></seemfa>.
+            <c>dist_util:net_ticker_spawn_options()</c> will by default return
+            <c>[link, {priority, max}]</c>, but allows the user to configure more
+            options using the
+            <seeapp marker="kernel:kernel_app#net_ticker_spawn_options"><c>net_ticker_spawn_options</c></seeapp>
+            kernel parameter. The process identifier of this process should be
+            returned.
 	  </p>
 	  <p>The arguments:</p>
 	  <taglist>
@@ -380,8 +390,18 @@
 	    <c>Node</c>. When connection has been established it should
 	    perform the Erlang distribution handshake for the connection.
 	    If the handshake successfully completes it should continue to
-	    function as a connection supervisor. This process
-	    should preferably execute on <c>max</c> priority.
+	    function as a connection supervisor. This process should
+            preferably execute on <c>max</c> priority and should be linked
+            to the caller. The <c>dist_util:net_ticker_spawn_options()</c>
+            function can be called to get spawn options suitable for this process
+            which can be passed directly to
+            <seemfa marker="erts:erlang#spawn_opt/4"><c>erlang:spawn_opt/4</c></seemfa>.
+            <c>dist_util:net_ticker_spawn_options()</c> will by default return
+            <c>[link, {priority, max}]</c>, but allows the user to configure more
+            options using the
+            <seeapp marker="kernel:kernel_app#net_ticker_spawn_options"><c>net_ticker_spawn_options</c></seeapp>
+            kernel parameter. The process identifier of this process should be
+            returned.
 	  </p>
 	  <p>The arguments:</p>
 	  <taglist>
diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml
index bc7ef2e973..905191202f 100644
--- a/lib/kernel/doc/src/kernel_app.xml
+++ b/lib/kernel/doc/src/kernel_app.xml
@@ -290,15 +290,6 @@
 	  other distributed Erlang nodes.
 	  See <seemfa marker="gen_tcp#connect/4"><c>gen_tcp:connect/4</c></seemfa>.</p>
       </item>
-      <tag><c>{net_ticker_spawn_options, Opts}</c></tag>
-      <item>
-        <marker id="net_ticker_spawn_options"></marker>
-        <p>Defines a list of extra spawn options for dist_util:con_loop processes.
-          When there is a large number of dist connections, setting up garbage collection
-          options can be helpful to reduce memory usage. Default is [link, {priority, max}],
-          and these two options cannot be changed.
-          See <seemfa marker="erts:erlang#spawn_opt/2"><c>erlang:spawn_opt/2</c></seemfa>.</p>
-      </item>
       <tag><c>inet_parse_error_log = silent</c></tag>
       <item>
         <p>If set, no log events are issued when erroneous lines are
@@ -325,6 +316,35 @@
           setup time, but rather each individual network operation during
           the connection setup and handshake.</p>
       </item>
+      <tag><marker id="net_ticker_spawn_options"/><c>net_ticker_spawn_options = Opts</c></tag>
+      <item>
+        <p>
+          Defines a list of extra spawn options for net ticker processes. There exist
+          one such process for each connection to another node. A net ticker process is
+          responsible for supervising the connection it is associated with. These
+          processes also execute the distribution handshake protocol when setting up
+          connections. When there is a large number of distribution connections,
+          setting up garbage collection options can be helpful to reduce memory usage.
+          Default is <c>[link, {priority, max}]</c>, and these two options cannot be
+          changed. The <c>monitor</c> and <c>{monitor, MonitorOpts}</c> options are
+          not allowed and will be dropped if present. See the documentation of the
+          <seemfa marker="erts:erlang#spawn_opt/4"><c>erlang:spawn_opt/4</c></seemfa>
+          BIF for information about valid options. If the <c>Opts</c> list is not
+          a proper list, or containing invalid options the setup of connections
+          will fail.
+        </p>
+        <p>
+          Note that the behavior described above is only true if the distribution
+          carrier protocol used is implemented as described in
+ 	  <seeguide marker="erts:alt_dist#distribution_module">ERTS
+	  User's Guide ➜ How to implement an Alternative Carrier
+	  for the Erlang Distribution ➜ Distribution Module</seeguide> without
+          further alterations. The implementer of the distribution carrier protocol
+          used, may have chosen to ignore the <c>net_ticker_spawn_options</c> parameter
+          or altered its behavior. Currently all distribution modules shipped with OTP
+          do, however, behave as described above.
+        </p>
+      </item>
       <tag><marker id="net_tickintensity"/><c>net_tickintensity = NetTickIntensity</c></tag>
       <item>
         <p><i>Net tick intensity</i> specifies how many ticks to send during a
diff --git a/lib/kernel/examples/erl_uds_dist/src/erl_uds_dist.erl b/lib/kernel/examples/erl_uds_dist/src/erl_uds_dist.erl
index e4ef56b606..d6310bdd19 100644
--- a/lib/kernel/examples/erl_uds_dist/src/erl_uds_dist.erl
+++ b/lib/kernel/examples/erl_uds_dist/src/erl_uds_dist.erl
@@ -432,7 +432,7 @@ accept_loop(Kernel, ListeningSocket) ->
 accept_connection(AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) ->
     spawn_opt(?MODULE, accept_supervisor,
               [self(), AcceptPid, DistCtrl, MyNode, Allowed, SetupTime],
-              net_ticker_spawn_options()).
+              dist_util:net_ticker_spawn_options()).
 
 accept_supervisor(Kernel, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) ->
     ?trace("~p~n", [{?MODULE, accept_connection, self()}]),
@@ -472,18 +472,6 @@ accept_supervisor(Kernel, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) ->
             dist_util:handshake_other_started(HSData)
     end.
 
-
-%% ---------------------------------------------------------------------
-%% Allow to set different spawn options for dist_util processes using
-%% the net_ticker_spawn_options configuration parameter. Default is
-%% [link, {priority, max}] and these two options cannot be changed.
-%% ---------------------------------------------------------------------
-net_ticker_spawn_options() ->
-    Opts = application:get_env(kernel, net_ticker_spawn_options, []),
-    Opts1 = [{priority, max} | proplists:delete(priority, Opts)],
-    [link | proplists:delete(link, Opts1)].
-
-
 %% ---------------------------------------------------------------------
 %% Define common values of the handshake data record, defined in
 %% kernel/include/dist_util.hrl
@@ -676,7 +664,7 @@ getopts(ListeningSocket, Options) ->
 setup(Node, Type, MyNode, _LongOrShortNames, SetupTime) ->
     spawn_opt(?MODULE, setup_supervisor,
 	      [self(), Node, Type, MyNode, SetupTime],
-              net_ticker_spawn_options()).
+              dist_util:net_ticker_spawn_options()).
 
 setup_supervisor(Kernel, Node, Type, MyNode, SetupTime) ->
     ?trace("~p~n", [{?MODULE, setup, self(), Node}]),
diff --git a/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl b/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl
index f73a622607..39fa664db7 100644
--- a/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl
+++ b/lib/kernel/examples/gen_tcp_dist/src/gen_tcp_dist.erl
@@ -183,7 +183,7 @@ flush_controller(Pid, Socket) ->
 accept_connection(AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) ->
     spawn_opt(?MODULE, do_accept,
 	      [self(), AcceptPid, DistCtrl, MyNode, Allowed, SetupTime],
-	      [link, {priority, max}]).
+	      dist_util:net_ticker_spawn_options()).
 
 do_accept(Kernel, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime) ->
     ?trace("~p~n",[{?MODULE, do_accept, self(), MyNode}]),
@@ -230,7 +230,7 @@ nodelay() ->
 setup(Node, Type, MyNode, LongOrShortNames,SetupTime) ->
     spawn_opt(?MODULE, do_setup, 
 	      [self(), Node, Type, MyNode, LongOrShortNames, SetupTime],
-	      [link, {priority, max}]).
+	      dist_util:net_ticker_spawn_options()).
 
 do_setup(Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
     ?trace("~p~n",[{?MODULE, do_setup, self(), Node}]),
diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl
index 832fd2d485..66540478cb 100644
--- a/lib/kernel/src/dist_util.erl
+++ b/lib/kernel/src/dist_util.erl
@@ -31,7 +31,8 @@
 	 start_timer/1, setup_timer/2, 
 	 reset_timer/1, cancel_timer/1,
          is_node_name/1, split_node/1, is_allowed/2,
-	 shutdown/3, shutdown/4]).
+	 shutdown/3, shutdown/4,
+         net_ticker_spawn_options/0]).
 
 -import(error_logger,[error_msg/2]).
 
@@ -1269,3 +1270,20 @@ cancel_timer(Timer) ->
     unlink(Timer),
     exit(Timer, shutdown).
 
+net_ticker_spawn_options() ->
+    Opts = application:get_env(kernel, net_ticker_spawn_options, []),
+    [link, {priority, max} | cleanup_net_ticker_spawn_options(Opts)].
+
+cleanup_net_ticker_spawn_options([]) ->
+    [];
+cleanup_net_ticker_spawn_options([link|Opts]) ->
+    cleanup_net_ticker_spawn_options(Opts);
+cleanup_net_ticker_spawn_options([{priority, _}|Opts]) ->
+    cleanup_net_ticker_spawn_options(Opts);
+cleanup_net_ticker_spawn_options([monitor|Opts]) ->
+    cleanup_net_ticker_spawn_options(Opts);
+cleanup_net_ticker_spawn_options([{monitor, _}|Opts]) ->
+    cleanup_net_ticker_spawn_options(Opts);
+cleanup_net_ticker_spawn_options([Opt|Opts]) ->
+    [Opt|cleanup_net_ticker_spawn_options(Opts)].
+
diff --git a/lib/kernel/src/inet_tcp_dist.erl b/lib/kernel/src/inet_tcp_dist.erl
index 621445923d..0102c5c677 100644
--- a/lib/kernel/src/inet_tcp_dist.erl
+++ b/lib/kernel/src/inet_tcp_dist.erl
@@ -208,7 +208,7 @@ accept_connection(AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
 gen_accept_connection(Driver, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
     spawn_opt(?MODULE, do_accept,
 	      [Driver, self(), AcceptPid, Socket, MyNode, Allowed, SetupTime],
-	      net_ticker_spawn_options()).
+	      dist_util:net_ticker_spawn_options()).
 
 do_accept(Driver, Kernel, AcceptPid, Socket, MyNode, Allowed, SetupTime) ->
     receive
@@ -274,15 +274,6 @@ nodelay() ->
 	    {nodelay, true}
     end.
 
-
-% we may want different spawn options for dist_util processes
-
-net_ticker_spawn_options() ->
-    Opts = application:get_env(kernel, net_ticker_spawn_options, []),
-    Opts1 = [{priority, max} | proplists:delete(priority, Opts)],
-    [link | proplists:delete(link, Opts1)].
-
-
 %% ------------------------------------------------------------
 %% Get remote information about a Socket.
 %% ------------------------------------------------------------
@@ -312,7 +303,7 @@ setup(Node, Type, MyNode, LongOrShortNames,SetupTime) ->
 gen_setup(Driver, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
     spawn_opt(?MODULE, do_setup, 
 	      [Driver, self(), Node, Type, MyNode, LongOrShortNames, SetupTime],
-	      net_ticker_spawn_options()).
+	      dist_util:net_ticker_spawn_options()).
 
 do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
     ?trace("~p~n",[{inet_tcp_dist,self(),setup,Node}]),
diff --git a/lib/kernel/test/erl_distribution_SUITE.erl b/lib/kernel/test/erl_distribution_SUITE.erl
index 8ec5e67abf..098af198db 100644
--- a/lib/kernel/test/erl_distribution_SUITE.erl
+++ b/lib/kernel/test/erl_distribution_SUITE.erl
@@ -1094,6 +1094,9 @@ get_socket_priorities() ->
 
 %% check net_ticker_spawn_options
 net_ticker_spawn_options(Config) when is_list(Config) ->
+    run_dist_configs(fun net_ticker_spawn_options/2, Config).
+
+net_ticker_spawn_options(DCfg, Config) when is_list(Config) ->
     FullsweepString0 = "[{fullsweep_after,0}]",
     FullsweepString =
         case os:cmd("echo [{a,1}]") of
@@ -1107,16 +1110,16 @@ net_ticker_spawn_options(Config) when is_list(Config) ->
         "-hidden "
         "-kernel net_ticker_spawn_options "++FullsweepString,
     {ok,Node1} =
-        start_node("", net_ticker_spawn_options_1, InetDistOptions),
+        start_node(DCfg, net_ticker_spawn_options_1, InetDistOptions),
     {ok,Node2} =
-        start_node("", net_ticker_spawn_options_2, InetDistOptions),
+        start_node(DCfg, net_ticker_spawn_options_2, InetDistOptions),
     %%
     pong =
-        rpc:call(Node1, net_adm, ping, [Node2]),
+        erpc:call(Node1, net_adm, ping, [Node2]),
     FullsweepOptionNode1 =
-        rpc:call(Node1, ?MODULE, get_net_ticker_fullsweep_option, [Node2]),
+        erpc:call(Node1, ?MODULE, get_net_ticker_fullsweep_option, [Node2]),
     FullsweepOptionNode2 =
-        rpc:call(Node2, ?MODULE, get_net_ticker_fullsweep_option, [Node1]),
+        erpc:call(Node2, ?MODULE, get_net_ticker_fullsweep_option, [Node1]),
     io:format("FullsweepOptionNode1 = ~p", [FullsweepOptionNode1]),
     io:format("FullsweepOptionNode2 = ~p", [FullsweepOptionNode2]),
     0 = FullsweepOptionNode1,
@@ -1127,9 +1130,33 @@ net_ticker_spawn_options(Config) when is_list(Config) ->
     ok.
 
 get_net_ticker_fullsweep_option(Node) ->
-    Port = proplists:get_value(Node, erlang:system_info(dist_ctrl)),
-    {links, [DistUtilPid, _NetKernelPid]} = erlang:port_info(Port, links),
-    {garbage_collection, GCOpts} = erlang:process_info(DistUtilPid, garbage_collection),
+    Links = case proplists:get_value(Node, erlang:system_info(dist_ctrl)) of
+                DistCtrl when is_port(DistCtrl) ->
+                    {links, Ls} = erlang:port_info(DistCtrl, links),
+                    Ls;
+                DistCtrl when is_pid(DistCtrl) ->
+                    {links, Ls} = process_info(DistCtrl, links),
+                    Ls
+            end,
+    Ticker = try
+                 lists:foreach(
+                   fun (Pid) when is_pid(Pid) ->
+                           {current_stacktrace, Stk}
+                               = process_info(Pid, current_stacktrace),
+                           lists:foreach(
+                             fun ({dist_util, con_loop, _, _}) ->
+                                     throw(Pid);
+                                 (_) ->
+                                     ok
+                             end, Stk);
+                       (_) ->
+                           ok
+                   end, Links),
+                 error(no_ticker_found)
+             catch
+                 throw:Pid when is_pid(Pid) -> Pid
+             end,
+    {garbage_collection, GCOpts} = erlang:process_info(Ticker, garbage_collection),
     proplists:get_value(fullsweep_after, GCOpts).
 
 
diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl
index a19f0f2544..7e01ae4f71 100644
--- a/lib/ssl/src/inet_tls_dist.erl
+++ b/lib/ssl/src/inet_tls_dist.erl
@@ -440,7 +440,7 @@ gen_accept_connection(
                   Driver, AcceptPid, DistCtrl,
                   MyNode, Allowed, SetupTime, Kernel)
         end,
-        net_ticker_spawn_options())).
+        dist_util:net_ticker_spawn_options())).
 
 do_accept(
   _Driver, AcceptPid, DistCtrl, MyNode, Allowed, SetupTime, Kernel) ->
@@ -539,7 +539,7 @@ gen_setup(Driver, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
     Kernel = self(),
     monitor_pid(
       spawn_opt(setup_fun(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime),
-                net_ticker_spawn_options())).
+                dist_util:net_ticker_spawn_options())).
 
 -spec setup_fun(_,_,_,_,_,_,_) -> fun(() -> no_return()).
 setup_fun(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) ->
@@ -807,13 +807,6 @@ nodelay() ->
     end.
 
 
-% we may want different spawn options for dist_util processes
-
-net_ticker_spawn_options() ->
-    Opts = application:get_env(kernel, net_ticker_spawn_options, []),
-    Opts1 = [{priority, max} | proplists:delete(priority, Opts)],
-    [link | proplists:delete(link, Opts1)].
-
 get_ssl_options(Type) ->
     try ets:lookup(ssl_dist_opts, Type) of
         [{Type, Opts0}] ->
-- 
2.34.1

openSUSE Build Service is sponsored by