aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/src')
-rw-r--r--lib/kernel/src/application.erl24
-rw-r--r--lib/kernel/src/application_controller.erl48
-rw-r--r--lib/kernel/src/application_master.erl38
-rw-r--r--lib/kernel/src/inet.erl5
-rw-r--r--lib/kernel/src/kernel.appup.src12
5 files changed, 80 insertions, 47 deletions
diff --git a/lib/kernel/src/application.erl b/lib/kernel/src/application.erl
index 4e8ba1b78a..76a80553b0 100644
--- a/lib/kernel/src/application.erl
+++ b/lib/kernel/src/application.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -132,7 +132,7 @@ ensure_all_started(Application, Type) ->
{ok, Started} ->
{ok, lists:reverse(Started)};
{error, Reason, Started} ->
- [stop(App) || App <- Started],
+ _ = [stop(App) || App <- Started],
{error, Reason}
end.
@@ -285,16 +285,18 @@ info() ->
set_env(Application, Key, Val) ->
application_controller:set_env(Application, Key, Val).
--spec set_env(Application, Par, Val, Timeout) -> 'ok' when
+-spec set_env(Application, Par, Val, Opts) -> 'ok' when
Application :: atom(),
Par :: atom(),
Val :: term(),
- Timeout :: timeout().
+ Opts :: [{timeout, timeout()} | {persistent, boolean()}].
set_env(Application, Key, Val, infinity) ->
- application_controller:set_env(Application, Key, Val, infinity);
+ set_env(Application, Key, Val, [{timeout, infinity}]);
set_env(Application, Key, Val, Timeout) when is_integer(Timeout), Timeout>=0 ->
- application_controller:set_env(Application, Key, Val, Timeout).
+ set_env(Application, Key, Val, [{timeout, Timeout}]);
+set_env(Application, Key, Val, Opts) when is_list(Opts) ->
+ application_controller:set_env(Application, Key, Val, Opts).
-spec unset_env(Application, Par) -> 'ok' when
Application :: atom(),
@@ -303,15 +305,17 @@ set_env(Application, Key, Val, Timeout) when is_integer(Timeout), Timeout>=0 ->
unset_env(Application, Key) ->
application_controller:unset_env(Application, Key).
--spec unset_env(Application, Par, Timeout) -> 'ok' when
+-spec unset_env(Application, Par, Opts) -> 'ok' when
Application :: atom(),
Par :: atom(),
- Timeout :: timeout().
+ Opts :: [{timeout, timeout()} | {persistent, boolean()}].
unset_env(Application, Key, infinity) ->
- application_controller:unset_env(Application, Key, infinity);
+ unset_env(Application, Key, [{timeout, infinity}]);
unset_env(Application, Key, Timeout) when is_integer(Timeout), Timeout>=0 ->
- application_controller:unset_env(Application, Key, Timeout).
+ unset_env(Application, Key, [{timeout, Timeout}]);
+unset_env(Application, Key, Opts) when is_list(Opts) ->
+ application_controller:unset_env(Application, Key, Opts).
-spec get_env(Par) -> 'undefined' | {'ok', Val} when
Par :: atom(),
diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl
index 1a4473593a..ed13035104 100644
--- a/lib/kernel/src/application_controller.erl
+++ b/lib/kernel/src/application_controller.erl
@@ -461,14 +461,16 @@ permit_application(ApplName, Flag) ->
set_env(AppName, Key, Val) ->
- gen_server:call(?AC, {set_env, AppName, Key, Val}).
-set_env(AppName, Key, Val, Timeout) ->
- gen_server:call(?AC, {set_env, AppName, Key, Val}, Timeout).
+ gen_server:call(?AC, {set_env, AppName, Key, Val, []}).
+set_env(AppName, Key, Val, Opts) ->
+ Timeout = proplists:get_value(timeout, Opts, 5000),
+ gen_server:call(?AC, {set_env, AppName, Key, Val, Opts}, Timeout).
unset_env(AppName, Key) ->
- gen_server:call(?AC, {unset_env, AppName, Key}).
-unset_env(AppName, Key, Timeout) ->
- gen_server:call(?AC, {unset_env, AppName, Key}, Timeout).
+ gen_server:call(?AC, {unset_env, AppName, Key, []}).
+unset_env(AppName, Key, Opts) ->
+ Timeout = proplists:get_value(timeout, Opts, 5000),
+ gen_server:call(?AC, {unset_env, AppName, Key, Opts}, Timeout).
%%%-----------------------------------------------------------------
%%% call-back functions from gen_server
@@ -609,8 +611,8 @@ check_para([Else | _ParaList], AppName) ->
| {'change_application_data', _, _}
| {'permit_application', atom() | {'application',atom(),_},_}
| {'start_application', _, _}
- | {'unset_env', _, _}
- | {'set_env', _, _, _}.
+ | {'unset_env', _, _, _}
+ | {'set_env', _, _, _, _}.
-spec handle_call(calls(), {pid(), term()}, state()) ->
{'noreply', state()} | {'reply', term(), state()}.
@@ -858,13 +860,25 @@ handle_call(which_applications, _From, S) ->
end, S#state.running),
{reply, Reply, S};
-handle_call({set_env, AppName, Key, Val}, _From, S) ->
+handle_call({set_env, AppName, Key, Val, Opts}, _From, S) ->
ets:insert(ac_tab, {{env, AppName, Key}, Val}),
- {reply, ok, S};
+ case proplists:get_value(persistent, Opts, false) of
+ true ->
+ Fun = fun(Env) -> lists:keystore(Key, 1, Env, {Key, Val}) end,
+ {reply, ok, S#state{conf_data = change_app_env(S#state.conf_data, AppName, Fun)}};
+ false ->
+ {reply, ok, S}
+ end;
-handle_call({unset_env, AppName, Key}, _From, S) ->
+handle_call({unset_env, AppName, Key, Opts}, _From, S) ->
ets:delete(ac_tab, {env, AppName, Key}),
- {reply, ok, S};
+ case proplists:get_value(persistent, Opts, false) of
+ true ->
+ Fun = fun(Env) -> lists:keydelete(Key, 1, Env) end,
+ {reply, ok, S#state{conf_data = change_app_env(S#state.conf_data, AppName, Fun)}};
+ false ->
+ {reply, ok, S}
+ end;
handle_call({control_application, AppName}, {Pid, _Tag}, S) ->
Control = S#state.control,
@@ -1640,6 +1654,16 @@ merge_env([{App, AppEnv1} | T], Env2, Res) ->
merge_env([], Env2, Res) ->
Env2 ++ Res.
+%% Changes the environment for the given application
+%% If there is no application, an empty one is created
+change_app_env(Env, App, Fun) ->
+ case get_env_key(App, Env) of
+ {value, AppEnv, RestEnv} ->
+ [{App, Fun(AppEnv)} | RestEnv];
+ _ ->
+ [{App, Fun([])} | Env]
+ end.
+
%% Merges envs for an application. Env2 overrides Env1
merge_app_env(Env1, Env2) ->
merge_app_env(Env1, Env2, []).
diff --git a/lib/kernel/src/application_master.erl b/lib/kernel/src/application_master.erl
index 68f78c6eb8..bc15b5a7de 100644
--- a/lib/kernel/src/application_master.erl
+++ b/lib/kernel/src/application_master.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -27,7 +27,7 @@
-include("application_master.hrl").
--record(state, {child, appl_data, children = [], procs = 0, gleader}).
+-record(state, {child, appl_data, children = [], procs = 0, gleader, req=[]}).
%%-----------------------------------------------------------------
%% Func: start_link/1
@@ -205,22 +205,25 @@ terminate_loop(Child, State) ->
%%-----------------------------------------------------------------
%% The Application Master is linked to *all* processes in the group
-%% (application).
+%% (application).
%%-----------------------------------------------------------------
handle_msg({get_child, Tag, From}, State) ->
- From ! {Tag, get_child_i(State#state.child)},
- State;
+ get_child_i(State, Tag, From);
handle_msg({stop, Tag, From}, State) ->
catch terminate(normal, State),
From ! {Tag, ok},
exit(normal);
+handle_msg({child, Ref, GrandChild, Mod}, #state{req=Reqs0}=State) ->
+ {value, {_, Tag, From}, Reqs} = lists:keytake(Ref, 1, Reqs0),
+ From ! {Tag, {GrandChild, Mod}},
+ State#state{req=Reqs};
handle_msg(_, State) ->
State.
-
-terminate(Reason, State) ->
- terminate_child(State#state.child, State),
- kill_children(State#state.children),
+terminate(Reason, State = #state{child=Child, children=Children, req=Reqs}) ->
+ _ = [From ! {Tag, error} || {_, Tag, From} <- Reqs],
+ terminate_child(Child, State),
+ kill_children(Children),
exit(Reason).
@@ -342,8 +345,8 @@ start_supervisor(Type, M, A) ->
loop_it(Parent, Child, Mod, AppState) ->
receive
- {Parent, get_child} ->
- Parent ! {self(), Child, Mod},
+ {Parent, get_child, Ref} ->
+ Parent ! {child, Ref, Child, Mod},
loop_it(Parent, Child, Mod, AppState);
{Parent, terminate} ->
NewAppState = prep_stop(Mod, AppState),
@@ -382,10 +385,15 @@ prep_stop(Mod, AppState) ->
NewAppState
end.
-get_child_i(Child) ->
- Child ! {self(), get_child},
- receive
- {Child, GrandChild, Mod} -> {GrandChild, Mod}
+get_child_i(#state{child=Child, req=Reqs}=State, Tag, From) ->
+ Ref = erlang:make_ref(),
+ case erlang:is_process_alive(Child) of
+ true ->
+ Child ! {self(), get_child, Ref},
+ State#state{req=[{Ref, Tag, From}|Reqs]};
+ false ->
+ From ! {Tag, error},
+ State
end.
terminate_child_i(Child, State) ->
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index 792593246a..41d422d7d4 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -597,8 +597,7 @@ getservbyname(Name, Protocol) when is_atom(Name) ->
Error -> Error
end.
--spec ntoa(IpAddress) ->
- {ok, Address} | {error, einval} when
+-spec ntoa(IpAddress) -> Address | {error, einval} when
Address :: string(),
IpAddress :: ip_address().
ntoa(Addr) ->
diff --git a/lib/kernel/src/kernel.appup.src b/lib/kernel/src/kernel.appup.src
index b946c2d1af..f8f4cc1ec2 100644
--- a/lib/kernel/src/kernel.appup.src
+++ b/lib/kernel/src/kernel.appup.src
@@ -1,7 +1,7 @@
%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -16,12 +16,10 @@
%%
%% %CopyrightEnd%
{"%VSN%",
- %% Up from - max two major revisions back
+ %% Up from - max one major revision back
[{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
- {<<"2\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R16
- {<<"2\\.15(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R15
- %% Down to - max two major revisions back
+ {<<"2\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R16
+ %% Down to - max one major revision back
[{<<"3\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17
- {<<"2\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R16
- {<<"2\\.15(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R15
+ {<<"2\\.16(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R16
}.