libtorrent sync 1567, for many fixes, including upnp and run conditions

This commit is contained in:
Marcos Pinto 2007-09-16 07:56:11 +00:00
commit 3f89fd2753
21 changed files with 105 additions and 45 deletions

View file

@ -185,7 +185,7 @@ namespace libtorrent
~session_impl(); ~session_impl();
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*)> ext); void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext);
#endif #endif
void operator()(); void operator()();
@ -246,7 +246,8 @@ namespace libtorrent
, entry const& resume_data , entry const& resume_data
, bool compact_mode , bool compact_mode
, storage_constructor_type sc , storage_constructor_type sc
, bool paused); , bool paused
, void* userdata);
torrent_handle add_torrent( torrent_handle add_torrent(
char const* tracker_url char const* tracker_url
@ -256,7 +257,8 @@ namespace libtorrent
, entry const& resume_data , entry const& resume_data
, bool compact_mode , bool compact_mode
, storage_constructor_type sc , storage_constructor_type sc
, bool paused); , bool paused
, void* userdata);
void remove_torrent(torrent_handle const& h); void remove_torrent(torrent_handle const& h);
@ -519,7 +521,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
typedef std::list<boost::function<boost::shared_ptr< typedef std::list<boost::function<boost::shared_ptr<
torrent_plugin>(torrent*)> > extension_list_t; torrent_plugin>(torrent*, void*)> > extension_list_t;
extension_list_t m_extensions; extension_list_t m_extensions;
#endif #endif

View file

@ -52,6 +52,7 @@ namespace libtorrent
public: public:
broadcast_socket(asio::io_service& ios, udp::endpoint const& multicast_endpoint broadcast_socket(asio::io_service& ios, udp::endpoint const& multicast_endpoint
, receive_handler_t const& handler); , receive_handler_t const& handler);
~broadcast_socket() { close(); }
void send(char const* buffer, int size, asio::error_code& ec); void send(char const* buffer, int size, asio::error_code& ec);
void close(); void close();

View file

@ -50,6 +50,7 @@ namespace libtorrent
, buffer_size(0) , buffer_size(0)
, piece(0) , piece(0)
, offset(0) , offset(0)
, priority(0)
{} {}
enum action_t enum action_t
@ -72,6 +73,12 @@ namespace libtorrent
// to the error message // to the error message
std::string str; std::string str;
// priority decides whether or not this
// job will skip entries in the queue or
// not. It always skips in front of entries
// with lower priority
int priority;
// this is called when operation completes // this is called when operation completes
boost::function<void(int, disk_io_job const&)> callback; boost::function<void(int, disk_io_job const&)> callback;
}; };

View file

@ -149,6 +149,12 @@ namespace libtorrent
virtual bool on_cancel(peer_request const& req) virtual bool on_cancel(peer_request const& req)
{ return false; } { return false; }
virtual bool on_reject(peer_request const& req)
{ return false; }
virtual bool on_suggest(int index)
{ return false; }
// called when an extended message is received. If returning true, // called when an extended message is received. If returning true,
// the message is not processed by any other plugin and if false // the message is not processed by any other plugin and if false
// is returned the next plugin in the chain will receive it to // is returned the next plugin in the chain will receive it to

View file

@ -48,7 +48,7 @@ namespace libtorrent
{ {
struct torrent_plugin; struct torrent_plugin;
class torrent; class torrent;
TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_metadata_plugin(torrent*); TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_metadata_plugin(torrent*, void*);
} }
#endif // TORRENT_METADATA_TRANSFER_HPP_INCLUDED #endif // TORRENT_METADATA_TRANSFER_HPP_INCLUDED

View file

@ -48,7 +48,7 @@ namespace libtorrent
{ {
struct torrent_plugin; struct torrent_plugin;
class torrent; class torrent;
TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_ut_pex_plugin(torrent*); TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_ut_pex_plugin(torrent*, void*);
} }
#endif // TORRENT_UT_PEX_EXTENSION_HPP_INCLUDED #endif // TORRENT_UT_PEX_EXTENSION_HPP_INCLUDED

View file

@ -72,7 +72,8 @@ namespace libtorrent
dht = 0x2, dht = 0x2,
pex = 0x4, pex = 0x4,
lsd = 0x8, lsd = 0x8,
resume_data = 0x10 resume_data = 0x10,
incoming = 0x20
}; };
int source; int source;

View file

