aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/src/application_starter.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/src/application_starter.erl')
-rw-r--r--lib/kernel/src/application_starter.erl111
1 files changed, 111 insertions, 0 deletions
diff --git a/lib/kernel/src/application_starter.erl b/lib/kernel/src/application_starter.erl
new file mode 100644
index 0000000000..8d839e4662
--- /dev/null
+++ b/lib/kernel/src/application_starter.erl
@@ -0,0 +1,111 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. 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
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%% ----------------------------------------------------------------------
+%% Purpose : Starts applications in the phases defined in the .app file's
+%% start_phases key. If the application includes other applications
+%% these are also started according to their mod and
+%% start_phases-keys in their .app file.
+%% ----------------------------------------------------------------------
+
+-module(application_starter).
+
+-export([start/3]).
+
+%%%=============================================================================
+%%%=============================================================================
+%%%=============================================================================
+%%% start(Phases, Type, Applications) -> ok | {error, ErrorMessage}
+%%%
+%%% The applications are started by calling Module:start_phase(Phase, Type, Args)
+%%% where Module and is defined in the mod-key, Phase and Args are defined in
+%%% the start_phases-key.
+%%%=============================================================================
+%%%=============================================================================
+%%%=============================================================================
+start([], _Type, _Apps) ->
+ ok;
+start([{Phase,_PhaseArgs}|Phases], Type, Apps) ->
+ case start_apps(Phase, Type, Apps) of
+ {error, Error} ->
+ {error, Error};
+ _ ->
+ start(Phases, Type, Apps)
+ end.
+
+
+%%%=============================================================================
+%%% Start each application in the phase Phase.
+%%%=============================================================================
+start_apps(_Phase, _Type, []) ->
+ ok;
+start_apps(Phase, Type, [App | Apps]) ->
+ case catch run_start_phase(Phase, Type, App) of
+ {error, Error} ->
+ {error, Error};
+ _ ->
+ start_apps(Phase, Type, Apps)
+ end.
+
+
+%%%=============================================================================
+%%% If application_starter is used recursively, start also all the included
+%%% applications in the phase Phase.
+%%%=============================================================================
+run_start_phase(Phase, Type, App) ->
+ {ok,{Mod,Arg}} = application:get_key(App, mod),
+ case Mod of
+ application_starter ->
+ [StartMod, _StartArgs] = Arg,
+ run_the_phase(Phase, Type, App, StartMod),
+ {ok, IncApps} = application:get_key(App, included_applications),
+ start_apps(Phase, Type, IncApps);
+ _ ->
+ run_the_phase(Phase, Type, App, Mod)
+ end.
+
+
+%%%=============================================================================
+%%% Start the application only if the start phase is defined in the
+%%% start_phases-key.
+%%%=============================================================================
+run_the_phase(Phase, Type, App, Mod) ->
+ Start_phases = case application_controller:get_key(App, start_phases) of
+ {ok, undefined} ->
+ throw({error, {start_phases_undefined, App}});
+ {ok, Sp} ->
+ Sp
+ end,
+ case lists:keysearch(Phase, 1, Start_phases) of
+ false ->
+ ok;
+ {value, {Phase, PhaseArgs}} ->
+ case catch Mod:start_phase(Phase, Type, PhaseArgs) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ throw({error, {Reason,
+ {Mod, start_phase,
+ [Phase, Type, PhaseArgs]}}});
+ Other ->
+ throw({error, {bad_return_value,
+ {{Mod, start_phase,
+ [Phase, Type, PhaseArgs]},
+ Other}}})
+ end
+ end.