File 3501-Add-application-get_supervisor-1.patch of Package erlang
From 26237d26a47416d1143218f98086b622cc9e19f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?= <jose.valim@dashbit.co>
Date: Mon, 30 May 2022 23:50:15 +0200
Subject: [PATCH] Add application:get_supervisor/1
It returns the Pid of the supervisor running at
the root of the given application.
This allows tools for introspection and debugging
to print supervision trees without relying on
private APIs.
---
lib/kernel/doc/src/application.xml | 10 ++++++++++
lib/kernel/src/application.erl | 16 +++++++++++++++-
lib/kernel/src/application_master.erl | 2 +-
lib/kernel/test/application_SUITE.erl | 10 ++++++++--
4 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/lib/kernel/doc/src/application.xml b/lib/kernel/doc/src/application.xml
index 2a807e62bb..d4d7810531 100644
--- a/lib/kernel/doc/src/application.xml
+++ b/lib/kernel/doc/src/application.xml
@@ -180,6 +180,16 @@
</desc>
</func>
+ <func>
+ <name name="get_supervisor" arity="1" since="OTP 25.1"/>
+ <fsummary>Get the supervisor of an application.</fsummary>
+ <desc>
+ <p>Returns the <c><anno>Pid</anno></c> of the supervisor running
+ at the root of <c><anno>Application</anno></c>.</p>
+ <p>If the specified application does not exist or does not
+ define a callback module, the function returns <c>undefined</c>.</p>
+ </desc>
+ </func>
<func>
<name name="load" arity="1" since=""/>
<name name="load" arity="2" since=""/>
diff --git a/lib/kernel/src/application.erl b/lib/kernel/src/application.erl
index 3eb87d73c7..3214d85944 100644
--- a/lib/kernel/src/application.erl
+++ b/lib/kernel/src/application.erl
@@ -28,7 +28,7 @@
-export([set_env/1, set_env/2, set_env/3, set_env/4, unset_env/2, unset_env/3]).
-export([get_env/1, get_env/2, get_env/3, get_all_env/0, get_all_env/1]).
-export([get_key/1, get_key/2, get_all_key/0, get_all_key/1]).
--export([get_application/0, get_application/1, info/0]).
+-export([get_application/0, get_application/1, get_supervisor/1, info/0]).
-export([start_type/0]).
-export_type([start_type/0]).
@@ -466,6 +466,20 @@ get_application(Pid) when is_pid(Pid) ->
get_application(Module) when is_atom(Module) ->
application_controller:get_application_module(Module).
+-spec get_supervisor(Application) -> 'undefined' | {'ok', Pid} when
+ Pid :: pid(),
+ Application :: atom().
+
+get_supervisor(Application) when is_atom(Application) ->
+ case application_controller:get_master(Application) of
+ undefined -> undefined;
+ Master ->
+ case application_master:get_child(Master) of
+ {Root, _App} -> {ok, Root};
+ error -> undefined
+ end
+ end.
+
-spec start_type() -> StartType | 'undefined' | 'local' when
StartType :: start_type().
diff --git a/lib/kernel/src/application_master.erl b/lib/kernel/src/application_master.erl
index 35c9db170e..880e36047d 100644
--- a/lib/kernel/src/application_master.erl
+++ b/lib/kernel/src/application_master.erl
@@ -75,7 +75,7 @@ call(AppMaster, Req) ->
AppMaster ! {Req, Tag, self()},
receive
{'DOWN', Ref, process, _, _Info} ->
- ok;
+ error;
{Tag, Res} ->
erlang:demonitor(Ref, [flush]),
Res
diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl
index 6817435576..88784cc1b7 100644
--- a/lib/kernel/test/application_SUITE.erl
+++ b/lib/kernel/test/application_SUITE.erl
@@ -30,7 +30,7 @@
otp_1586/1, otp_2078/1, otp_2012/1, otp_2718/1, otp_2973/1,
otp_3002/1, otp_3184/1, otp_4066/1, otp_4227/1, otp_5363/1,
otp_5606/1,
- start_phases/1, get_key/1, get_env/1,
+ start_phases/1, get_key/1, get_env/1, get_supervisor/1,
set_env/1, set_env_persistent/1, set_env_errors/1, optional_applications/1,
permit_false_start_local/1, permit_false_start_dist/1, script_start/1,
nodedown_start/1, init2973/0, loop2973/0, loop5606/1, otp_16504/1]).
@@ -58,7 +58,7 @@ all() ->
load_use_cache, ensure_started, {group, reported_bugs}, start_phases,
script_start, nodedown_start, permit_false_start_local,
permit_false_start_dist, get_key, get_env, ensure_all_started,
- set_env, set_env_persistent, set_env_errors,
+ set_env, set_env_persistent, set_env_errors, get_supervisor,
{group, distr_changed}, config_change, shutdown_func, shutdown_timeout,
shutdown_deadlock, config_relative_paths, optional_applications,
persistent_env, handle_many_config_files, format_log_1, format_log_2,
@@ -1652,6 +1652,12 @@ get_env(Conf) when is_list(Conf) ->
default = application:get_env(kernel, error_logger_xyz, default),
ok.
+get_supervisor(Conf) when is_list(Conf) ->
+ undefined = application:get_supervisor(stdlib),
+ {ok, Pid} = application:get_supervisor(kernel),
+ Pid = erlang:whereis(kernel_sup),
+ ok.
+
%%-----------------------------------------------------------------
%% Should be started in a CC view with:
%% erl -sname XXX -rsh ctrsh where XX not in [cp1, cp2, cp3]
--
2.35.3