merge fix

This commit is contained in:
arvidn 2016-04-29 23:34:25 -04:00
commit 36a5a11ee2
20 changed files with 106 additions and 128 deletions

View File

@ -13,6 +13,7 @@
1.1.1 release
* fix set_settings in python binding
* Added missing alert categories in python binding
* Added dht_get_peers_reply_alert alert in python binding

View File

@ -102,16 +102,17 @@ namespace
void make_settings_pack(lt::settings_pack& p, dict const& sett_dict)
{
list iterkeys = (list)sett_dict.keys();
for (int i = 0; i < boost::python::len(iterkeys); i++)
int const len = boost::python::len(iterkeys);
for (int i = 0; i < len; i++)
{
std::string key = extract<std::string>(iterkeys[i]);
std::string const key = extract<std::string>(iterkeys[i]);
int sett = setting_by_name(key);
if (sett == 0) continue;
if (sett < 0) continue;
TORRENT_TRY
{
object value = sett_dict[key];
object const value = sett_dict[key];
switch (sett & settings_pack::type_mask)
{
case settings_pack::string_type_base:

View File

@ -182,8 +182,9 @@ class test_session(unittest.TestCase):
def test_apply_settings(self):
s = lt.session({})
s.apply_settings({'num_want': 66})
s.apply_settings({'num_want': 66, 'user_agent': 'test123'})
self.assertEqual(s.get_settings()['num_want'], 66)
self.assertEqual(s.get_settings()['user_agent'], 'test123')
if __name__ == '__main__':

View File

@ -5,7 +5,6 @@ nobase_include_HEADERS = \
add_torrent_params.hpp \
alert.hpp \
alert_manager.hpp \
alert_observer.hpp \
alert_types.hpp \
alloca.hpp \
allocator.hpp \
@ -202,4 +201,3 @@ nobase_include_HEADERS = \
kademlia/item.hpp \
kademlia/get_item.hpp \
kademlia/get_peers.hpp

View File

@ -1,58 +0,0 @@
/*
Copyright (c) 2012-2016, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_ALERT_OBSERVER_HPP_INCLUDED
#define TORRENT_ALERT_OBSERVER_HPP_INCLUDED
#include <boost/cstdint.hpp>
namespace libtorrent
{
class alert;
struct alert_observer
{
friend struct alert_handler;
alert_observer(): num_types(0), flags(0) {}
virtual void handle_alert(alert const* a) = 0;
private:
boost::uint8_t types[64];
int num_types;
int flags;
};
};
#endif // TORRENT_ALERT_OBSERVER_HPP_INCLUDED

View File

@ -779,7 +779,7 @@ namespace libtorrent
// the peer class all TCP peers belong to by default
// all tcp peer connections are subject to these
// bandwidth limits. Local peers are excempted
// bandwidth limits. Local peers are exempted
// from this limit. The purpose is to be able to
// throttle TCP that passes over the internet
// bottleneck (i.e. modem) to avoid starving out
@ -925,7 +925,7 @@ namespace libtorrent
int m_auto_manage_time_scaler;
// works like unchoke_time_scaler but it
// is only decresed when the unchoke set
// is only decreased when the unchoke set
// is recomputed, and when it reaches zero,
// the optimistic unchoke is moved to another peer.
// TODO: replace this by a proper asio timer
@ -979,7 +979,7 @@ namespace libtorrent
boost::uint16_t session_time() const TORRENT_OVERRIDE
{
// +1 is here to make it possible to distinguish uninitialized (to
// 0) timestamps and timestamps of things that happend during the
// 0) timestamps and timestamps of things that happened during the
// first second after the session was constructed
boost::int64_t const ret = total_seconds(aux::time_now()
- m_created) + 1;
@ -1053,7 +1053,8 @@ namespace libtorrent
libtorrent::utp_socket_manager m_utp_socket_manager;
#ifdef TORRENT_USE_OPENSSL
// used for uTP connectons over SSL
// used for uTP connections over SSL
udp_socket m_ssl_udp_socket;
libtorrent::utp_socket_manager m_ssl_utp_socket_manager;
#endif

View File

@ -44,7 +44,7 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
// The bitfiled type stores any number of bits as a bitfield
// The bitfield type stores any number of bits as a bitfield
// in a heap allocated array.
struct TORRENT_EXPORT bitfield
{
@ -55,7 +55,7 @@ namespace libtorrent
//
// The constructor taking a pointer ``b`` and ``bits`` copies a bitfield
// from the specified buffer, and ``bits`` number of bits (rounded up to
// the nearest byte boundry).
// the nearest byte boundary).
bitfield(): m_buf(NULL) {}
bitfield(int bits): m_buf(NULL)
{ resize(bits); }

View File

@ -157,4 +157,3 @@ namespace libtorrent
TORRENT_ASSERT(size() == bits);
}
}

View File

@ -87,7 +87,7 @@ namespace libtorrent
bool c2_quota_complete = !rhs->is_choked() && c2
> (std::max)(t2->torrent_file().piece_length() * pieces, 256 * 1024);
// if c2 has completed a quanta, it shuold be de-prioritized
// if c2 has completed a quanta, it should be de-prioritized
// and vice versa
if (c1_quota_complete < c2_quota_complete) return true;
if (c1_quota_complete > c2_quota_complete) return false;
@ -174,7 +174,7 @@ namespace libtorrent
// the anti-leech seeding algorithm is based on the paper "Improving
// BitTorrent: A Simple Approach" from Chow et. al. and ranks peers based
// on how many pieces they have, prefering to unchoke peers that just
// on how many pieces they have, preferring to unchoke peers that just
// started and peers that are close to completing. Like this:
// ^
// | \ / |
@ -417,4 +417,3 @@ namespace libtorrent
}
}

View File

@ -324,10 +324,8 @@ namespace libtorrent
, m_include_mtime((flags & modification_time) != 0)
, m_include_symlinks((flags & symlinks) != 0)
{
TORRENT_ASSERT(fs.num_files() > 0);
// return instead of crash in release mode
if (fs.num_files() == 0) return;
if (fs.num_files() == 0 || fs.total_size() == 0) return;
if (!m_multifile && has_parent_path(m_files.file_path(0))) m_multifile = true;
@ -386,6 +384,10 @@ namespace libtorrent
, m_include_symlinks(false)
{
TORRENT_ASSERT(ti.is_valid());
TORRENT_ASSERT(ti.num_pieces() > 0);
TORRENT_ASSERT(ti.num_files() > 0);
TORRENT_ASSERT(ti.total_size() > 0);
if (ti.creation_date()) m_creation_date = *ti.creation_date();
if (!ti.creator().empty()) set_creator(ti.creator().c_str());
@ -420,13 +422,13 @@ namespace libtorrent
entry create_torrent::generate() const
{
TORRENT_ASSERT(m_files.piece_length() > 0);
entry dict;
if (m_files.num_files() == 0)
if (m_files.num_files() == 0 || m_files.total_size() == 0)
return dict;
TORRENT_ASSERT(m_files.piece_length() > 0);
if (!m_urls.empty()) dict["announce"] = m_urls.front().first;
if (!m_nodes.empty())

View File

@ -443,6 +443,8 @@ namespace aux {
#if TORRENT_USE_ASSERTS
m_posting_torrent_updates = false;
#endif
update_time_now();
}
// This function is called by the creating thread, not in the message loop's

View File

@ -1345,7 +1345,6 @@ namespace libtorrent
if (m_abort)
{
piece_block block_finished(p.piece, p.start / block_size());
return;
}
@ -11474,4 +11473,3 @@ namespace libtorrent
#endif
}

View File

@ -471,7 +471,7 @@ public:
// we set our cwnd to 1 MSS. This condition can happen either because
// a packet has timed out and needs to be resent or because our
// cwnd is set to less than one MSS during congestion control.
// it can also happen if the other end sends an advertized window
// it can also happen if the other end sends an advertised window
// size less than one MSS.
time_point m_timeout;
@ -1819,7 +1819,7 @@ bool utp_socket_impl::send_pkt(int flags)
, effective_mtu - header_size);
// if we have one MSS worth of data, make sure it fits in our
// congestion window and the advertized receive window from
// congestion window and the advertised receive window from
// the other end.
if (m_bytes_in_flight + payload_size > (std::min)(int(m_cwnd >> 16)
, int(m_adv_wnd - m_bytes_in_flight)))
@ -2425,7 +2425,7 @@ void utp_socket_impl::ack_packet(packet* p, time_point const& receive_time
// this means our clock is not monotonic. Just assume the RTT was 100 ms
rtt = 100000;
// the clock for this plaform is not monotonic!
// the clock for this platform is not monotonic!
TORRENT_ASSERT(false);
}
@ -2543,7 +2543,7 @@ bool utp_socket_impl::consume_incoming_data(
{
// if we don't have a buffer from the upper layer, and the
// number of queued up bytes, waiting for the upper layer,
// exceeds the advertized receive window, start ignoring
// exceeds the advertised receive window, start ignoring
// more data packets
UTP_LOG("%8p: ERROR: our advertized window is not honored. "
"recv_buf: %d buffered_in: %d max_size: %d\n"
@ -2850,7 +2850,7 @@ bool utp_socket_impl::incoming_packet(aux::array_view<boost::uint8_t const> buf
{
// this is too far out to fit in our reorder buffer. Drop it
// This is either an attack to try to break the connection
// or a seariously damaged connection that lost a lot of
// or a seriously damaged connection that lost a lot of
// packets. Neither is very likely, and it should be OK
// to drop the timestamp information.
UTP_LOG("%8p: ERROR: incoming packet seq_nr:%d our ack_nr:%d (ignored)\n"
@ -3187,7 +3187,7 @@ bool utp_socket_impl::incoming_packet(aux::array_view<boost::uint8_t const> buf
{
// we need to ack some data we received, and we didn't
// end up sending any payload packets in the loop
// above (becasue m_out_packets would have been incremented
// above (because m_out_packets would have been incremented
// in that case). This means we need to send an ack.
// don't do it right away, because we may still receive
// more packets. defer the ack to send as few acks as possible
@ -3200,7 +3200,7 @@ bool utp_socket_impl::incoming_packet(aux::array_view<boost::uint8_t const> buf
if (m_state == UTP_STATE_ERROR_WAIT || m_state == UTP_STATE_DELETE) return true;
// Everything up to the FIN has been receieved, respond with a FIN
// Everything up to the FIN has been received, respond with a FIN
// from our side.
if (m_eof && m_ack_nr == ((m_eof_seq_nr - 1) & ACK_MASK))
{
@ -3404,7 +3404,7 @@ void utp_socket_impl::do_ledbat(const int acked_bytes, const int delay
// the portion of the in-flight bytes that were acked. This is used to make
// the gain factor be scaled by the rtt. The formula is applied once per
// rtt, or on every ACK skaled by the number of ACKs per rtt
// rtt, or on every ACK scaled by the number of ACKs per rtt
TORRENT_ASSERT(in_flight > 0);
TORRENT_ASSERT(acked_bytes > 0);
@ -3450,7 +3450,7 @@ void utp_socket_impl::do_ledbat(const int acked_bytes, const int delay
// bytes to cwnd
if (m_ssthres != 0 && ((m_cwnd + exponential_gain) >> 16) > m_ssthres)
{
// if we would exeed the slow start threshold by growing the cwnd
// if we would exceed the slow start threshold by growing the cwnd
// exponentially, don't do it, and leave slow-start mode. This
// make us avoid causing more delay and/or packet loss by being too
// aggressive
@ -3760,4 +3760,3 @@ void utp_socket_impl::check_invariant() const
}
#endif
}

View File

@ -89,7 +89,7 @@ struct dht_server
fprintf(stderr, "%s: DHT initialized on port %d\n", time_now_string(), m_port);
m_thread.reset(new thread(boost::bind(&dht_server::thread_fun, this)));
m_thread.reset(new libtorrent::thread(boost::bind(&dht_server::thread_fun, this)));
}
~dht_server()

View File

@ -92,7 +92,7 @@ struct peer_server
fprintf(stderr, "%s: PEER peer initialized on port %d\n", time_now_string(), m_port);
m_thread.reset(new thread(boost::bind(&peer_server::thread_fun, this)));
m_thread.reset(new libtorrent::thread(boost::bind(&peer_server::thread_fun, this)));
}
~peer_server()

View File

@ -258,7 +258,7 @@ TORRENT_TEST(wait_for_alert)
mgr.get_all(alerts);
start = clock_type::now();
thread posting_thread(boost::bind(&post_torrent_added, &mgr));
libtorrent::thread posting_thread(boost::bind(&post_torrent_added, &mgr));
a = mgr.wait_for_alert(seconds(10));
end = clock_type::now();

View File

@ -77,11 +77,11 @@ TORRENT_TEST(threads)
{
condition_variable cond;
libtorrent::mutex m;
std::list<thread*> threads;
std::list<libtorrent::thread*> threads;
int waiting = 0;
for (int i = 0; i < 20; ++i)
{
threads.push_back(new thread(boost::bind(&fun, &cond, &m, &waiting, i)));
threads.push_back(new libtorrent::thread(boost::bind(&fun, &cond, &m, &waiting, i)));
}
// make sure all threads are waiting on the condition_variable
@ -96,7 +96,7 @@ TORRENT_TEST(threads)
cond.notify_all();
l.unlock();
for (std::list<thread*>::iterator i = threads.begin(); i != threads.end(); ++i)
for (std::list<libtorrent::thread*>::iterator i = threads.begin(); i != threads.end(); ++i)
{
(*i)->join();
delete *i;
@ -107,8 +107,8 @@ TORRENT_TEST(threads)
boost::atomic<int> c(0);
for (int i = 0; i < 3; ++i)
{
threads.push_back(new thread(boost::bind(&increment, &cond, &m, &waiting, &c)));
threads.push_back(new thread(boost::bind(&decrement, &cond, &m, &waiting, &c)));
threads.push_back(new libtorrent::thread(boost::bind(&increment, &cond, &m, &waiting, &c)));
threads.push_back(new libtorrent::thread(boost::bind(&decrement, &cond, &m, &waiting, &c)));
}
// make sure all threads are waiting on the condition_variable
@ -123,7 +123,7 @@ TORRENT_TEST(threads)
cond.notify_all();
l.unlock();
for (std::list<thread*>::iterator i = threads.begin(); i != threads.end(); ++i)
for (std::list<libtorrent::thread*>::iterator i = threads.begin(); i != threads.end(); ++i)
{
(*i)->join();
delete *i;

View File

@ -83,10 +83,10 @@ TORRENT_TEST(time)
mutex m;
condition_variable cv;
thread t1(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
thread t2(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
thread t3(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
thread t4(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
libtorrent::thread t1(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
libtorrent::thread t2(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
libtorrent::thread t3(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
libtorrent::thread t4(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
test_sleep(100);

View File

@ -82,7 +82,7 @@ void test_running_torrent(boost::shared_ptr<torrent_info> info, boost::int64_t f
// test_sleep(500);
torrent_status st = h.status();
TEST_EQUAL(st.total_wanted, file_size * 3);
TEST_EQUAL(st.total_wanted, file_size); // we want the single file
TEST_EQUAL(st.total_wanted_done, 0);
std::vector<int> prio(info->num_files(), 1);
@ -90,7 +90,7 @@ void test_running_torrent(boost::shared_ptr<torrent_info> info, boost::int64_t f
h.prioritize_files(prio);
st = h.status();
TEST_EQUAL(st.total_wanted, file_size * 2);
TEST_EQUAL(st.total_wanted, 0); // we don't want anything
TEST_EQUAL(st.total_wanted_done, 0);
TEST_EQUAL(int(h.file_priorities().size()), info->num_files());
if (!st.is_seeding)
@ -129,13 +129,12 @@ void test_running_torrent(boost::shared_ptr<torrent_info> info, boost::int64_t f
std::vector<char> piece(info->piece_length());
for (int i = 0; i < int(piece.size()); ++i)
piece[i] = (i % 26) + 'A';
h.add_piece(0, &piece[0]);
h.add_piece(0, &piece[0], torrent_handle::overwrite_existing);
// wait until the piece is done writing and hashing
// TODO: wait for an alert rather than just waiting 10 seconds. This is kind of silly
test_sleep(2000);
wait_for_alert(ses, piece_finished_alert::alert_type, "piece_finished_alert");
st = h.status();
TEST_CHECK(st.pieces.size() > 0 && st.pieces[0] == true);
TEST_CHECK(st.pieces.size() > 0);
std::cout << "reading piece 0" << std::endl;
h.read_piece(0);
@ -146,7 +145,7 @@ void test_running_torrent(boost::shared_ptr<torrent_info> info, boost::int64_t f
if (rpa)
{
std::cout << "SUCCEEDED!" << std::endl;
TEST_CHECK(memcmp(&piece[0], rpa->buffer.get(), piece.size()) == 0);
TEST_CHECK(memcmp(&piece[0], rpa->buffer.get(), info->piece_size(0)) == 0);
TEST_CHECK(rpa->size == info->piece_size(0));
TEST_CHECK(rpa->piece == 0);
TEST_CHECK(hasher(&piece[0], int(piece.size())).final() == info->hash_for_piece(0));
@ -251,27 +250,50 @@ TORRENT_TEST(torrent)
{
file_storage fs;
fs.add_file("test_torrent_dir2/tmp1", 0);
fs.add_file("test_torrent_dir2/tmp1", 1024);
libtorrent::create_torrent t(fs, 128 * 1024, 6);
std::vector<char> piece(128 * 1024);
for (int i = 0; i < int(piece.size()); ++i)
piece[i] = (i % 26) + 'A';
// calculate the hash for all pieces
sha1_hash ph = hasher(&piece[0], piece.size()).final();
int num = t.num_pieces();
TEST_CHECK(t.num_pieces() > 0);
for (int i = 0; i < num; ++i)
t.set_hash(i, ph);
std::vector<char> tmp;
std::back_insert_iterator<std::vector<char> > out(tmp);
bencode(out, t.generate());
error_code ec;
boost::shared_ptr<torrent_info> info(boost::make_shared<torrent_info>(&tmp[0], tmp.size(), boost::ref(ec), 0));
test_running_torrent(info, 0);
test_running_torrent(info, 1024);
}
}
TORRENT_TEST(torrent_total_size_zero)
{
file_storage fs;
error_code ec;
fs.add_file("test_torrent_dir2/tmp1", 0);
libtorrent::create_torrent t(fs);
TEST_CHECK(fs.num_files() == 1);
TEST_CHECK(fs.total_size() == 0);
error_code ec;
set_piece_hashes(t, ".", ec);
ec.clear();
libtorrent::create_torrent t1(fs);
set_piece_hashes(t1, ".", ec);
TEST_CHECK(ec);
fs.add_file("test_torrent_dir2/tmp2", 0);
TEST_CHECK(fs.num_files() == 2);
TEST_CHECK(fs.total_size() == 0);
ec.clear();
libtorrent::create_torrent t2(fs);
set_piece_hashes(t2, ".", ec);
TEST_CHECK(ec);
}

View File

@ -60,6 +60,7 @@ struct udp_tracker
boost::detail::atomic_count m_udp_announces;
udp::socket m_socket;
int m_port;
bool m_abort;
boost::shared_ptr<libtorrent::thread> m_thread;
@ -77,12 +78,17 @@ struct udp_tracker
return;
}
if (m_abort)
{
return;
}
fprintf(stderr, "%s: UDP message %d bytes\n", time_now_string(), int(bytes_transferred));
char* ptr = buffer;
detail::read_uint64(ptr);
boost::uint32_t action = detail::read_uint32(ptr);
boost::uint32_t transaction_id = detail::read_uint32(ptr);
boost::uint32_t const action = detail::read_uint32(ptr);
boost::uint32_t const transaction_id = detail::read_uint32(ptr);
error_code e;
@ -140,6 +146,7 @@ struct udp_tracker
: m_udp_announces(0)
, m_socket(m_ios)
, m_port(0)
, m_abort(false)
{
error_code ec;
m_socket.open(udp::v4(), ec);
@ -164,13 +171,19 @@ struct udp_tracker
fprintf(stderr, "%s: UDP tracker initialized on port %d\n", time_now_string(), m_port);
m_thread.reset(new thread(boost::bind(&udp_tracker::thread_fun, this)));
m_thread.reset(new libtorrent::thread(boost::bind(&udp_tracker::thread_fun, this)));
}
void stop()
{
m_abort = true;
m_socket.cancel();
m_socket.close();
}
~udp_tracker()
{
m_socket.cancel();
m_socket.close();
m_ios.post(boost::bind(&udp_tracker::stop, this));
if (m_thread) m_thread->join();
}