1 %%%-------------------------------------------------------------------
2 %%% File : etorrent_counters.erl
3 %%% Author : Jesper Louis Andersen <jlouis@ogre.home>
4 %%% Description : Various global counters in etorrent
6 %%% Created : 29 Jul 2008 by Jesper Louis Andersen <jlouis@ogre.home>
7 %%%-------------------------------------------------------------------
8 -module(etorrent_counters
).
10 -behaviour(gen_server
).
13 -export([start_link
/0, next
/1, obtain_peer_slot
/0, release_peer_slot
/0,
14 max_peer_processes
/0]).
16 %% gen_server callbacks
17 -export([init
/1, handle_call
/3, handle_cast
/2, handle_info
/2,
18 terminate
/2, code_change
/3]).
21 -define(SERVER
, ?MODULE
).
22 -define(MAX_PEER_PROCESSES
, 40).
24 %%====================================================================
26 %%====================================================================
27 %%--------------------------------------------------------------------
28 %% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
29 %% Description: Starts the server
30 %%--------------------------------------------------------------------
32 gen_server:start_link({local
, ?SERVER
}, ?MODULE
, [], []).
35 gen_server:call(?SERVER
, {next
, Sequence
}).
38 gen_server:call(?SERVER
, obtain_peer_slot
).
40 release_peer_slot() ->
41 gen_server:cast(?SERVER
, release_peer_slot
).
43 %%====================================================================
44 %% gen_server callbacks
45 %%====================================================================
47 %%--------------------------------------------------------------------
48 %% Function: init(Args) -> {ok, State} |
49 %% {ok, State, Timeout} |
52 %% Description: Initiates the server
53 %%--------------------------------------------------------------------
55 process_flag(trap_exit
, true
),
56 _Tid
= ets:new(etorrent_counters
, [named_table
, protected
]),
57 ets:insert(etorrent_counters
, [{torrent
, 0},
62 %%--------------------------------------------------------------------
63 %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
64 %% {reply, Reply, State, Timeout} |
66 %% {noreply, State, Timeout} |
67 %% {stop, Reason, Reply, State} |
68 %% {stop, Reason, State}
69 %% Description: Handling call messages
70 %%--------------------------------------------------------------------
71 handle_call({next
, Seq
}, _From
, S
) ->
72 N
= ets:update_counter(etorrent_counters
, Seq
, 1),
74 handle_call(obtain_peer_slot
, _From
, S
) ->
75 [{peer_slots
, K
}] = ets:lookup(etorrent_counters
, peer_slots
),
76 case K
>= max_peer_processes() of
80 ets:update_counter(etorrent_counters
, peer_slots
, 1),
83 handle_call(_Request
, _From
, State
) ->
85 {reply
, Reply
, State
}.
87 %%--------------------------------------------------------------------
88 %% Function: handle_cast(Msg, State) -> {noreply, State} |
89 %% {noreply, State, Timeout} |
90 %% {stop, Reason, State}
91 %% Description: Handling cast messages
92 %%--------------------------------------------------------------------
93 handle_cast(release_peer_slot
, S
) ->
94 K
= ets:update_counter(etorrent_counters
, peer_slots
, -1),
97 handle_cast(_Msg
, State
) ->
100 %%--------------------------------------------------------------------
101 %% Function: handle_info(Info, State) -> {noreply, State} |
102 %% {noreply, State, Timeout} |
103 %% {stop, Reason, State}
104 %% Description: Handling all non call/cast messages
105 %%--------------------------------------------------------------------
106 handle_info(_Info
, State
) ->
109 %%--------------------------------------------------------------------
110 %% Function: terminate(Reason, State) -> void()
111 %% Description: This function is called by a gen_server when it is about to
112 %% terminate. It should be the opposite of Module:init/1 and do any necessary
113 %% cleaning up. When it returns, the gen_server terminates with Reason.
114 %% The return value is ignored.
115 %%--------------------------------------------------------------------
116 terminate(_Reason
, _State
) ->
117 true
= ets:delete(etorrent_counters
),
120 %%--------------------------------------------------------------------
121 %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
122 %% Description: Convert process state when code is changed
123 %%--------------------------------------------------------------------
124 code_change(_OldVsn
, State
, _Extra
) ->
127 %%--------------------------------------------------------------------
128 %%% Internal functions
129 %%--------------------------------------------------------------------
130 max_peer_processes() ->
131 case application:get_env(etorrent
, max_peers
) of
132 {ok
, N
} when is_integer(N
) ->