Handle HAVE_ALL and HAVE_NONE. Cleanup the BITFIELD message.
[etorrent.git] / lib / etorrent-1.0 / src / etorrent_mgr.erl
blobaac56947f312ce159f856c2e62764d1fd41fc4b0
1 %%%
2 %%% This module is responsible for managing the run of set of torrent files.
3 %%%
4 -module(etorrent_mgr).
5 -behaviour(gen_server).
7 -include("etorrent_mnesia_table.hrl").
9 -export([start_link/1,
11 start/1, stop/1,
12 check/1,
14 stop_all/0]).
16 -export([handle_cast/2, handle_call/3, init/1, terminate/2]).
17 -export([handle_info/2, code_change/3]).
19 -define(SERVER, ?MODULE).
22 -record(state, {local_peer_id}).
24 %% API
26 %% Start a new etorrent_t_manager process
27 start_link(PeerId) ->
28 gen_server:start_link({local, ?SERVER}, ?MODULE, [PeerId], []).
30 %% Ask the manager process to start a new torrent, given in File.
31 start(File) ->
32 gen_server:cast(?SERVER, {start, File}).
34 %% Check a torrents contents
35 check(Id) ->
36 gen_server:cast(?SERVER, {check, Id}).
38 %% Ask the manager process to stop a torrent, identified by File.
39 stop(File) ->
40 gen_server:cast(?SERVER, {stop, File}).
42 stop_all() ->
43 gen_server:call(?SERVER, stop_all, 120000).
45 %% Callbacks
46 init([PeerId]) ->
47 {ok, #state { local_peer_id = PeerId}}.
49 handle_cast({start, F}, S) ->
50 case torrent_duplicate(F) of
51 true -> {noreply, S};
52 false ->
53 {ok, _} =
54 etorrent_t_pool_sup:add_torrent(
56 S#state.local_peer_id,
57 etorrent_counters:next(torrent)),
58 {noreply, S}
59 end;
60 handle_cast({check, Id}, S) ->
61 {atomic, [T]} = etorrent_tracking_map:select(Id),
62 SPid = T#tracking_map.supervisor_pid,
63 Child = etorrent_t_sup:get_pid(SPid, control),
64 etorrent_t_control:check_torrent(Child),
65 {noreply, S};
66 handle_cast({stop, F}, S) ->
67 stop_torrent(F, S).
69 handle_call(stop_all, _From, S) ->
70 {atomic, Torrents} = etorrent_tracking_map:all(),
71 lists:foreach(fun(#tracking_map { filename = F }) ->
72 etorrent_t_pool_sup:stop_torrent(F),
74 end,
75 Torrents),
76 {reply, ok, S};
77 handle_call(_A, _B, S) ->
78 {noreply, S}.
80 handle_info(Info, State) ->
81 error_logger:info_msg("Unknown message: ~p~n", [Info]),
82 {noreply, State}.
84 terminate(_Foo, _State) ->
85 ok.
87 code_change(_OldVsn, State, _Extra) ->
88 {ok, State}.
90 %% Internal functions
91 stop_torrent(F, S) ->
92 error_logger:info_msg("Stopping ~p~n", [F]),
93 case etorrent_tracking_map:select({filename, F}) of
94 {atomic, [T]} when is_record(T, tracking_map) ->
95 etorrent_t_pool_sup:stop_torrent(F),
96 ok;
97 {atomic, []} ->
98 %% Was already removed, it is ok.
100 end,
101 {noreply, S}.
104 torrent_duplicate(F) ->
105 case etorrent_tracking_map:select({filename, F}) of
106 {atomic, []} -> false;
107 {atomic, [T]} -> duplicate =:= T#tracking_map.state
108 end.