1
// libTorrent - BitTorrent library
2
// Copyright (C) 2005-2007, Jari Sundell
4
// This program is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 2 of the License, or
7
// (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
// In addition, as a special exception, the copyright holders give
19
// permission to link the code of portions of this program with the
20
// OpenSSL library under certain conditions as described in each
21
// individual source file, and distribute linked combinations
24
// You must obey the GNU General Public License in all respects for
25
// all of the code used other than OpenSSL. If you modify file(s)
26
// with this exception, you may extend this exception to your version
27
// of the file(s), but you are not obligated to do so. If you do not
28
// wish to do so, delete this exception statement from your version.
29
// If you delete this exception statement from all source files in the
30
// program, then also delete it here.
32
// Contact: Jari Sundell <jaris@ifi.uio.no>
35
// 3185 Skoppum, NORWAY
39
#include "torrent/exceptions.h"
41
#include "download/choke_manager.h"
42
#include "download/download_manager.h"
43
#include "download/download_wrapper.h"
44
#include "download/download_main.h"
45
#include "data/hash_torrent.h"
46
#include "protocol/handshake_manager.h"
47
#include "data/hash_queue.h"
48
#include "net/listen.h"
50
#include "torrent/chunk_manager.h"
51
#include "torrent/connection_manager.h"
52
#include "torrent/dht_manager.h"
53
#include "torrent/data/file_manager.h"
54
#include "torrent/peer/client_list.h"
55
#include "torrent/throttle.h"
58
#include "resource_manager.h"
62
Manager* manager = NULL;
65
m_downloadManager(new DownloadManager),
66
m_fileManager(new FileManager),
67
m_handshakeManager(new HandshakeManager),
68
m_hashQueue(new HashQueue),
69
m_resourceManager(new ResourceManager),
71
m_chunkManager(new ChunkManager),
72
m_clientList(new ClientList),
73
m_connectionManager(new ConnectionManager),
74
m_dhtManager(new DhtManager),
78
m_uploadThrottle(Throttle::create_throttle()),
79
m_downloadThrottle(Throttle::create_throttle()),
83
m_taskTick.set_slot(rak::mem_fn(this, &Manager::receive_tick));
85
priority_queue_insert(&taskScheduler, &m_taskTick, cachedTime.round_seconds());
87
m_handshakeManager->slot_download_id(rak::make_mem_fun(m_downloadManager, &DownloadManager::find_main));
88
m_handshakeManager->slot_download_id_obfuscated(rak::make_mem_fun(m_downloadManager, &DownloadManager::find_main_obfuscated));
89
m_connectionManager->listen()->slot_incoming(rak::make_mem_fun(m_handshakeManager, &HandshakeManager::add_incoming));
93
priority_queue_erase(&taskScheduler, &m_taskTick);
95
m_handshakeManager->clear();
96
m_downloadManager->clear();
98
delete m_downloadManager;
100
delete m_handshakeManager;
103
delete m_resourceManager;
105
delete m_connectionManager;
106
delete m_chunkManager;
110
Throttle::destroy_throttle(m_uploadThrottle);
111
Throttle::destroy_throttle(m_downloadThrottle);
115
Manager::initialize_download(DownloadWrapper* d) {
116
d->main()->slot_count_handshakes(rak::make_mem_fun(m_handshakeManager, &HandshakeManager::size_info));
117
d->main()->slot_start_handshake(rak::make_mem_fun(m_handshakeManager, &HandshakeManager::add_outgoing));
118
d->main()->slot_stop_handshakes(rak::make_mem_fun(m_handshakeManager, &HandshakeManager::erase_download));
120
m_downloadManager->insert(d);
121
m_resourceManager->insert(d->main(), 1);
122
m_chunkManager->insert(d->main()->chunk_list());
124
d->main()->set_upload_throttle(m_uploadThrottle->throttle_list());
125
d->main()->set_download_throttle(m_downloadThrottle->throttle_list());
127
d->main()->upload_choke_manager()->set_slot_unchoke(rak::make_mem_fun(manager->resource_manager(), &ResourceManager::receive_upload_unchoke));
128
d->main()->upload_choke_manager()->set_slot_can_unchoke(rak::make_mem_fun(manager->resource_manager(), &ResourceManager::retrieve_upload_can_unchoke));
129
d->main()->download_choke_manager()->set_slot_unchoke(rak::make_mem_fun(manager->resource_manager(), &ResourceManager::receive_download_unchoke));
130
d->main()->download_choke_manager()->set_slot_can_unchoke(rak::make_mem_fun(manager->resource_manager(), &ResourceManager::retrieve_download_can_unchoke));
134
Manager::cleanup_download(DownloadWrapper* d) {
138
m_resourceManager->erase(d->main());
139
m_chunkManager->erase(d->main()->chunk_list());
141
m_downloadManager->erase(d);
145
Manager::receive_tick() {
148
m_resourceManager->receive_tick();
149
m_chunkManager->periodic_sync();
151
// To ensure the downloads get equal chance over time at using
152
// various limited resources, like sockets for handshakes, cycle the
153
// group in reverse order.
154
if (!m_downloadManager->empty()) {
155
DownloadManager::iterator split = m_downloadManager->end() - m_ticks % m_downloadManager->size() - 1;
157
std::for_each(split, m_downloadManager->end(), std::bind2nd(std::mem_fun(&DownloadWrapper::receive_tick), m_ticks));
158
std::for_each(m_downloadManager->begin(), split, std::bind2nd(std::mem_fun(&DownloadWrapper::receive_tick), m_ticks));
161
// If you change the interval, make sure the keepalives gets
162
// triggered every 120 seconds.
163
priority_queue_insert(&taskScheduler, &m_taskTick, (cachedTime + rak::timer::from_seconds(30)).round_seconds());