Handle HAVE_ALL and HAVE_NONE. Cleanup the BITFIELD message.
[etorrent.git] / lib / etorrent-1.0 / src / etorrent_counters.erl
blobc7b8d3b601dc39e8da9a8e450dce04267636a976
1 %%%-------------------------------------------------------------------
2 %%% File : etorrent_counters.erl
3 %%% Author : Jesper Louis Andersen <jlouis@ogre.home>
4 %%% Description : Various global counters in etorrent
5 %%%
6 %%% Created : 29 Jul 2008 by Jesper Louis Andersen <jlouis@ogre.home>
7 %%%-------------------------------------------------------------------
8 -module(etorrent_counters).
10 -behaviour(gen_server).
12 %% API
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]).
20 -record(state, {}).
21 -define(SERVER, ?MODULE).
22 -define(MAX_PEER_PROCESSES, 40).
24 %%====================================================================
25 %% API
26 %%====================================================================
27 %%--------------------------------------------------------------------
28 %% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
29 %% Description: Starts the server
30 %%--------------------------------------------------------------------
31 start_link() ->
32 gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
34 next(Sequence) ->
35 gen_server:call(?SERVER, {next, Sequence}).
37 obtain_peer_slot() ->
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} |
50 %% ignore |
51 %% {stop, Reason}
52 %% Description: Initiates the server
53 %%--------------------------------------------------------------------
54 init([]) ->
55 process_flag(trap_exit, true),
56 _Tid = ets:new(etorrent_counters, [named_table, protected]),
57 ets:insert(etorrent_counters, [{torrent, 0},
58 {path_map, 0},
59 {peer_slots, 0}]),
60 {ok, #state{}}.
62 %%--------------------------------------------------------------------
63 %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
64 %% {reply, Reply, State, Timeout} |
65 %% {noreply, State} |
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),
73 {reply, N, S};
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
77 true ->
78 {reply, full, S};
79 false ->
80 ets:update_counter(etorrent_counters, peer_slots, 1),
81 {reply, ok, S}
82 end;
83 handle_call(_Request, _From, State) ->
84 Reply = ok,
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),
95 true = K >= 0,
96 {noreply, S};
97 handle_cast(_Msg, State) ->
98 {noreply, 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) ->
107 {noreply, 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) ->
125 {ok, State}.
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) ->
134 undefined ->
135 ?MAX_PEER_PROCESSES
136 end.