forked from premiere/premiere-libtorrent
*** empty log message ***
This commit is contained in:
parent
b716a40795
commit
fc74e19224
|
@ -181,8 +181,8 @@ The ``session`` class has the following synopsis::
|
|||
|
||||
class session: public boost::noncopyable
|
||||
{
|
||||
session(int listen_port, const fingerprint& print);
|
||||
session(int listen_port);
|
||||
session(std::pair<int, int> listen_port_range, const fingerprint& print);
|
||||
session(std::pair<int, int> listen_port_range);
|
||||
|
||||
torrent_handle add_torrent(
|
||||
const torrent_info& t
|
||||
|
@ -237,10 +237,12 @@ timeout can be set with ``set_http_settings()``.
|
|||
The torrent_handle_ returned by ``add_torrent`` can be used to retrieve information
|
||||
about the torrent's progress, its peers etc. It is also used to abort a torrent.
|
||||
|
||||
The constructor takes a listen port as argument, if the given port is busy it will
|
||||
The constructor takes a range of listen ports as argument, if the first port is busy it will
|
||||
increase the port number by one and try again. If it still fails it will continue
|
||||
increasing the port number until it succeeds or has failed 9 ports. *This will
|
||||
change in the future to give more control of the listen-port.*
|
||||
increasing the port number until it succeeds or has reached the end of the range. If it
|
||||
fails with all ports, a listen_failed_alert_ will be posted and the session thread will
|
||||
exit. The only thing you can do with your session if this alert is posted is to destruct
|
||||
it and possibly try again or change the port range.
|
||||
|
||||
For information about the ``pop_alert()`` function, see alerts_.
|
||||
|
||||
|
@ -1104,6 +1106,43 @@ user in different ways.
|
|||
The specific alerts, that all derives from ``alert``, are:
|
||||
|
||||
|
||||
listen_failed_alert
|
||||
-------------------
|
||||
|
||||
This alert is generated when none of the ports, given in the port range, to
|
||||
session_ can be opened for listening. Without a listening port the session
|
||||
object will exit its thread. This alert is generated as severity level ``fatal``.
|
||||
|
||||
::
|
||||
|
||||
struct listen_failed_alert: alert
|
||||
{
|
||||
listen_failed_alert(const std::string& msg);
|
||||
virtual std::auto_ptr<alert> clone() const;
|
||||
};
|
||||
|
||||
|
||||
file_error_alert
|
||||
----------------
|
||||
|
||||
If the storage fails to read or write files that it needs access to, this alert is
|
||||
generated and the torrent is aborted. It is generated as severity level ``fatal``.
|
||||
|
||||
::
|
||||
|
||||
struct file_error_alert: alert
|
||||
{
|
||||
file_error_alert(
|
||||
const torrent_handle& h
|
||||
, const std::string& msg);
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const;
|
||||
|
||||
torrent_handle handle;
|
||||
};
|
||||
|
||||
|
||||
|
||||
tracker_alert
|
||||
-------------
|
||||
|
||||
|
@ -1415,7 +1454,7 @@ This is a simple client. It doesn't have much output to keep it simple::
|
|||
|
||||
try
|
||||
{
|
||||
session s(6881);
|
||||
session s(std::make_pair(6881, 6889));
|
||||
|
||||
std::ifstream in(argv[1], std::ios_base::binary);
|
||||
in.unsetf(std::ios_base::skipws);
|
||||
|
|
|
@ -236,7 +236,7 @@ int main(int argc, char* argv[])
|
|||
try
|
||||
{
|
||||
std::vector<torrent_handle> handles;
|
||||
session ses(6881);
|
||||
session ses(std::make_pair(6881, 6889));
|
||||
|
||||
// ses.set_upload_rate_limit(30 * 1024);
|
||||
ses.set_http_settings(settings);
|
||||
|
|
|
@ -56,7 +56,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
try
|
||||
{
|
||||
session s(6881);
|
||||
session s(std::make_pair(6881, 6889));
|
||||
|
||||
std::ifstream in(argv[1], std::ios_base::binary);
|
||||
in.unsetf(std::ios_base::skipws);
|
||||
|
|
|
@ -140,7 +140,6 @@ namespace libtorrent
|
|||
torrent_handle handle;
|
||||
};
|
||||
|
||||
// TODO: document and test
|
||||
struct file_error_alert: alert
|
||||
{
|
||||
file_error_alert(
|
||||
|
@ -155,6 +154,17 @@ namespace libtorrent
|
|||
|
||||
torrent_handle handle;
|
||||
};
|
||||
|
||||
struct listen_failed_alert: alert
|
||||
{
|
||||
listen_failed_alert(
|
||||
const std::string& msg)
|
||||
: alert(alert::fatal, msg)
|
||||
{}
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const
|
||||
{ return std::auto_ptr<alert>(new listen_failed_alert(*this)); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -166,7 +166,9 @@ namespace libtorrent
|
|||
break;
|
||||
case entry::dictionary_t:
|
||||
*out = 'd'; ++out;
|
||||
for (entry::dictionary_type::const_iterator i = e.dict().begin(); i != e.dict().end(); ++i)
|
||||
for (entry::dictionary_type::const_iterator i = e.dict().begin();
|
||||
i != e.dict().end();
|
||||
++i)
|
||||
{
|
||||
// write key
|
||||
write_integer(out, i->first.length());
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace libtorrent
|
|||
inline T read_impl(InIt& start, type<T>)
|
||||
{
|
||||
T ret = 0;
|
||||
for (int i = 0; i < sizeof(T); ++i)
|
||||
for (int i = 0; i < (int)sizeof(T); ++i)
|
||||
{
|
||||
ret <<= 8;
|
||||
ret |= static_cast<unsigned char>(*start);
|
||||
|
@ -98,7 +98,7 @@ namespace libtorrent
|
|||
template <class T, class OutIt>
|
||||
inline void write_impl(T val, OutIt& start)
|
||||
{
|
||||
for (int i = sizeof(T)-1; i >= 0; --i)
|
||||
for (int i = (int)sizeof(T)-1; i >= 0; --i)
|
||||
{
|
||||
*start = static_cast<unsigned char>((val >> (i * 8)) & 0xff);
|
||||
++start;
|
||||
|
|
|
@ -275,7 +275,7 @@ namespace libtorrent
|
|||
{
|
||||
assert(index >= 0);
|
||||
assert(index < (int)m_piece_map.size());
|
||||
if (index+1 == m_piece_map.size())
|
||||
if (index+1 == (int)m_piece_map.size())
|
||||
return m_blocks_in_last_piece;
|
||||
else
|
||||
return m_blocks_per_piece;
|
||||
|
|
|
@ -156,7 +156,10 @@ namespace libtorrent
|
|||
friend class invariant_access;
|
||||
typedef std::map<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> > connection_map;
|
||||
|
||||
session_impl(int listen_port, const fingerprint& cl_fprint);
|
||||
session_impl(
|
||||
std::pair<int, int> listen_port_range
|
||||
, const fingerprint& cl_fprint);
|
||||
|
||||
void operator()();
|
||||
|
||||
// must be locked to access the data
|
||||
|
@ -182,6 +185,9 @@ namespace libtorrent
|
|||
// the peer id that is generated at the start of each torrent
|
||||
peer_id m_peer_id;
|
||||
|
||||
// the range of ports we try to listen on
|
||||
std::pair<int, int> m_listen_port_range;
|
||||
|
||||
// the port we are listening on for connections
|
||||
int m_listen_port;
|
||||
|
||||
|
@ -231,8 +237,8 @@ namespace libtorrent
|
|||
{
|
||||
public:
|
||||
|
||||
session(int listen_port, const fingerprint& print);
|
||||
session(int listen_port);
|
||||
session(std::pair<int, int> listen_port_range, const fingerprint& print);
|
||||
session(std::pair<int, int> listen_port_range);
|
||||
|
||||
~session();
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace libtorrent
|
|||
|
||||
// TODO: add a check to see if filenames are accepted on the
|
||||
// current platform.
|
||||
// TODO: add a filename converter function that will transform
|
||||
// also add a filename converter function that will transform
|
||||
// invalid filenames to valid filenames on the current platform
|
||||
|
||||
class torrent_info
|
||||
|
|
|
@ -474,7 +474,7 @@ namespace libtorrent
|
|||
INVARIANT_CHECK;
|
||||
|
||||
assert(received > 0);
|
||||
if (m_packet_size - 1 != (m_have_piece.size() + 7) / 8)
|
||||
if (m_packet_size - 1 != ((int)m_have_piece.size() + 7) / 8)
|
||||
throw protocol_error("bitfield with invalid size");
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (m_recv_pos < m_packet_size) return;
|
||||
|
@ -1353,7 +1353,6 @@ namespace libtorrent
|
|||
(*m_logger) << " protocol: '" << std::string(m_recv_buffer.begin(), m_recv_buffer.end()) << "'\n";
|
||||
#endif
|
||||
const char protocol_string[] = "BitTorrent protocol";
|
||||
const int protocol_len = sizeof(protocol_string) - 1;
|
||||
if (!std::equal(m_recv_buffer.begin(), m_recv_buffer.end(), protocol_string))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
|
@ -1555,9 +1554,6 @@ namespace libtorrent
|
|||
|
||||
// only add new piece-chunks if the send buffer is small enough
|
||||
// otherwise there will be no end to how large it will be!
|
||||
// TODO: make this a bit better. Don't always read the entire
|
||||
// requested block. Have a limit of how much of the requested
|
||||
// block is actually read at a time.
|
||||
while (!m_requests.empty()
|
||||
&& ((int)m_send_buffer.size() < m_torrent->block_size())
|
||||
&& !m_choked)
|
||||
|
@ -1680,7 +1676,7 @@ namespace libtorrent
|
|||
// empty the entire buffer at once or if
|
||||
// only a part of the buffer could be sent
|
||||
// remove the part that was sent from the buffer
|
||||
if (sent == m_send_buffer.size())
|
||||
if (sent == (int)m_send_buffer.size())
|
||||
{
|
||||
m_send_buffer.clear();
|
||||
}
|
||||
|
@ -1749,6 +1745,6 @@ namespace libtorrent
|
|||
bool peer_connection::is_seed() const
|
||||
{
|
||||
return std::count(m_have_piece.begin(), m_have_piece.end(), true)
|
||||
== m_have_piece.size();
|
||||
== (int)m_have_piece.size();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,9 +144,8 @@ namespace libtorrent
|
|||
assert(sizeof(piece_pos) == 4);
|
||||
|
||||
if (t != 0)
|
||||
assert(m_piece_map.size() == t->torrent_file().num_pieces());
|
||||
assert((int)m_piece_map.size() == t->torrent_file().num_pieces());
|
||||
|
||||
int last_val = 0;
|
||||
for (std::vector<piece_pos>::const_iterator i = m_piece_map.begin();
|
||||
i != m_piece_map.end();
|
||||
++i)
|
||||
|
@ -163,7 +162,7 @@ namespace libtorrent
|
|||
if (peer->second->has_piece(index)) actual_peer_count++;
|
||||
}
|
||||
|
||||
assert(i->peer_count == actual_peer_count);
|
||||
assert((int)i->peer_count == actual_peer_count);
|
||||
/*
|
||||
int num_downloaders = 0;
|
||||
for (std::vector<peer_connection*>::const_iterator peer = t->begin();
|
||||
|
@ -262,7 +261,7 @@ namespace libtorrent
|
|||
// update the piece_map
|
||||
piece_pos& p = m_piece_map[index];
|
||||
|
||||
assert(p.downloading != downloading || p.peer_count != peer_count);
|
||||
assert(p.downloading != downloading || (int)p.peer_count != peer_count);
|
||||
|
||||
std::vector<std::vector<int> >& dst_vec = (p.downloading)?m_downloading_piece_info:m_piece_info;
|
||||
|
||||
|
@ -286,13 +285,13 @@ namespace libtorrent
|
|||
m_piece_map[replace_index].index = elem_index;
|
||||
|
||||
assert((int)src_vec[peer_count].size() > elem_index);
|
||||
assert(m_piece_map[replace_index].peer_count == peer_count);
|
||||
assert(m_piece_map[replace_index].index == elem_index);
|
||||
assert((int)m_piece_map[replace_index].peer_count == peer_count);
|
||||
assert((int)m_piece_map[replace_index].index == elem_index);
|
||||
assert(src_vec[peer_count][elem_index] == replace_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(src_vec[peer_count].size() == elem_index+1);
|
||||
assert((int)src_vec[peer_count].size() == elem_index+1);
|
||||
}
|
||||
|
||||
src_vec[peer_count].pop_back();
|
||||
|
@ -519,9 +518,9 @@ namespace libtorrent
|
|||
assert(i != m_downloads.end());
|
||||
assert((int)i->finished_blocks.count() <= m_blocks_per_piece);
|
||||
int max_blocks = blocks_in_piece(index);
|
||||
if (i->finished_blocks.count() != max_blocks) return false;
|
||||
if ((int)i->finished_blocks.count() != max_blocks) return false;
|
||||
|
||||
assert(i->requested_blocks.count() == max_blocks);
|
||||
assert((int)i->requested_blocks.count() == max_blocks);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -761,7 +761,7 @@ namespace libtorrent
|
|||
const std::vector<bool>& peer_has = i->connection->get_bitfield();
|
||||
const std::vector<bool>& we_have = m_torrent->pieces();
|
||||
assert(we_have.size() == peer_has.size());
|
||||
for (int j = 0; j != we_have.size(); ++j)
|
||||
for (int j = 0; j != (int)we_have.size(); ++j)
|
||||
{
|
||||
if (!we_have[j] && peer_has[j])
|
||||
{
|
||||
|
|
|
@ -357,15 +357,18 @@ namespace libtorrent
|
|||
return 0;
|
||||
}
|
||||
|
||||
session_impl::session_impl(int listen_port,
|
||||
session_impl::session_impl(std::pair<int, int> listen_port_range,
|
||||
const fingerprint& cl_fprint)
|
||||
: m_abort(false)
|
||||
, m_tracker_manager(m_settings)
|
||||
, m_listen_port(listen_port)
|
||||
: m_tracker_manager(m_settings)
|
||||
, m_listen_port_range(listen_port_range)
|
||||
, m_listen_port(listen_port_range.first)
|
||||
, m_abort(false)
|
||||
, m_upload_rate(-1)
|
||||
, m_incoming_connection(false)
|
||||
{
|
||||
assert(listen_port > 0);
|
||||
assert(listen_port_range.first > 0);
|
||||
assert(listen_port_range.first < listen_port_range.second);
|
||||
assert(m_listen_port > 0);
|
||||
|
||||
// ---- generate a peer id ----
|
||||
|
||||
|
@ -395,7 +398,7 @@ namespace libtorrent
|
|||
{
|
||||
m_connections.erase(m_disconnect_peer.back());
|
||||
m_disconnect_peer.pop_back();
|
||||
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
|
||||
assert(m_selector.count_read_monitors() == (int)m_connections.size() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,11 +411,8 @@ namespace libtorrent
|
|||
try
|
||||
{
|
||||
#endif
|
||||
boost::shared_ptr<socket> listener(new socket(socket::tcp, false));
|
||||
int max_port = m_listen_port + 9;
|
||||
|
||||
|
||||
// create listener socket
|
||||
boost::shared_ptr<socket> listener(new socket(socket::tcp, false));
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
@ -422,9 +422,13 @@ namespace libtorrent
|
|||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
if (m_listen_port > max_port)
|
||||
throw;
|
||||
m_listen_port++;
|
||||
if (m_listen_port > m_listen_port_range.second)
|
||||
{
|
||||
m_alerts.post_alert(listen_failed_alert(
|
||||
"none of the ports in the given range could be opened"));
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
@ -470,7 +474,7 @@ namespace libtorrent
|
|||
boost::mutex::scoped_lock l(m_mutex);
|
||||
|
||||
// +1 for the listen socket
|
||||
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
|
||||
assert(m_selector.count_read_monitors() == (int)m_connections.size() + 1);
|
||||
|
||||
if (m_abort)
|
||||
{
|
||||
|
@ -520,17 +524,21 @@ namespace libtorrent
|
|||
}
|
||||
catch (file_error& e)
|
||||
{
|
||||
torrent* t = p->second->associated_torrent();
|
||||
assert(t != 0);
|
||||
|
||||
if (m_alerts.should_post(alert::fatal))
|
||||
{
|
||||
m_alerts.post_alert(
|
||||
file_error_alert(
|
||||
p->second->associated_torrent()->get_handle()
|
||||
t->get_handle()
|
||||
, e.what()));
|
||||
}
|
||||
|
||||
m_selector.remove(*i);
|
||||
m_connections.erase(p);
|
||||
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
|
||||
assert(m_selector.count_read_monitors() == (int)m_connections.size() + 1);
|
||||
t->abort();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
@ -544,7 +552,7 @@ namespace libtorrent
|
|||
|
||||
m_selector.remove(*i);
|
||||
m_connections.erase(p);
|
||||
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
|
||||
assert(m_selector.count_read_monitors() == (int)m_connections.size() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -600,17 +608,21 @@ namespace libtorrent
|
|||
}
|
||||
catch (file_error& e)
|
||||
{
|
||||
torrent* t = p->second->associated_torrent();
|
||||
assert(t != 0);
|
||||
|
||||
if (m_alerts.should_post(alert::fatal))
|
||||
{
|
||||
m_alerts.post_alert(
|
||||
file_error_alert(
|
||||
p->second->associated_torrent()->get_handle()
|
||||
t->get_handle()
|
||||
, e.what()));
|
||||
}
|
||||
|
||||
m_selector.remove(*i);
|
||||
m_connections.erase(p);
|
||||
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
|
||||
assert(m_selector.count_read_monitors() == (int)m_connections.size() + 1);
|
||||
t->abort();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
@ -623,7 +635,7 @@ namespace libtorrent
|
|||
// from the connection-list
|
||||
m_selector.remove(*i);
|
||||
m_connections.erase(p);
|
||||
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
|
||||
assert(m_selector.count_read_monitors() == (int)m_connections.size() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -656,7 +668,7 @@ namespace libtorrent
|
|||
if (p != m_connections.end())
|
||||
{
|
||||
m_connections.erase(p);
|
||||
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
|
||||
assert(m_selector.count_read_monitors() == (int)m_connections.size() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,7 +704,7 @@ namespace libtorrent
|
|||
{
|
||||
m_selector.remove(j->first);
|
||||
m_connections.erase(j);
|
||||
assert(m_selector.count_read_monitors() == m_connections.size() + 1);
|
||||
assert(m_selector.count_read_monitors() == (int)m_connections.size() + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -822,13 +834,14 @@ namespace libtorrent
|
|||
|
||||
}
|
||||
|
||||
// TODO: take a port range instead!
|
||||
session::session(int listen_port, const fingerprint& id)
|
||||
: m_impl(listen_port, id)
|
||||
session::session(std::pair<int, int> listen_port_range, const fingerprint& id)
|
||||
: m_impl(listen_port_range, id)
|
||||
, m_checker_impl(m_impl)
|
||||
, m_thread(boost::ref(m_impl))
|
||||
, m_checker_thread(boost::ref(m_checker_impl))
|
||||
{
|
||||
assert(listen_port_range.first > 0);
|
||||
assert(listen_port_range.first < listen_port_range.second);
|
||||
#ifndef NDEBUG
|
||||
// this test was added after it came to my attention
|
||||
// that devstudios managed c++ failed to generate
|
||||
|
@ -838,12 +851,14 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
|
||||
session::session(int listen_port)
|
||||
: m_impl(listen_port, fingerprint("LT",0,0,1,0))
|
||||
session::session(std::pair<int, int> listen_port_range)
|
||||
: m_impl(listen_port_range, fingerprint("LT",0,0,1,0))
|
||||
, m_checker_impl(m_impl)
|
||||
, m_thread(boost::ref(m_impl))
|
||||
, m_checker_thread(boost::ref(m_checker_impl))
|
||||
{
|
||||
assert(listen_port_range.first > 0);
|
||||
assert(listen_port_range.first < listen_port_range.second);
|
||||
#ifndef NDEBUG
|
||||
boost::function0<void> test = boost::ref(m_impl);
|
||||
assert(!test.empty());
|
||||
|
@ -1071,7 +1086,7 @@ namespace libtorrent
|
|||
const std::string& bitmask = i->dict()["bitmask"].string();
|
||||
|
||||
const int num_bitmask_bytes = std::max(num_blocks_per_piece / 8, 1);
|
||||
if (bitmask.size() != num_bitmask_bytes) return;
|
||||
if ((int)bitmask.size() != num_bitmask_bytes) return;
|
||||
for (int j = 0; j < num_bitmask_bytes; ++j)
|
||||
{
|
||||
unsigned char bits = bitmask[j];
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace libtorrent
|
|||
, const boost::filesystem::path& p
|
||||
, const std::vector<size_type>& sizes)
|
||||
{
|
||||
if (sizes.size() != t.num_files()) return false;
|
||||
if ((int)sizes.size() != t.num_files()) return false;
|
||||
|
||||
std::vector<size_type>::const_iterator s = sizes.begin();
|
||||
for (torrent_info::file_iterator i = t.begin_files();
|
||||
|
@ -326,6 +326,7 @@ namespace libtorrent
|
|||
return result;
|
||||
}
|
||||
|
||||
// throws file_error if it fails to write
|
||||
void storage::write(
|
||||
const char* buf
|
||||
, int slot
|
||||
|
@ -356,26 +357,18 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
fs::path path(m_pimpl->save_path / file_iter->path / file_iter->filename);
|
||||
/*
|
||||
fs::ofstream out;
|
||||
|
||||
if (fs::exists(path))
|
||||
out.open(path, std::ios_base::binary | std::ios_base::in);
|
||||
else
|
||||
out.open(path, std::ios_base::binary);
|
||||
*/
|
||||
file out(path, file::out);
|
||||
|
||||
assert(file_offset < file_iter->size);
|
||||
|
||||
// out.seekp(file_offset);
|
||||
out.seek(file_offset);
|
||||
|
||||
// assert(file_offset == out.tellp());
|
||||
#ifndef NDEBUG
|
||||
size_type out_tell = out.tell();
|
||||
assert(file_offset == out_tell);
|
||||
#endif
|
||||
if (out.tell() != file_offset)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "no storage for slot " << slot;
|
||||
throw file_error(s.str());
|
||||
}
|
||||
|
||||
int left_to_write = size;
|
||||
int slot_size = m_pimpl->info.piece_size(slot);
|
||||
|
@ -387,8 +380,6 @@ namespace libtorrent
|
|||
|
||||
int buf_pos = 0;
|
||||
|
||||
// TODO
|
||||
// handle case when we can't write size bytes.
|
||||
while (left_to_write > 0)
|
||||
{
|
||||
int write_bytes = left_to_write;
|
||||
|
@ -400,7 +391,14 @@ namespace libtorrent
|
|||
|
||||
assert(buf_pos >= 0);
|
||||
assert(write_bytes > 0);
|
||||
out.write(buf + buf_pos, write_bytes);
|
||||
size_type written = out.write(buf + buf_pos, write_bytes);
|
||||
|
||||
if (written != write_bytes)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "no storage for slot " << slot;
|
||||
throw file_error(s.str());
|
||||
}
|
||||
|
||||
left_to_write -= write_bytes;
|
||||
buf_pos += write_bytes;
|
||||
|
@ -926,9 +924,6 @@ namespace libtorrent
|
|||
|
||||
int found_piece = -1;
|
||||
|
||||
// TODO: there's still potential problems if some
|
||||
// pieces have the same hash
|
||||
// for the file not to be corrupt, piece_index <= slot_index
|
||||
for (int i = current_slot; i < m_info.num_pieces(); ++i)
|
||||
{
|
||||
if (pieces[i] && i != current_slot) continue;
|
||||
|
@ -1038,7 +1033,7 @@ namespace libtorrent
|
|||
, std::vector<bool>& have_pieces
|
||||
, const std::multimap<sha1_hash, int>& hash_to_piece)
|
||||
{
|
||||
assert(have_pieces.size() == m_info.num_pieces());
|
||||
assert((int)have_pieces.size() == m_info.num_pieces());
|
||||
|
||||
const int piece_size = m_info.piece_length();
|
||||
const int last_piece_size = m_info.piece_size(
|
||||
|
@ -1234,9 +1229,6 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
std::vector<char> piece_data(m_info.piece_length());
|
||||
const int piece_size = m_info.piece_length();
|
||||
const int last_piece_size = m_info.piece_size(
|
||||
m_info.num_pieces() - 1);
|
||||
|
||||
std::multimap<sha1_hash, int> hash_to_piece;
|
||||
// build the hash-map, that maps hashes to pieces
|
||||
|
@ -1329,7 +1321,7 @@ namespace libtorrent
|
|||
|
||||
if (m_free_slots.empty())
|
||||
{
|
||||
allocate_slots(5);
|
||||
allocate_slots(1);
|
||||
assert(!m_free_slots.empty());
|
||||
}
|
||||
|
||||
|
@ -1349,9 +1341,9 @@ namespace libtorrent
|
|||
if (*iter == m_info.num_pieces() - 1 && piece_index != *iter)
|
||||
{
|
||||
if (m_free_slots.size() == 1)
|
||||
allocate_slots(5);
|
||||
allocate_slots(1);
|
||||
assert(m_free_slots.size() > 1);
|
||||
// TODO: assumes that all allocated slots
|
||||
// assumes that all allocated slots
|
||||
// are put at the end of the free_slots vector
|
||||
iter = m_free_slots.end() - 1;
|
||||
}
|
||||
|
@ -1422,42 +1414,48 @@ namespace libtorrent
|
|||
{
|
||||
// this is used to notify potential other
|
||||
// threads that the allocation-function has exited
|
||||
struct allocation_cleanup
|
||||
struct allocation_syncronization
|
||||
{
|
||||
allocation_cleanup(bool& flag, boost::condition& cond)
|
||||
allocation_syncronization(
|
||||
bool& flag
|
||||
, boost::condition& cond
|
||||
, boost::mutex& monitor)
|
||||
: m_flag(flag)
|
||||
, m_cond(cond)
|
||||
{}
|
||||
|
||||
~allocation_cleanup()
|
||||
, m_monitor(monitor)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_monitor);
|
||||
|
||||
while (m_flag)
|
||||
m_cond.wait(lock);
|
||||
|
||||
m_flag = true;
|
||||
}
|
||||
|
||||
~allocation_syncronization()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_monitor);
|
||||
m_flag = false;
|
||||
m_cond.notify_one();
|
||||
}
|
||||
|
||||
bool& m_flag;
|
||||
boost::condition& m_cond;
|
||||
boost::mutex& m_monitor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// TODO: signal the m_allocating_condition on exit!
|
||||
void piece_manager::impl::allocate_slots(int num_slots)
|
||||
{
|
||||
assert(num_slots > 0);
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_allocating_monitor);
|
||||
|
||||
while (m_allocating)
|
||||
m_allocating_condition.wait(lock);
|
||||
|
||||
m_allocating = true;
|
||||
}
|
||||
|
||||
// this object will signal the other threads and
|
||||
// set m_allocating to false upon exit
|
||||
allocation_cleanup clean_obj(m_allocating, m_allocating_condition);
|
||||
// this object will syncronize the allocation with
|
||||
// potential other threads
|
||||
allocation_syncronization sync_obj(
|
||||
m_allocating
|
||||
, m_allocating_condition
|
||||
, m_allocating_monitor);
|
||||
|
||||
// synchronization ------------------------------------------------------
|
||||
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
||||
|
@ -1476,7 +1474,7 @@ namespace libtorrent
|
|||
++i)
|
||||
{
|
||||
int pos = m_unallocated_slots.front();
|
||||
int piece_pos = pos;
|
||||
// int piece_pos = pos;
|
||||
|
||||
int new_free_slot = pos;
|
||||
if (m_piece_to_slot[pos] != has_no_slot)
|
||||
|
@ -1516,8 +1514,8 @@ namespace libtorrent
|
|||
// ----------------------------------------------------------------------
|
||||
if (m_piece_to_slot.empty()) return;
|
||||
|
||||
assert(m_piece_to_slot.size() == m_info.num_pieces());
|
||||
assert(m_slot_to_piece.size() == m_info.num_pieces());
|
||||
assert((int)m_piece_to_slot.size() == m_info.num_pieces());
|
||||
assert((int)m_slot_to_piece.size() == m_info.num_pieces());
|
||||
|
||||
for (std::vector<int>::const_iterator i = m_free_slots.begin();
|
||||
i != m_free_slots.end();
|
||||
|
|
|
@ -745,7 +745,7 @@ namespace libtorrent
|
|||
|
||||
if (m_got_tracker_response == false)
|
||||
st.state = torrent_status::connecting_to_tracker;
|
||||
else if (m_num_pieces == m_have_pieces.size())
|
||||
else if (m_num_pieces == (int)m_have_pieces.size())
|
||||
st.state = torrent_status::seeding;
|
||||
else
|
||||
st.state = torrent_status::downloading;
|
||||
|
@ -774,9 +774,7 @@ namespace libtorrent
|
|||
try_next_tracker();
|
||||
}
|
||||
|
||||
// TODO: this function should also take the
|
||||
// HTTP-response code as an argument.
|
||||
// with some codes, we should just consider
|
||||
// TODO: with some response codes, we should just consider
|
||||
// the tracker as a failure and not retry
|
||||
// it anymore
|
||||
void torrent::tracker_request_error(int response_code, const std::string& str)
|
||||
|
|
|
@ -209,7 +209,9 @@ namespace libtorrent
|
|||
m_piece_hash.resize(num_pieces);
|
||||
|
||||
const std::string& hash_string = i->second.string();
|
||||
if (hash_string.length() != num_pieces * 20) throw invalid_torrent_file();
|
||||
if ((int)hash_string.length() != num_pieces * 20)
|
||||
throw invalid_torrent_file();
|
||||
|
||||
for (int i = 0; i < num_pieces; ++i)
|
||||
std::copy(hash_string.begin() + i*20, hash_string.begin() + (i+1)*20, m_piece_hash[i].begin());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue