aboutsummaryrefslogtreecommitdiffstats
path: root/lib/megaco/src/engine/megaco_timer.erl
blob: 9f524523a8ba1f992f64cbf32491b29242481312 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
%%
%% %CopyrightBegin%
%% 
%% Copyright Ericsson AB 2007-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: Timer handling
%%----------------------------------------------------------------------

-module(megaco_timer).

%% Application internal export
-export([
	 init/1,
	 restart/1,
	 verify/1
        ]).


-include_lib("megaco/include/megaco.hrl").


%%-----------------------------------------------------------------

%% init(Timer) -> {TimeoutTime, NewTimer}
%% Timer       = megaco_timer()
%% NewTimer    = megaco_timer() 
%% TimeoutTime = infinity | integer()
%% 
init(SingleWaitFor) when SingleWaitFor == infinity ->
    {SingleWaitFor, timeout};
init(SingleWaitFor) when is_integer(SingleWaitFor) and (SingleWaitFor >= 0) ->
    {SingleWaitFor, timeout};
init(Timer) when is_record(Timer, megaco_incr_timer) ->
    return_incr(Timer).


%% Returns {WaitFor, NewTimer} | {WaitFor, timeout}
restart(#megaco_incr_timer{wait_for    = Old,
			   factor      = Factor,
			   incr        = Incr,
			   max_retries = MaxRetries} = Timer) ->
    New    = wait_for(Old, Factor, Incr),
    Max    = decr(MaxRetries),
    Timer2 = Timer#megaco_incr_timer{wait_for    = New,
				     max_retries = Max},
    return_incr(Timer2);
restart({Timer, timeout}) when is_record(Timer, megaco_incr_timer) ->
    restart(Timer).

wait_for(Old, Factor, Incr) ->
    New = (Old * Factor) + Incr,
    if 
	New < 0 ->
	    0;
	true ->
	    New
    end.

verify(#megaco_incr_timer{wait_for    = WaitFor,
			  factor      = Factor,
			  incr        = Incr,
			  max_retries = MaxRetries}) ->
    (megaco_config:verify_strict_uint(WaitFor) and
     megaco_config:verify_strict_uint(Factor)  and
     megaco_config:verify_strict_int(Incr)     and
     verify_max_retries(MaxRetries));
verify(Timer) ->
    megaco_config:verify_uint(Timer).

verify_max_retries(infinity_restartable) ->
    true;
verify_max_retries(Val) ->
    megaco_config:verify_uint(Val).


%%-----------------------------------------------------------------


return_incr(#megaco_incr_timer{wait_for    = WaitFor,
			       max_retries = infinity} = Timer) ->
    {WaitFor, Timer};

return_incr(#megaco_incr_timer{wait_for    = WaitFor,
			       max_retries = infinity_restartable} = Timer) ->
    {WaitFor, {Timer, timeout}};

return_incr(#megaco_incr_timer{wait_for    = WaitFor,
			       max_retries = Int} = Timer) 
  when is_integer(Int) and (Int > 0) ->
    {WaitFor, Timer};

return_incr(#megaco_incr_timer{wait_for    = WaitFor,
			       max_retries = 0} = _Timer) ->
    {WaitFor, timeout}.


decr(infinity = V)             -> V;
decr(infinity_restartable = V) -> V;
decr(Int) when is_integer(Int) -> Int - 1.