aboutsummaryrefslogtreecommitdiffstats
path: root/lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl')
-rw-r--r--lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl304
1 files changed, 304 insertions, 0 deletions
diff --git a/lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl b/lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl
new file mode 100644
index 0000000000..5885691e87
--- /dev/null
+++ b/lib/cosTime/src/CosTimerEvent_TimerEventHandler_impl.erl
@@ -0,0 +1,304 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-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 : CosTimerEvent_TimerEventHandler_impl.erl
+%% Purpose :
+%%----------------------------------------------------------------------
+
+-module('CosTimerEvent_TimerEventHandler_impl').
+
+%%--------------- INCLUDES -----------------------------------
+-include("cosTimeApp.hrl").
+
+
+%%--------------- EXPORTS ------------------------------------
+%%--------------- External -----------------------------------
+%% Attributes (external)
+-export(['_get_status'/2]).
+%% Interface functions
+-export([time_set/2, set_timer/4]).
+-export([cancel_timer/2, set_data/3]).
+
+%%--------------- gen_server specific exports ----------------
+-export([handle_info/2, code_change/3]).
+-export([init/1, terminate/2]).
+
+
+%% Data structures
+-record(state, {parent,
+ parentPid,
+ event,
+ status = 'ESTimeCleared',
+ timer,
+ time,
+ timeObj,
+ myType,
+ pushConsumer,
+ uto}).
+%% Data structures constructors
+-define(get_InitState(P,PP,E,PC,TO),
+ #state{parent=P,
+ parentPid=PP,
+ event=E,
+ pushConsumer=PC,
+ timeObj=TO}).
+
+%% Data structures selectors
+-define(get_Status(S), S#state.status).
+-define(get_ParentPid(S), S#state.parentPid).
+-define(get_Parent(S), S#state.parent).
+-define(get_Event(S), S#state.event).
+-define(get_Timer(S), S#state.timer).
+-define(get_Time(S), S#state.time).
+-define(get_TimeObj(S), S#state.timeObj).
+-define(get_MyType(S), S#state.myType).
+-define(get_PushConsumer(S), S#state.pushConsumer).
+-define(get_Uto(S), S#state.uto).
+
+%% Data structures modifiers
+-define(set_Status(S,V), S#state{status=V}).
+-define(set_ParentPid(S,PP), S#state{parentPid=PP}).
+-define(set_Parent(S,P), S#state{parent=P}).
+-define(set_Event(S,E), S#state{event=E}).
+-define(set_Timer(S,T), S#state{timer=T}).
+-define(set_Time(S,T), S#state{time=T}).
+-define(set_MyType(S,Ty), S#state{myType=Ty}).
+-define(set_PushConsumer(S,P), S#state{pushConsumer=P}).
+-define(set_Uto(S,U,Type), S#state{uto=U, myType=Type}).
+-define(set_TimeData(S,U,Ty,Ti),S#state{uto=U, myType=Ty, time=Ti}).
+
+%% MISC
+-define(not_Cancelled(S), S#state.status =/= 'ESTimeCleared').
+-define(is_TimeSet(S), S#state.status == 'ESTimeSet').
+-define(is_UtoSet(S), S#state.uto =/= undefined).
+-define(is_NotAbsolute(S), S#state.myType =/= 'TTAbsolute').
+
+%%-----------------------------------------------------------%
+%% function : handle_info, code_change
+%% Arguments:
+%% Returns :
+%% Effect : Functions demanded by the gen_server module.
+%%------------------------------------------------------------
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+handle_info(Info, State) ->
+ ?debug_print("INFO: ~p~n", [Info]),
+ case Info of
+ {'EXIT', Pid, _Reason} when Pid == ?get_ParentPid(State) ->
+ ?debug_print("PARENT TERMINATED with reason: ~p~n",[_Reason]),
+ {noreply, State};
+ oe_event when ?not_Cancelled(State) ->
+ %% Push event
+ case catch 'CosEventComm_PushConsumer':push(?get_PushConsumer(State),
+ ?get_Event(State)) of
+ ok ->
+ ?debug_print("PUSHED: ~p~n", [?get_Event(State)]),
+ {noreply, ?set_Status(State, 'ESTriggered')};
+ _Other->
+ ?debug_print("FAILED PUSH: ~p ~p~n", [?get_Event(State), _Other]),
+ {noreply, ?set_Status(State, 'ESFailedTrigger')}
+ end;
+ oe_periodic_event when ?not_Cancelled(State) ->
+ %% Push event
+ catch 'CosEventComm_PushConsumer':push(?get_PushConsumer(State),
+ ?get_Event(State)),
+ {noreply, State};
+ _ ->
+ {noreply, State}
+ end.
+
+%%----------------------------------------------------------%
+%% function : init, terminate
+%% Arguments:
+%%-----------------------------------------------------------
+
+init([Parent, ParentPid, PushConsumer, Event, TimeObj]) ->
+ process_flag(trap_exit, true),
+ {ok, ?get_InitState(Parent, ParentPid, Event, PushConsumer, TimeObj)}.
+
+terminate(_Reason, State) ->
+ clear_timer(State),
+ ok.
+
+%%-----------------------------------------------------------
+%%------------------------ attributes -----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% Attribute: '_get_status'
+%% Type : readonly
+%% Returns : 'ESTimeSet' | 'ESTimeCleared' | 'ESTriggered' |
+%% 'ESFailedTrigger'
+%%-----------------------------------------------------------
+'_get_status'(_OE_THIS, State) ->
+ {reply, ?get_Status(State), State}.
+
+%%-----------------------------------------------------------
+%%------- Exported external functions -----------------------
+%%-----------------------------------------------------------
+%%----------------------------------------------------------%
+%% function : time_set
+%% Arguments: -
+%% Returns : {boolean(), CosTime::UTO}
+%%-----------------------------------------------------------
+time_set(_OE_THIS, State) when ?is_UtoSet(State) ->
+ {reply, {?is_TimeSet(State), ?get_Uto(State)}, State};
+time_set(_OE_THIS, State) ->
+ Utc = #'TimeBase_UtcT'{time=0, inacclo = 0,inacchi = 0, tdf = 0},
+ {reply,
+ {?is_TimeSet(State),
+ 'CosTime_UTO':oe_create([Utc, ?get_TimeObj(State)], [{pseudo,true}|?CREATE_OPTS])},
+ State}.
+
+
+%%-----------------------------------------------------------
+%% function : set_timer
+%% Arguments: TimeType - 'TTAbsolute' | 'TTRelative' | 'TTPeriodic'
+%% TriggerTime - CosTime::UTO
+%% Returns : ok
+%%-----------------------------------------------------------
+set_timer(_OE_THIS, State, 'TTAbsolute', TriggerTime) ->
+ NewState = clear_timer(State),
+ ?time_TypeCheck(TriggerTime, 'CosTime_UTO'),
+ case catch {'CosTime_UTO':'_get_time'(TriggerTime),
+ 'CosTime_UTO':'_get_time'(
+ 'CosTime_TimeService':universal_time(?get_TimeObj(State)))} of
+ {Time, CurrentTime} when is_integer(Time) andalso is_integer(CurrentTime) andalso
+ Time > CurrentTime ->
+ %% Set a timer to send a message in (Time-CurrentTime)*10^-7 secs.
+ case timer:send_after(?convert_TimeT2TimerT(Time-CurrentTime), oe_event) of
+ {ok, TRef} ->
+ NewState1 = ?set_Timer(NewState, TRef),
+ NewState2 = ?set_Uto(NewState1, TriggerTime, 'TTAbsolute'),
+ ?debug_print("TIMER SET: ~p~n", [?convert_TimeT2TimerT(Time-CurrentTime)]),
+ {reply, ok, ?set_Status(NewState2, 'ESTimeSet')};
+ _->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+ {Time, CurrentTime} when is_integer(Time) andalso is_integer(CurrentTime) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO});
+ _->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+set_timer(_OE_THIS, State, 'TTRelative', TriggerTime) ->
+ NewState = clear_timer(State),
+ ?time_TypeCheck(TriggerTime, 'CosTime_UTO'),
+ case catch {'CosTime_UTO':'_get_time'(TriggerTime), ?get_Time(State)} of
+ {0,OldTime} when ?is_NotAbsolute(NewState) andalso is_integer(OldTime) ->
+ %% Set a timer to send a message within Time*10^-7 secs
+ case timer:send_after(OldTime, oe_event) of
+ {ok, TRef} ->
+ NewState1 = ?set_Timer(NewState, TRef),
+ NewState2 = ?set_Uto(NewState1, TriggerTime, 'TTRelative'),
+ ?debug_print("TIMER SET: ~p~n", [?convert_TimeT2TimerT(OldTime)]),
+ {reply, ok, ?set_Status(NewState2, 'ESTimeSet')};
+ _->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+ {UtoTime,_} when is_integer(UtoTime) ->
+ %% Set a timer to send a message within Time*10^-7 secs
+ Time = ?convert_TimeT2TimerT(UtoTime),
+ case timer:send_after(Time, oe_event) of
+ {ok, TRef} ->
+ NewState1 = ?set_Timer(NewState, TRef),
+ NewState2 = ?set_TimeData(NewState1, TriggerTime,
+ 'TTRelative', Time),
+ ?debug_print("TIMER SET: ~p~n", [?convert_TimeT2TimerT(Time)]),
+ {reply, ok, ?set_Status(NewState2, 'ESTimeSet')};
+ _->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+
+ _->
+ {reply, {'EXCEPTION', #'BAD_PARAM'{completion_status=?COMPLETED_NO}}, NewState}
+ end;
+set_timer(_OE_THIS, State, 'TTPeriodic', TriggerTime) ->
+ NewState = clear_timer(State),
+ ?time_TypeCheck(TriggerTime, 'CosTime_UTO'),
+ case catch {'CosTime_UTO':'_get_time'(TriggerTime), ?get_Time(State)} of
+ {0,OldTime} when ?is_NotAbsolute(NewState) andalso is_integer(OldTime) ->
+ %% Set a timer to send a message within Time*10^-7 secs
+ case timer:send_interval(OldTime, oe_periodic_event) of
+ {ok, TRef} ->
+ NewState1 = ?set_Timer(NewState, TRef),
+ NewState2 = ?set_Uto(NewState1, TriggerTime, 'TTPeriodic'),
+ ?debug_print("TIMER SET: ~p~n", [?convert_TimeT2TimerT(OldTime)]),
+ {reply, ok, ?set_Status(NewState2, 'ESTimeSet')};
+ _->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+ {UtoTime,_} when is_integer(UtoTime) ->
+ %% Set a timer to send a message within Time*10^-7 secs
+ Time = ?convert_TimeT2TimerT(UtoTime),
+ case timer:send_interval(Time, oe_periodic_event) of
+ {ok, TRef} ->
+ NewState1 = ?set_Timer(NewState, TRef),
+ NewState2 = ?set_TimeData(NewState1, TriggerTime,
+ 'TTPeriodic', Time),
+ ?debug_print("TIMER SET: ~p~n", [?convert_TimeT2TimerT(Time)]),
+ {reply, ok, ?set_Status(NewState2, 'ESTimeSet')};
+ _->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+
+ _->
+ {reply, {'EXCEPTION', #'BAD_PARAM'{completion_status=?COMPLETED_NO}}, NewState}
+ end;
+set_timer(_OE_THIS, _State, _, _) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+%%----------------------------------------------------------%
+%% function : cancel_timer
+%% Arguments: -
+%% Returns : boolean()
+%%-----------------------------------------------------------
+cancel_timer(_OE_THIS, State) ->
+ NewState=clear_timer(State),
+ case ?get_Status(NewState) of
+ 'ESTriggered' ->
+ {reply, false, NewState};
+ 'ESFailedTrigger' ->
+ {reply, false, NewState};
+ _ ->
+ {reply, true, ?set_Status(NewState, 'ESTimeCleared')}
+ end.
+
+%%----------------------------------------------------------%
+%% function : set_data
+%% Arguments: EventData - any#
+%% Returns : ok
+%%-----------------------------------------------------------
+set_data(_OE_THIS, State, EventData) when is_record(EventData, any) ->
+ {reply, ok, ?set_Event(State, EventData)};
+set_data(_OE_THIS, _State, _EventData) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+
+%%--------------- LOCAL FUNCTIONS ----------------------------
+clear_timer(State) when ?get_Timer(State) == undefined ->
+ State;
+clear_timer(State) ->
+ catch timer:cancel(?get_Timer(State)),
+ ?set_Timer(State, undefined).
+
+%%--------------- MISC FUNCTIONS, E.G. DEBUGGING -------------
+%%--------------- END OF MODULE ------------------------------