44
44
#include "protocol/peer_connection_base.h"
45
45
#include "tracker/tracker_manager.h"
46
46
#include "torrent/exceptions.h"
47
#include "torrent/data/file_list.h"
48
#include "torrent/peer/peer_info.h"
48
50
#include "available_list.h"
49
51
#include "choke_manager.h"
65
67
m_uploadThrottle(NULL),
66
68
m_downloadThrottle(NULL) {
68
m_connectionList = new ConnectionList(this);
69
m_chokeManager = new ChokeManager(m_connectionList);
70
m_connectionList = new ConnectionList(this);
71
m_uploadChokeManager = new ChokeManager(m_connectionList);
72
m_downloadChokeManager = new ChokeManager(m_connectionList, ChokeManager::flag_unchoke_all_new);
74
m_uploadChokeManager->set_slot_choke_weight(&calculate_upload_choke);
75
m_uploadChokeManager->set_slot_unchoke_weight(&calculate_upload_unchoke);
76
m_uploadChokeManager->set_slot_connection(std::mem_fun(&PeerConnectionBase::receive_upload_choke));
78
std::memcpy(m_uploadChokeManager->choke_weight(), weights_upload_choke, ChokeManager::weight_size_bytes);
79
std::memcpy(m_uploadChokeManager->unchoke_weight(), weights_upload_unchoke, ChokeManager::weight_size_bytes);
81
m_downloadChokeManager->set_slot_choke_weight(&calculate_download_choke);
82
m_downloadChokeManager->set_slot_unchoke_weight(&calculate_download_unchoke);
83
m_downloadChokeManager->set_slot_connection(std::mem_fun(&PeerConnectionBase::receive_download_choke));
85
std::memcpy(m_downloadChokeManager->choke_weight(), weights_download_choke, ChokeManager::weight_size_bytes);
86
std::memcpy(m_downloadChokeManager->unchoke_weight(), weights_download_unchoke, ChokeManager::weight_size_bytes);
71
88
m_delegator.slot_chunk_find(rak::make_mem_fun(m_chunkSelector, &ChunkSelector::find));
72
m_delegator.slot_chunk_size(rak::make_mem_fun(&m_content, &Content::chunk_index_size));
89
m_delegator.slot_chunk_size(rak::make_mem_fun(file_list(), &FileList::chunk_index_size));
74
91
m_delegator.transfer_list()->slot_canceled(std::bind1st(std::mem_fun(&ChunkSelector::not_using_index), m_chunkSelector));
75
92
m_delegator.transfer_list()->slot_queued(std::bind1st(std::mem_fun(&ChunkSelector::using_index), m_chunkSelector));
79
96
m_taskTrackerRequest.set_slot(rak::mem_fn(this, &DownloadMain::receive_tracker_request));
81
m_chunkList->slot_create_chunk(rak::make_mem_fun(&m_content, &Content::create_chunk));
82
m_chunkList->slot_free_diskspace(rak::make_mem_fun(m_content.entry_list(), &EntryList::free_diskspace));
98
m_chunkList->slot_create_chunk(rak::make_mem_fun(file_list(), &FileList::create_chunk_index));
99
m_chunkList->slot_free_diskspace(rak::make_mem_fun(file_list(), &FileList::free_diskspace));
85
102
DownloadMain::~DownloadMain() {
101
119
if (info()->is_open())
102
120
throw internal_error("Tried to open a download that is already open");
104
m_content.entry_list()->open();
106
m_chunkList->resize(m_content.chunk_total());
107
m_chunkStatistics->initialize(m_content.chunk_total());
124
m_chunkList->resize(file_list()->size_chunks());
125
m_chunkStatistics->initialize(file_list()->size_chunks());
109
127
info()->set_open(true);
120
138
info()->set_open(false);
122
m_trackerManager->close();
140
// Don't close the tracker manager here else it will cause STOPPED
141
// requests to be lost. TODO: Check that this is valid.
142
// m_trackerManager->close();
123
144
m_delegator.transfer_list()->clear();
125
m_content.bitfield()->unallocate();
126
m_content.entry_list()->close();
146
file_list()->mutable_bitfield()->unallocate();
147
file_list()->close();
128
149
// Clear the chunklist last as it requires all referenced chunks to
135
156
void DownloadMain::start() {
136
157
if (!info()->is_open())
137
throw client_error("Tried to start a closed download");
158
throw internal_error("Tried to start a closed download");
139
160
if (info()->is_active())
140
throw client_error("Tried to start an active download");
161
throw internal_error("Tried to start an active download");
142
163
info()->set_active(true);
143
164
m_lastConnectedSize = 0;
168
189
DownloadMain::update_endgame() {
169
if (!m_delegator.get_aggressive() && m_content.chunks_completed() + m_delegator.transfer_list()->size() + 5 >= m_content.chunk_total())
190
if (!m_delegator.get_aggressive() &&
191
file_list()->completed_chunks() + m_delegator.transfer_list()->size() + 5 >= file_list()->size_chunks())
170
192
m_delegator.set_aggressive(true);