diff options
Diffstat (limited to 'lib/kernel/src/application_starter.erl')
-rw-r--r-- | lib/kernel/src/application_starter.erl | 111 |
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. |