1%%-------------------------------------------------------------------- 2%% 3%% %CopyrightBegin% 4%% 5%% Copyright Ericsson AB 2001-2016. All Rights Reserved. 6%% 7%% Licensed under the Apache License, Version 2.0 (the "License"); 8%% you may not use this file except in compliance with the License. 9%% You may obtain a copy of the License at 10%% 11%% http://www.apache.org/licenses/LICENSE-2.0 12%% 13%% Unless required by applicable law or agreed to in writing, software 14%% distributed under the License is distributed on an "AS IS" BASIS, 15%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16%% See the License for the specific language governing permissions and 17%% limitations under the License. 18%% 19%% %CopyrightEnd% 20%% 21%% 22%%---------------------------------------------------------------------- 23%% File : oe_CosEventComm_Channel_impl.erl 24%% Description : 25%% 26%%---------------------------------------------------------------------- 27-module(oe_CosEventComm_Channel_impl). 28 29%%---------------------------------------------------------------------- 30%% Include files 31%%---------------------------------------------------------------------- 32-include_lib("orber/include/corba.hrl"). 33-include("cosEventApp.hrl"). 34 35 36%%---------------------------------------------------------------------- 37%% External exports 38%%---------------------------------------------------------------------- 39%% Mandatory 40-export([init/1, 41 terminate/2, 42 code_change/3, 43 handle_info/2]). 44 45%% Exports from "CosEventChannelAdmin::EventChannel" 46-export([for_consumers/3, 47 for_suppliers/3, 48 destroy/3]). 49 50 51%%---------------------------------------------------------------------- 52%% Internal exports 53%%---------------------------------------------------------------------- 54%% Exports from "oe_CosEventComm::Event" 55-export([send/3, send_sync/4]). 56 57%%---------------------------------------------------------------------- 58%% Records 59%%---------------------------------------------------------------------- 60-record(state, {typecheck, pull_interval, maxevents, blocking, cadmins = [], 61 server_options}). 62 63%%---------------------------------------------------------------------- 64%% Macros 65%%---------------------------------------------------------------------- 66 67%%====================================================================== 68%% External functions 69%%====================================================================== 70%%---------------------------------------------------------------------- 71%% Function : init/1 72%% Returns : {ok, State} | 73%% {ok, State, Timeout} | 74%% ignore | 75%% {stop, Reason} 76%% Description: Initiates the server 77%%---------------------------------------------------------------------- 78init([Options, ServerOpts]) -> 79 process_flag(trap_exit, true), 80 PullI = cosEventApp:get_option(?PULL_INTERVAL, Options), 81 TC = cosEventApp:get_option(?TYPECHECK, Options), 82 Max = cosEventApp:get_option(?MAXEVENTS, Options), 83 Blocking = cosEventApp:get_option(?BLOCKING, Options), 84 {ok, #state{typecheck = TC, pull_interval = PullI, maxevents = Max, 85 blocking = Blocking, server_options = ServerOpts}}. 86 87%%---------------------------------------------------------------------- 88%% Function : terminate/2 89%% Returns : any (ignored by gen_server) 90%% Description: Shutdown the server 91%%---------------------------------------------------------------------- 92terminate(_Reason, _State) -> 93 ?DBG("Terminating ~p~n", [_Reason]), 94 ok. 95 96%%---------------------------------------------------------------------- 97%% Function : code_change/3 98%% Returns : {ok, NewState} 99%% Description: Convert process state when code is changed 100%%---------------------------------------------------------------------- 101code_change(_OldVsn, State, _Extra) -> 102 {ok, State}. 103 104%%---------------------------------------------------------------------% 105%% function : handle_info 106%% Arguments: 107%% Returns : {noreply, State} | 108%% {stop, Reason, State} 109%% Effect : Functions demanded by the gen_server module. 110%%---------------------------------------------------------------------- 111handle_info({'EXIT', Pid, _Reason}, #state{cadmins = CAdmins} = State) -> 112 ?DBG("Probably a child terminated with Reason: ~p~n", [_Reason]), 113 {noreply, State#state{cadmins = lists:keydelete(Pid, 2, CAdmins)}}; 114handle_info(_Info, State) -> 115 ?DBG("Unknown Info ~p~n", [_Info]), 116 {noreply, State}. 117 118 119%%---------------------------------------------------------------------- 120%% Function : for_consumers 121%% Arguments : 122%% Returns : 123%% Description: 124%%---------------------------------------------------------------------- 125for_consumers(_, _, #state{server_options = ServerOpts} = State) -> 126 case catch 'oe_CosEventComm_CAdmin':oe_create_link([self(), 127 State#state.typecheck, 128 State#state.maxevents, 129 ServerOpts], 130 [{sup_child, true}|ServerOpts]) of 131 {ok, Pid, AdminCo} -> 132 ?DBG("Created a new oe_CosEventComm_CAdmin.~n", []), 133 {reply, AdminCo, 134 State#state{cadmins = [{AdminCo, Pid}|State#state.cadmins]}}; 135 Other -> 136 orber:dbg("[~p] oe_CosEventComm_Channel:for_consumers(); Error: ~p", 137 [?LINE, Other], ?DEBUG_LEVEL), 138 corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) 139 end. 140 141%%---------------------------------------------------------------------- 142%% Function : for_suppliers 143%% Arguments : 144%% Returns : 145%% Description: 146%%---------------------------------------------------------------------- 147for_suppliers(OE_This, _, #state{server_options = ServerOpts} = State) -> 148 case catch 'CosEventChannelAdmin_SupplierAdmin':oe_create_link([OE_This, self(), 149 State#state.typecheck, 150 State#state.pull_interval, 151 ServerOpts], 152 [{sup_child, true}|ServerOpts]) of 153 {ok, _Pid, AdminSu} -> 154 ?DBG("Created a new CosEventChannelAdmin_SupplierAdmin.~n", []), 155 {reply, AdminSu, State}; 156 Other -> 157 orber:dbg("[~p] oe_CosEventComm_Channel:for_suppliers();~nError: ~p", 158 [?LINE, Other], ?DEBUG_LEVEL), 159 corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) 160 end. 161 162%%---------------------------------------------------------------------- 163%% Function : destroy 164%% Arguments : 165%% Returns : 166%% Description: 167%%---------------------------------------------------------------------- 168destroy(_, _, State) -> 169 ?DBG("Destroy invoked.", []), 170 {stop, normal, ok, State}. 171 172%%---------------------------------------------------------------------- 173%% Function : send 174%% Arguments : 175%% Returns : 176%% Description: 177%%---------------------------------------------------------------------- 178send(_OE_This, #state{cadmins = CAdmins} = State, Any) -> 179 ?DBG("Received Event ~p~n", [Any]), 180 case send_helper(CAdmins, Any, [], false) of 181 ok -> 182 ?DBG("Received Event and forwarded it successfully.~n", []), 183 {noreply, State}; 184 {error, Dropped} -> 185 ?DBG("Received Event but forward failed for: ~p~n", [Dropped]), 186 RemainingAdmins = delete_cadmin(Dropped, CAdmins), 187 {noreply, State#state{cadmins = RemainingAdmins}} 188 end. 189 190%%---------------------------------------------------------------------- 191%% Function : send_sync 192%% Arguments : 193%% Returns : 194%% Description: 195%%---------------------------------------------------------------------- 196send_sync(_OE_This, OE_From, #state{cadmins = CAdmins, blocking = BL} = State, Any) -> 197 ?DBG("Received Event ~p~n", [Any]), 198 corba:reply(OE_From, ok), 199 case send_helper(CAdmins, Any, [], BL) of 200 ok -> 201 ?DBG("Received Event and forwarded (sync) it successfully.~n", []), 202 {reply, ok, State}; 203 {error, Dropped} -> 204 ?DBG("Received Event but forward (sync) failed for: ~p~n", [Dropped]), 205 RemainingAdmins = delete_cadmin(Dropped, CAdmins), 206 {reply, ok, State#state{cadmins = RemainingAdmins}} 207 end. 208 209 210%%====================================================================== 211%% Internal functions 212%%====================================================================== 213send_helper([], _, [], _) -> 214 ok; 215send_helper([], _, Dropped, _) -> 216 {error, Dropped}; 217send_helper([{ObjRef, Pid}|T], Event, Dropped, false) -> 218 case catch 'oe_CosEventComm_CAdmin':send(ObjRef, Event) of 219 ok -> 220 send_helper(T, Event, Dropped, false); 221 What -> 222 orber:dbg("[~p] oe_CosEventComm_Channel:send_helper(~p, ~p);~n" 223 "Bad return value ~p. Closing connection.", 224 [?LINE, ObjRef, Event, What], ?DEBUG_LEVEL), 225 send_helper(T, Event, [{ObjRef, Pid}|Dropped], false) 226 end; 227send_helper([{ObjRef, Pid}|T], Event, Dropped, Sync) -> 228 case catch 'oe_CosEventComm_CAdmin':send_sync(ObjRef, Event) of 229 ok -> 230 send_helper(T, Event, Dropped, Sync); 231 What -> 232 orber:dbg("[~p] oe_CosEventComm_Channel:send_helper(~p, ~p);~n" 233 "Bad return value ~p. Closing connection.", 234 [?LINE, ObjRef, Event, What], ?DEBUG_LEVEL), 235 send_helper(T, Event, [{ObjRef, Pid}|Dropped], Sync) 236 end. 237 238 239delete_cadmin([], RemainingAdmins) -> 240 RemainingAdmins; 241delete_cadmin([{_,Pid}|T], CAdmins) -> 242 Rest = lists:keydelete(Pid, 2, CAdmins), 243 delete_cadmin(T, Rest). 244 245%%====================================================================== 246%% END OF MODULE 247%%====================================================================== 248