@ -233,7 +233,7 @@ namespace libtorrent
bool is_finished(piece_block block) const; bool is_finished(piece_block block) const;
// marks this piece-block as queued for downloading // marks this piece-block as queued for downloading
void mark_as_downloading(piece_block block, void* peer bool mark_as_downloading(piece_block block, void* peer
, piece_state_t s); , piece_state_t s);
void mark_as_writing(piece_block block, void* peer); void mark_as_writing(piece_block block, void* peer);
void mark_as_finished(piece_block block, void* peer); void mark_as_finished(piece_block block, void* peer);

View file

@ -150,7 +150,8 @@ namespace libtorrent
, entry const& resume_data = entry() , entry const& resume_data = entry()
, bool compact_mode = true , bool compact_mode = true
, bool paused = false , bool paused = false
, storage_constructor_type sc = default_storage_constructor); , storage_constructor_type sc = default_storage_constructor
, void* userdata = 0);
torrent_handle add_torrent( torrent_handle add_torrent(
char const* tracker_url char const* tracker_url
@ -160,7 +161,8 @@ namespace libtorrent
, entry const& resume_data = entry() , entry const& resume_data = entry()
, bool compact_mode = true , bool compact_mode = true
, bool paused = false , bool paused = false
, storage_constructor_type sc = default_storage_constructor); , storage_constructor_type sc = default_storage_constructor
, void* userdata = 0);
session_proxy abort() { return session_proxy(m_impl); } session_proxy abort() { return session_proxy(m_impl); }
@ -181,7 +183,7 @@ namespace libtorrent
#endif #endif
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*)> ext); void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext);
#endif #endif
void set_ip_filter(ip_filter const& f); void set_ip_filter(ip_filter const& f);

View file

@ -202,7 +202,8 @@ namespace libtorrent
void async_read( void async_read(
peer_request const& r peer_request const& r
, boost::function<void(int, disk_io_job const&)> const& handler , boost::function<void(int, disk_io_job const&)> const& handler
, char* buffer = 0); , char* buffer = 0
, int priority = 0);
void async_write( void async_write(
peer_request const& r peer_request const& r

View file

@ -60,8 +60,6 @@ namespace libtorrent
{ {
// ignore the loopback // ignore the loopback
if (i->endpoint().address() == address_v4((127 << 24) + 1)) continue; if (i->endpoint().address() == address_v4((127 << 24) + 1)) continue;
// ignore addresses that are not on a local network
if (!is_local(i->endpoint().address())) continue;
// ignore non-IPv4 addresses // ignore non-IPv4 addresses
if (i->endpoint().address().is_v4()) break; if (i->endpoint().address().is_v4()) break;
} }
@ -96,17 +94,24 @@ namespace libtorrent
if (ec) continue; if (ec) continue;
s->set_option(datagram_socket::reuse_address(true), ec); s->set_option(datagram_socket::reuse_address(true), ec);
if (ec) continue; if (ec) continue;
s->bind(udp::endpoint(*i, 0), ec); s->bind(udp::endpoint(address_v4::any(), multicast_endpoint.port()), ec);
if (ec) continue; if (ec) continue;
s->set_option(join_group(multicast_endpoint.address()), ec); s->set_option(join_group(multicast_endpoint.address()), ec);
if (ec) continue; if (ec) continue;
s->set_option(outbound_interface(i->to_v4()), ec); s->set_option(outbound_interface(i->to_v4()), ec);
if (ec) continue; if (ec) continue;
s->set_option(hops(255)); s->set_option(hops(255), ec);
if (ec) continue;
s->set_option(enable_loopback(true), ec);
if (ec) continue;
m_sockets.push_back(socket_entry(s)); m_sockets.push_back(socket_entry(s));
socket_entry& se = m_sockets.back(); socket_entry& se = m_sockets.back();
s->async_receive_from(asio::buffer(se.buffer, sizeof(se.buffer)) s->async_receive_from(asio::buffer(se.buffer, sizeof(se.buffer))
, se.remote, bind(&broadcast_socket::on_receive, this, &se, _1, _2)); , se.remote, bind(&broadcast_socket::on_receive, this, &se, _1, _2));
#ifndef NDEBUG
// std::cerr << "broadcast socket [ if: " << i->to_v4().to_string()
// << " group: " << multicast_endpoint.address() << " ]" << std::endl;
#endif
} }
} }
@ -117,7 +122,9 @@ namespace libtorrent
{ {
asio::error_code e; asio::error_code e;
i->socket->send_to(asio::buffer(buffer, size), m_multicast_endpoint, 0, e); i->socket->send_to(asio::buffer(buffer, size), m_multicast_endpoint, 0, e);
#ifndef NDEBUG
// std::cerr << " sending on " << i->socket->local_endpoint().address().to_string() << std::endl; // std::cerr << " sending on " << i->socket->local_endpoint().address().to_string() << std::endl;
#endif
if (e) ec = e; if (e) ec = e;
} }
} }

