diff options
Diffstat (limited to 'lib/cosEvent/src/cosEventApp.erl')
-rw-r--r-- | lib/cosEvent/src/cosEventApp.erl | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/lib/cosEvent/src/cosEventApp.erl b/lib/cosEvent/src/cosEventApp.erl new file mode 100644 index 0000000000..084490f845 --- /dev/null +++ b/lib/cosEvent/src/cosEventApp.erl @@ -0,0 +1,290 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-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% +%% +%% +%%---------------------------------------------------------------------- +%% File : cosEventApp.erl +%% Description : +%% +%%---------------------------------------------------------------------- +-module(cosEventApp). + +%%--------------- INCLUDES ----------------------------------- +-include_lib("orber/include/corba.hrl"). +-include("cosEventApp.hrl"). + + +%%--------------- EXPORTS------------------------------------- +%% cosEvent API external +-export([start/0, stop/0, install/0, uninstall/0, start_channel/0, start_channel/1, + start_channel_link/0, start_channel_link/1, stop_channel/1]). + +%% cosEvent API internal +-export([create_link/3, get_option/2, type_check/3, disconnect/3, do_disconnect/3]). + +%% Application callbacks +-export([start/2, init/1, stop/1]). + +%%--------------- DEFINES ------------------------------------ +-define(IDL_MODULES, ['oe_CosEventComm', + 'oe_CosEventChannelAdmin', + 'oe_cosEventApp']). + +-define(SUPERVISOR_NAME, oe_cosEventSup). +-define(SUP_FLAG, {simple_one_for_one,50,10}). + +-define(SUP_SPEC(Name, Args), + ['CosEventChannel_EventChannel',Args, + [{sup_child, true}, {regname, {global, Name}}]]). +-define(SUP_CHILD, + {"oe_EventChild", + {cosEventApp,create_link, []}, + transient,100000,worker, + ['CosEventChannel_EventChannel']}). + + +%%-----------------------------------------------------------% +%% function : install +%% Arguments: - +%% Returns : ok | EXIT | EXCEPTION +%% Effect : Install necessary data in the IFR DB +%%------------------------------------------------------------ +install() -> + install_loop(?IDL_MODULES, []). + +install_loop([], _) -> + ok; +install_loop([H|T], Accum) -> + case catch H:'oe_register'() of + {'EXIT',{unregistered,App}} -> + ?write_ErrorMsg("Unable to register '~p'; application ~p not registered. +Trying to unregister ~p~n", [H,App,Accum]), + uninstall_loop(Accum, {exit, register}); + {'EXCEPTION',_} -> + ?write_ErrorMsg("Unable to register '~p'; propably already registered. +You are adviced to confirm this. +Trying to unregister ~p~n", [H,Accum]), + uninstall_loop(Accum, {exit, register}); + ok -> + install_loop(T, [H|Accum]); + _ -> + ?write_ErrorMsg("Unable to register '~p'; reason unknown. +Trying to unregister ~p~n", [H,Accum]), + uninstall_loop(Accum, {exit, register}) + end. + +%%-----------------------------------------------------------% +%% function : uninstall +%% Arguments: - +%% Returns : ok | EXIT | EXCEPTION +%% Effect : Remove data related to cosEvent from the IFR DB +%%------------------------------------------------------------ +uninstall() -> + uninstall_loop(lists:reverse(?IDL_MODULES), ok). + +uninstall_loop([],ok) -> + ok; +uninstall_loop([],{exit, register}) -> + exit({?MODULE, "oe_register failed"}); +uninstall_loop([],{exit, unregister}) -> + exit({?MODULE, "oe_unregister failed"}); +uninstall_loop([],{exit, both}) -> + exit({?MODULE, "oe_register and, for some of those already registered, oe_unregister failed"}); +uninstall_loop([H|T], Status) -> + case catch H:'oe_unregister'() of + ok -> + uninstall_loop(T, Status); + _ when Status == ok -> + ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered. +You are adviced to confirm this.~n",[H]), + uninstall_loop(T, {exit, unregister}); + _ -> + ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered. +You are adviced to confirm this.~n",[H]), + uninstall_loop(T, {exit, both}) + end. + +%%-----------------------------------------------------------% +%% function : start/stop +%% Arguments: +%% Returns : +%% Effect : Starts or stops the cosTime application. +%%------------------------------------------------------------ + +start() -> + application:start(cosEvent). +stop() -> + application:stop(cosEvent). + +%%-----------------------------------------------------------% +%% function : start +%% Arguments: Type - see module application +%% Arg - see module application +%% Returns : +%% Effect : Module callback for application +%%------------------------------------------------------------ + +start(_, _) -> + supervisor:start_link({local, ?SUPERVISOR_NAME}, cosEventApp, app_init). + + +%%-----------------------------------------------------------% +%% function : stop +%% Arguments: Arg - see module application +%% Returns : +%% Effect : Module callback for application +%%------------------------------------------------------------ + +stop(_) -> + ok. + +%%-----------------------------------------------------------% +%% function : start_channel +%% Arguments: - +%% Returns : +%% Effect : +%%------------------------------------------------------------ +start_channel() -> + start_channel(?DEFAULT_OPTIONS). + +start_channel(Options) when is_list(Options) -> + ServerOpts = get_option(?SERVER, Options), + 'oe_CosEventComm_Channel':oe_create([Options, ServerOpts], ServerOpts); +start_channel(Options) -> + orber:dbg("[~p] cosEventApp:start_channel(~p);~n" + "Options not correct.", [?LINE, Options], ?DEBUG_LEVEL), + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%%-----------------------------------------------------------% +%% function : start_channel +%% Arguments: - +%% Returns : +%% Effect : +%%------------------------------------------------------------ +start_channel_link() -> + start_channel_link(?DEFAULT_OPTIONS). + +start_channel_link(Options) when is_list(Options) -> + ServerOpts = get_option(?SERVER, Options), + 'oe_CosEventComm_Channel':oe_create_link([Options, ServerOpts], ServerOpts); +start_channel_link(Options) -> + orber:dbg("[~p] cosEventApp:start_channel_link(~p);~n" + "Options not correct.", [?LINE, Options], ?DEBUG_LEVEL), + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%%-----------------------------------------------------------% +%% function : stop_factory +%% Arguments: ChannelObj +%% Returns : +%% Effect : +%%------------------------------------------------------------ +stop_channel(ChannelObj) -> + corba:dispose(ChannelObj). + +%%-----------------------------------------------------------% +%% function : init +%% Arguments: +%% Returns : +%% Effect : +%%------------------------------------------------------------ + +%% Starting using create_factory/X +init(own_init) -> + {ok,{?SUP_FLAG, [?SUP_CHILD]}}; +%% When starting as an application. +init(app_init) -> + {ok,{?SUP_FLAG, [?SUP_CHILD]}}. + +%%-----------------------------------------------------------% +%% function : create_link +%% Arguments: Module - which Module to call +%% Env/ArgList - ordinary oe_create arguments. +%% Returns : +%% Exception: +%% Effect : Necessary since we want the supervisor to be a +%% 'simple_one_for_one'. Otherwise, using for example, +%% 'one_for_one', we have to call supervisor:delete_child +%% to remove the childs startspecification from the +%% supervisors internal state. +%%------------------------------------------------------------ +create_link(Module, Env, ArgList) -> + Module:oe_create_link(Env, ArgList). + + +%%-----------------------------------------------------------% +%% function : get_option +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +get_option(Key, OptionList) -> + case lists:keysearch(Key, 1, OptionList) of + {value,{Key,Value}} -> + Value; + _ -> + case lists:keysearch(Key, 1, ?DEFAULT_OPTIONS) of + {value,{Key,Value}} -> + Value; + _-> + {error, "Invalid option"} + end + end. + +%%-----------------------------------------------------------% +%% function : type_check +%% Arguments: Obj - objectrefernce to test. +%% Mod - Module which contains typeID/0. +%% Returns : 'ok' or raises exception. +%% Effect : +%%------------------------------------------------------------ +type_check(_Obj, _Mod, false) -> + ok; +type_check(Obj, Mod, _) -> + case catch corba_object:is_a(Obj, Mod:typeID()) of + true -> + ok; + _ -> + orber:dbg("[~p] cosEventApp:type_check(~p) failed; Should be ~p", + [?LINE, Obj, Mod], ?DEBUG_LEVEL), + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) + end. + +%%-----------------------------------------------------------% +%% function : disconnect +%% Arguments: Module - one of the interfaces defined in CosEventComm. +%% Function - the appropriate disconnect function. +%% Object - the client object reference. +%% Returns : ok +%% Exception: +%% Effect : If the process would try to diconnect itself it could +%% result in a deadlock. Hence, we spawn a new process to do it. +%%------------------------------------------------------------ +disconnect(Module, Function, Object) -> + spawn(cosEventApp, do_disconnect, [Module, Function, Object]), + ok. + +do_disconnect(Module, Function, Object) -> + catch Module:Function(Object), + ?DBG("Disconnect ~p:~p(..).~n", [Module, Function]), + ok. + +%%--------------- END OF MODULE ------------------------------ + + |