View file

@ -1221,7 +1221,7 @@ namespace libtorrent
{ {
tcp::endpoint adr(remote().address() tcp::endpoint adr(remote().address()
, (unsigned short)listen_port->integer()); , (unsigned short)listen_port->integer());
t->get_policy().peer_from_tracker(adr, pid(), 0, 0); t->get_policy().peer_from_tracker(adr, pid(), peer_info::incoming, 0);
} }
} }
// there should be a version too // there should be a version too

View file

@ -89,8 +89,15 @@ namespace libtorrent
namespace namespace
{ {
// The semantic of this operator is:
// shouls lhs come before rhs in the job queue
bool operator<(disk_io_job const& lhs, disk_io_job const& rhs) bool operator<(disk_io_job const& lhs, disk_io_job const& rhs)
{ {
// NOTE: comparison inverted to make higher priority
// skip _in_front_of_ lower priority
if (lhs.priority > rhs.priority) return true;
if (lhs.priority < rhs.priority) return false;
if (lhs.storage.get() < rhs.storage.get()) return true; if (lhs.storage.get() < rhs.storage.get()) return true;
if (lhs.storage.get() > rhs.storage.get()) return false; if (lhs.storage.get() > rhs.storage.get()) return false;
if (lhs.piece < rhs.piece) return true; if (lhs.piece < rhs.piece) return true;

View file

@ -247,19 +247,16 @@ namespace libtorrent
void set_size(size_type s) void set_size(size_type s)
{ {
size_type pos = tell(); #ifdef _WIN32
// Only set size if current file size not equals s. #error file.cpp is for posix systems only. use file_win.cpp on windows
// 2 as "m" argument is to be sure seek() sets SEEK_END on #else
// all compilers. if (ftruncate(m_fd, s) < 0)
if(s != seek(0, 2))
{ {
seek(s - 1); std::stringstream msg;
char dummy = 0; msg << "ftruncate failed: '" << strerror(errno);
read(&dummy, 1); throw file_error(msg.str());
seek(s - 1);
write(&dummy, 1);
} }
seek(pos); #endif
} }
size_type seek(size_type offset, int m = 1) size_type seek(size_type offset, int m = 1)

View file

@ -556,7 +556,7 @@ namespace libtorrent { namespace
namespace libtorrent namespace libtorrent
{ {
boost::shared_ptr<torrent_plugin> create_metadata_plugin(torrent* t) boost::shared_ptr<torrent_plugin> create_metadata_plugin(torrent* t, void*)
{ {
return boost::shared_ptr<torrent_plugin>(new metadata_plugin(*t)); return boost::shared_ptr<torrent_plugin>(new metadata_plugin(*t));
} }

View file

@ -687,6 +687,14 @@ namespace libtorrent
boost::shared_ptr<torrent> t = m_torrent.lock(); boost::shared_ptr<torrent> t = m_torrent.lock();
assert(t); assert(t);
#ifndef TORRENT_DISABLE_EXTENSIONS
for (extension_list_t::iterator i = m_extensions.begin()
, end(m_extensions.end()); i != end; ++i)
{
if ((*i)->on_reject(r)) return;
}
#endif
std::deque<piece_block>::iterator i = std::find_if( std::deque<piece_block>::iterator i = std::find_if(
m_download_queue.begin(), m_download_queue.end() m_download_queue.begin(), m_download_queue.end()
, bind(match_request, boost::cref(r), _1, t->block_size())); , bind(match_request, boost::cref(r), _1, t->block_size()));
@ -743,7 +751,7 @@ namespace libtorrent
void peer_connection::incoming_suggest(int index) void peer_connection::incoming_suggest(int index)
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
#ifdef TORRENT_VERBOSE_LOGGING #ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << time_now_string() (*m_logger) << time_now_string()
<< " <== SUGGEST_PIECE [ piece: " << index << " ]\n"; << " <== SUGGEST_PIECE [ piece: " << index << " ]\n";
@ -751,6 +759,14 @@ namespace libtorrent
boost::shared_ptr<torrent> t = m_torrent.lock(); boost::shared_ptr<torrent> t = m_torrent.lock();
if (!t) return; if (!t) return;
#ifndef TORRENT_DISABLE_EXTENSIONS
for (extension_list_t::iterator i = m_extensions.begin()
, end(m_extensions.end()); i != end; ++i)
{
if ((*i)->on_suggest(index)) return;
}
#endif
if (t->have_piece(index)) return; if (t->have_piece(index)) return;
if (m_suggested_pieces.size() > 9) if (m_suggested_pieces.size() > 9)
@ -1647,7 +1663,9 @@ namespace libtorrent
state = piece_picker::slow; state = piece_picker::slow;
} }
t->picker().mark_as_downloading(block, peer_info_struct(), state); if (!t->picker().mark_as_downloading(block, peer_info_struct(), state))
return;
if (t->alerts().should_post(alert::info)) if (t->alerts().should_post(alert::info))
{ {
t->alerts().post_alert(block_downloading_alert(t->get_handle(), t->alerts().post_alert(block_downloading_alert(t->get_handle(),

View file

@ -1229,6 +1229,7 @@ namespace libtorrent
bool piece_picker::can_pick(int piece, std::vector<bool> const& bitmask) const bool piece_picker::can_pick(int piece, std::vector<bool> const& bitmask) const
{ {
assert(piece >= 0 && piece < int(m_piece_map.size()));
return bitmask[piece] return bitmask[piece]
&& !m_piece_map[piece].have() && !m_piece_map[piece].have()
&& !m_piece_map[piece].downloading && !m_piece_map[piece].downloading
@ -1554,7 +1555,7 @@ namespace libtorrent
} }
void piece_picker::mark_as_downloading(piece_block block bool piece_picker::mark_as_downloading(piece_block block
, void* peer, piece_state_t state) , void* peer, piece_state_t state)
{ {
TORRENT_PIECE_PICKER_INVARIANT_CHECK; TORRENT_PIECE_PICKER_INVARIANT_CHECK;
@ -1589,6 +1590,9 @@ namespace libtorrent
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index)); = std::find_if(m_downloads.begin(), m_downloads.end(), has_index(block.piece_index));
assert(i != m_downloads.end()); assert(i != m_downloads.end());
block_info& info = i->info[block.block_index]; block_info& info = i->info[block.block_index];
if (info.state == block_info::state_writing
|| info.state == block_info::state_finished)
return false;
assert(info.state == block_info::state_none assert(info.state == block_info::state_none
|| (info.state == block_info::state_requested || (info.state == block_info::state_requested
&& (info.num_peers > 0))); && (info.num_peers > 0)));
@ -1601,6 +1605,7 @@ namespace libtorrent
++info.num_peers; ++info.num_peers;
if (i->state == none) i->state = state; if (i->state == none) i->state = state;
} }
return true;
} }
int piece_picker::num_peers(piece_block block) const int piece_picker::num_peers(piece_block block) const

View file

@ -132,7 +132,7 @@ namespace libtorrent
m_impl->abort(); m_impl->abort();
} }
void session::add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*)> ext) void session::add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext)
{ {
m_impl->add_extension(ext); m_impl->add_extension(ext);
} }
@ -185,7 +185,7 @@ namespace libtorrent
assert(!ti.m_half_metadata); assert(!ti.m_half_metadata);
boost::intrusive_ptr<torrent_info> tip(new torrent_info(ti)); boost::intrusive_ptr<torrent_info> tip(new torrent_info(ti));
return m_impl->add_torrent(tip, save_path, resume_data return m_impl->add_torrent(tip, save_path, resume_data
, compact_mode, sc, paused); , compact_mode, sc, paused, 0);
} }
torrent_handle session::add_torrent( torrent_handle session::add_torrent(
@ -194,11 +194,12 @@ namespace libtorrent
, entry const& resume_data , entry const& resume_data
, bool compact_mode , bool compact_mode
, bool paused , bool paused
, storage_constructor_type sc) , storage_constructor_type sc
, void* userdata)
{ {
assert(!ti->m_half_metadata); assert(!ti->m_half_metadata);
return m_impl->add_torrent(ti, save_path, resume_data return m_impl->add_torrent(ti, save_path, resume_data
, compact_mode, sc, paused); , compact_mode, sc, paused, userdata);
} }
torrent_handle session::add_torrent( torrent_handle session::add_torrent(
@ -209,10 +210,11 @@ namespace libtorrent
, entry const& e , entry const& e
, bool compact_mode , bool compact_mode
, bool paused , bool paused
, storage_constructor_type sc) , storage_constructor_type sc
, void* userdata)
{ {
return m_impl->add_torrent(tracker_url, info_hash, name, save_path, e return m_impl->add_torrent(tracker_url, info_hash, name, save_path, e
, compact_mode, sc, paused); , compact_mode, sc, paused, userdata);
} }
void session::remove_torrent(const torrent_handle& h) void session::remove_torrent(const torrent_handle& h)

View file

@ -593,7 +593,7 @@ namespace detail
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
void session_impl::add_extension( void session_impl::add_extension(
boost::function<boost::shared_ptr<torrent_plugin>(torrent*)> ext) boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext)
{ {
m_extensions.push_back(ext); m_extensions.push_back(ext);
} }
@ -1474,7 +1474,8 @@ namespace detail
, entry const& resume_data , entry const& resume_data
, bool compact_mode , bool compact_mode
, storage_constructor_type sc , storage_constructor_type sc
, bool paused) , bool paused
, void* userdata)
{ {
// if you get this assert, you haven't managed to // if you get this assert, you haven't managed to
// open a listen port. call listen_on() first. // open a listen port. call listen_on() first.
@ -1514,7 +1515,7 @@ namespace detail
for (extension_list_t::iterator i = m_extensions.begin() for (extension_list_t::iterator i = m_extensions.begin()
, end(m_extensions.end()); i != end; ++i) , end(m_extensions.end()); i != end; ++i)
{ {
boost::shared_ptr<torrent_plugin> tp((*i)(torrent_ptr.get())); boost::shared_ptr<torrent_plugin> tp((*i)(torrent_ptr.get(), userdata));
if (tp) torrent_ptr->add_extension(tp); if (tp) torrent_ptr->add_extension(tp);
} }
#endif #endif
@ -1554,7 +1555,8 @@ namespace detail
, entry const& , entry const&
, bool compact_mode , bool compact_mode
, storage_constructor_type sc , storage_constructor_type sc
, bool paused) , bool paused
, void* userdata)
{ {
// TODO: support resume data in this case // TODO: support resume data in this case
@ -1593,7 +1595,7 @@ namespace detail
for (extension_list_t::iterator i = m_extensions.begin() for (extension_list_t::iterator i = m_extensions.begin()
, end(m_extensions.end()); i != end; ++i) , end(m_extensions.end()); i != end; ++i)
{ {
boost::shared_ptr<torrent_plugin> tp((*i)(torrent_ptr.get())); boost::shared_ptr<torrent_plugin> tp((*i)(torrent_ptr.get(), userdata));
if (tp) torrent_ptr->add_extension(tp); if (tp) torrent_ptr->add_extension(tp);
} }
#endif #endif

View file

@ -1084,7 +1084,8 @@ namespace libtorrent
void piece_manager::async_read( void piece_manager::async_read(
peer_request const& r peer_request const& r
, boost::function<void(int, disk_io_job const&)> const& handler , boost::function<void(int, disk_io_job const&)> const& handler
, char* buffer) , char* buffer
, int priority)
{ {
disk_io_job j; disk_io_job j;
j.storage = this; j.storage = this;
@ -1093,6 +1094,7 @@ namespace libtorrent
j.offset = r.start; j.offset = r.start;
j.buffer_size = r.length; j.buffer_size = r.length;
j.buffer = buffer; j.buffer = buffer;
j.priority = priority;
// if a buffer is not specified, only one block can be read // if a buffer is not specified, only one block can be read
// since that is the size of the pool allocator's buffers // since that is the size of the pool allocator's buffers
assert(r.length <= 16 * 1024 || buffer != 0); assert(r.length <= 16 * 1024 || buffer != 0);

View file

@ -347,7 +347,7 @@ namespace libtorrent { namespace
namespace libtorrent namespace libtorrent
{ {
boost::shared_ptr<torrent_plugin> create_ut_pex_plugin(torrent* t) boost::shared_ptr<torrent_plugin> create_ut_pex_plugin(torrent* t, void*)
{ {
if (t->torrent_file().priv()) if (t->torrent_file().priv())
{ {