diff --git a/docs/manual.html b/docs/manual.html index 863c3c5a9..6b0ab9318 100755 --- a/docs/manual.html +++ b/docs/manual.html @@ -13,109 +13,110 @@

Contents

@@ -180,8 +181,8 @@ boost.filesystem, boost.date_time and various other boost libraries as well as z

Fails on:

@@ -189,6 +190,7 @@ boost.filesystem, boost.date_time and various other boost libraries as well as z

libtorrent is released under the BSD-license.

@@ -339,6 +341,8 @@ class session: public boost::noncopyable void set_upload_rate_limit(int bytes_per_second); void set_download_rate_limit(int bytes_per_second); + void set_max_uploads(int limit); + void set_max_connections(int limit); session_status status() const; @@ -351,7 +355,6 @@ class session: public boost::noncopyable std::auto_ptr<alert> pop_alert(); void set_severity_level(alert::severity_t s); - };

Once it's created, the session object will spawn the main thread that will do all the work. @@ -440,6 +443,20 @@ you don't want to limit upload rate, you can set this to -1 (the default). set_download_rate_limit() works the same way but for download rate instead of upload rate.

+
+

set_max_uploads() set_max_connections()

+
+
+void set_max_uploads(int limit);
+void set_max_connections(int limit);
+
+
+

These functions will set a global limit on the number of unchoked peers (uploads) +and the number of connections opened. The number of connections is set to a hard +minimum of at least two connections per torrent, so if you set a too low +connections limit, and open too many torrents, the limit will not be met. The +number of uploads is at least one per torrent.

+

status()

@@ -981,8 +998,8 @@ sha1_hash info_hash() const;

info_hash() returns the info-hash for the torrent.

-
-

set_max_uploads() set_max_connections()

+
+

set_max_uploads() set_max_connections()

 void set_max_uploads(int max_uploads);
@@ -1030,8 +1047,8 @@ std::vector<char> const& metadata() const;
 .torrent file. This buffer will be valid as long as the torrent is still running. When hashed,
 it will produce the same hash as the info-hash.

-
-

status()

+
+

status()

 torrent_status status();
diff --git a/docs/manual.rst b/docs/manual.rst
index ad1fc1220..61326c084 100755
--- a/docs/manual.rst
+++ b/docs/manual.rst
@@ -68,13 +68,14 @@ libtorrent has been successfully compiled and tested on:
 
 	* Windows 2000 vc7.1
 	* Linux x86 (debian) GCC 3.0.4, GCC 3.2.3
-	* Windows 2000, msvc6 sp5 (does not support 64-bit values due to problems with operator<<(ostream&, __int64))
 	* MacOS X, GCC 3.3
+	* SunOS 5.8 GCC 3.1
 
 Fails on:
 
 	* GCC 2.95.4 (``std::ios_base`` is missing)
 	* Cygwin GCC 3.3.1 (builds but crashes)
+	* msvc6 sp5
 
 libtorrent is released under the BSD-license_.
 
@@ -238,6 +239,8 @@ The ``session`` class has the following synopsis::
 
 		void set_upload_rate_limit(int bytes_per_second);
 		void set_download_rate_limit(int bytes_per_second);
+		void set_max_uploads(int limit);
+		void set_max_connections(int limit);
 
 		session_status status() const;
 
@@ -250,7 +253,6 @@ The ``session`` class has the following synopsis::
 
 		std::auto_ptr pop_alert();
 		void set_severity_level(alert::severity_t s);
-
 	};
 
 Once it's created, the session object will spawn the main thread that will do all the work.
@@ -348,6 +350,21 @@ you don't want to limit upload rate, you can set this to -1 (the default).
 of upload rate.
 
 
+set_max_uploads() set_max_connections()
+---------------------------------------
+
+	::
+
+		void set_max_uploads(int limit);
+		void set_max_connections(int limit);
+
+These functions will set a global limit on the number of unchoked peers (uploads)
+and the number of connections opened. The number of connections is set to a hard
+minimum of at least two connections per torrent, so if you set a too low
+connections limit, and open too many torrents, the limit will not be met. The
+number of uploads is at least one per torrent.
+
+
 status()
 --------
 
diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp
index 7c65c0743..07dac7393 100755
--- a/include/libtorrent/peer_connection.hpp
+++ b/include/libtorrent/peer_connection.hpp
@@ -273,7 +273,6 @@ namespace libtorrent
 		// and how much we are allowed to use.
 		resource_request m_ul_bandwidth_quota;
 		resource_request m_dl_bandwidth_quota;
-		resource_request m_unchoked_quota;
 
 	private:
 
diff --git a/include/libtorrent/policy.hpp b/include/libtorrent/policy.hpp
index 90d363f63..4c3a179a3 100755
--- a/include/libtorrent/policy.hpp
+++ b/include/libtorrent/policy.hpp
@@ -107,17 +107,6 @@ namespace libtorrent
 		// the peer is not interested in our pieces
 		void not_interested(peer_connection& c);
 
-		void set_max_uploads(int num_unchoked);
-		int get_max_uploads() const { return m_max_uploads; }
-
-		/*
-			A limit on the number of sockets opened, for use on systems where a
-			user has a limited number of open file descriptors. And for windows
-			which has a buggy tcp-stack.
-		*/
-		void set_max_connections(int num_connected);
-		int get_max_connections() const { return m_max_connections; }
-
 #ifndef NDEBUG
 		bool has_connection(const peer_connection* p);
 
@@ -173,6 +162,11 @@ namespace libtorrent
 			return m_num_peers;
 		}
 
+		int num_uploads() const
+		{
+			return m_num_unchoked;
+		}
+
 	private:
 
 		bool unchoke_one_peer();
@@ -213,13 +207,6 @@ namespace libtorrent
 		int m_num_peers;
 		torrent* m_torrent;
 
-		// the total number of unchoked peers at
-		// any given time. If set to -1, it's unlimited.
-		// must be 2 or higher otherwise.
-		int m_max_uploads;
-
-		int m_max_connections;
-
 		// the number of unchoked peers
 		// at any given time
 		int m_num_unchoked;
diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp
index 68915617e..828a265bb 100755
--- a/include/libtorrent/session.hpp
+++ b/include/libtorrent/session.hpp
@@ -229,6 +229,8 @@ namespace libtorrent
 			// unlimited
 			int m_upload_rate;
 			int m_download_rate;
+			int m_max_uploads;
+			int m_max_connections;
 
 			// statistics gathered from all torrents.
 			stat m_stat;
@@ -327,9 +329,8 @@ namespace libtorrent
 		void set_http_settings(const http_settings& s);
 		void set_upload_rate_limit(int bytes_per_second);
 		void set_download_rate_limit(int bytes_per_second);
-
-		// TODO: global max connections setting
-		// TODO: global max uploads setting
+		void set_max_uploads(int limit);
+		void set_max_connections(int limit);
 
 		std::auto_ptr pop_alert();
 		void set_severity_level(alert::severity_t s);
diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp
index 22845cc6b..38754e05d 100755
--- a/include/libtorrent/torrent.hpp
+++ b/include/libtorrent/torrent.hpp
@@ -329,11 +329,13 @@ namespace libtorrent
 
 		resource_request m_ul_bandwidth_quota;
 		resource_request m_dl_bandwidth_quota;
-		resource_request m_unchoked_quota;
+		resource_request m_uploads_quota;
 		resource_request m_connections_quota;
 
 		void set_upload_limit(int limit);
 		void set_download_limit(int limit);
+		void set_max_uploads(int limit);
+		void set_max_connections(int limit);
 		bool move_storage(boost::filesystem::path const& save_path);
 
 		bool valid_metadata() const { return m_storage.get() != 0; }
diff --git a/include/libtorrent/torrent_info.hpp b/include/libtorrent/torrent_info.hpp
index d79d284e0..6b6f2454f 100755
--- a/include/libtorrent/torrent_info.hpp
+++ b/include/libtorrent/torrent_info.hpp
@@ -89,6 +89,7 @@ namespace libtorrent
 		torrent_info();
 		torrent_info(sha1_hash const& info_hash);
 		torrent_info(entry const& torrent_file);
+		~torrent_info();
 
 		entry create_torrent() const;
 		entry create_info_metadata() const;
diff --git a/src/allocate_resources.cpp b/src/allocate_resources.cpp
index 809d96e58..b6c08c851 100644
--- a/src/allocate_resources.cpp
+++ b/src/allocate_resources.cpp
@@ -113,16 +113,20 @@ namespace libtorrent
 			{
 				int sum_given = 0;
 				int sum_max = 0;
+				int sum_min = 0;
 				for (It i = m_start, end(m_end); i != end; ++i)
 				{
 					assert(((*i).*m_res).max >= 0);
+					assert(((*i).*m_res).min >= 0);
+					assert(((*i).*m_res).max >= ((*i).*m_res).min);
 					assert(((*i).*m_res).given >= 0);
 					assert(((*i).*m_res).given <= ((*i).*m_res).max);
 
 					sum_given = saturated_add(sum_given, ((*i).*m_res).given);
 					sum_max = saturated_add(sum_max, ((*i).*m_res).max);
+					sum_min = saturated_add(sum_min, ((*i).*m_res).min);
 				}
-				assert(sum_given == std::min(m_resources, sum_max));
+				assert(sum_given == std::min(std::max(m_resources, sum_min), sum_max));
 			}
 		};
 
@@ -171,6 +175,7 @@ namespace libtorrent
 			if (resources == 0 || sum_max == 0)
 				return;
 
+			resources = std::max(resources, sum_min);
 			int resources_to_distribute = std::min(resources, sum_max) - sum_min;
 			assert(resources_to_distribute >= 0);
 
diff --git a/src/policy.cpp b/src/policy.cpp
index 72591dab8..d93e9defb 100755
--- a/src/policy.cpp
+++ b/src/policy.cpp
@@ -324,8 +324,8 @@ namespace libtorrent
 	policy::policy(torrent* t)
 		: m_num_peers(0)
 		, m_torrent(t)
-		, m_max_uploads(std::numeric_limits::max())
-		, m_max_connections(std::numeric_limits::max())
+//		, m_max_uploads(std::numeric_limits::max())
+//		, m_max_connections(std::numeric_limits::max())
 		, m_num_unchoked(0)
 		, m_available_free_upload(0)
 		, m_last_optimistic_disconnect(boost::gregorian::date(1970,boost::gregorian::Jan,1))
@@ -593,10 +593,10 @@ namespace libtorrent
 				++num_connected_peers;
 		}
 
-		if (m_max_connections != std::numeric_limits::max())
+		if (m_torrent->m_connections_quota.given != std::numeric_limits::max())
 		{
 
-			int max_connections = m_max_connections;
+			int max_connections = m_torrent->m_connections_quota.given;
 
 			if (num_connected_peers >= max_connections)
 			{
@@ -622,7 +622,7 @@ namespace libtorrent
 			}
 		}
 
-		while (m_torrent->num_peers() < m_max_connections)
+		while (m_torrent->num_peers() < m_torrent->m_connections_quota.given)
 		{
 			if (!connect_one_peer())
 				break;
@@ -665,7 +665,7 @@ namespace libtorrent
 		// ------------------------
 		if (m_torrent->is_seed())
 		{
-			if (num_connected_peers > m_max_uploads)
+			if (num_connected_peers > m_torrent->m_uploads_quota.given)
 			{
 				// this means there are some peers that
 				// are choked. To have the choked peers
@@ -675,7 +675,7 @@ namespace libtorrent
 				seed_unchoke_one_peer();
 			}
 
-			while (m_num_unchoked > m_max_uploads)
+			while (m_num_unchoked > m_torrent->m_uploads_quota.given)
 			{
 				peer* p = find_seed_choke_candidate();
 				assert(p != 0);
@@ -686,7 +686,7 @@ namespace libtorrent
 
 			// make sure we have enough
 			// unchoked peers
-			while (m_num_unchoked < m_max_uploads)
+			while (m_num_unchoked < m_torrent->m_uploads_quota.given)
 			{
 				if (!seed_unchoke_one_peer()) break;
 			}
@@ -719,11 +719,11 @@ namespace libtorrent
 				}
 			}
 			
-			if (m_max_uploads < m_torrent->num_peers())
+			if (m_torrent->m_uploads_quota.given < m_torrent->num_peers())
 			{
 				// make sure we don't have too many
 				// unchoked peers
-				while (m_num_unchoked > m_max_uploads)
+				while (m_num_unchoked > m_torrent->m_uploads_quota.given)
 				{
 					peer* p = find_choke_candidate();
 					assert(p);
@@ -745,7 +745,8 @@ namespace libtorrent
 
 			// make sure we have enough
 			// unchoked peers
-			while (m_num_unchoked < m_max_uploads && unchoke_one_peer());
+			while (m_num_unchoked < m_torrent->m_uploads_quota.given
+				&& unchoke_one_peer());
 		}
 #ifndef NDEBUG
 		check_invariant();
@@ -776,7 +777,7 @@ namespace libtorrent
 
 		// TODO: only allow _one_ connection to use this
 		// override at a time
-		if (m_torrent->num_peers() >= m_max_connections
+		if (m_torrent->num_peers() >= m_torrent->m_connections_quota.given
 			&& c.get_socket()->sender().ip() != m_torrent->current_tracker().ip())
 		{
 			throw protocol_error("too many connections, refusing incoming connection"); // cause a disconnect
@@ -870,7 +871,7 @@ namespace libtorrent
 
 			if (i->banned) return;
 
-			if (m_torrent->num_peers() < m_max_connections
+			if (m_torrent->num_peers() < m_torrent->m_connections_quota.given
 				&& !m_torrent->is_paused())
 			{
 				connect_peer(&*i);
@@ -1001,7 +1002,7 @@ namespace libtorrent
 
 	bool policy::connect_one_peer()
 	{
-		if(m_torrent->num_peers() >= m_max_connections)
+		if(m_torrent->num_peers() >= m_torrent->m_connections_quota.given)
 			return false;
 		peer* p = find_connect_candidate();
 		if (p == 0) return false;
@@ -1083,21 +1084,6 @@ namespace libtorrent
 		i->connection = 0;
 	}
 
-	void policy::set_max_uploads(int max_uploads)
-	{
-		assert(max_uploads > 1 || max_uploads == -1);
-		if (max_uploads == -1) max_uploads = std::numeric_limits::max();
-		m_max_uploads = max_uploads;
-	}
-
-	void policy::set_max_connections(int max_connections)
-	{
-		assert(max_connections > 1 || max_connections == -1);
-		if (max_connections == -1) max_connections = std::numeric_limits::max();
-		assert(max_connections >= 2);
-		m_max_connections = max_connections;
-	}
-
 	void policy::peer_is_interesting(peer_connection& c)
 	{
 		c.send_interested();
@@ -1117,7 +1103,7 @@ namespace libtorrent
 
 	void policy::check_invariant() const
 	{
-		assert(m_max_uploads >= 2);
+		assert(m_torrent->m_uploads_quota.given >= 2);
 		int actual_unchoked = 0;
 		for (std::vector::const_iterator i = m_peers.begin();
 			i != m_peers.end();
@@ -1126,7 +1112,7 @@ namespace libtorrent
 			if (!i->connection) continue;
 			if (!i->connection->is_choked()) actual_unchoked++;
 		}
-		assert(actual_unchoked <= m_max_uploads);
+		assert(actual_unchoked <= m_torrent->m_uploads_quota.given);
 	}
 #endif
 
diff --git a/src/session.cpp b/src/session.cpp
index f9179244d..158fa4757 100755
--- a/src/session.cpp
+++ b/src/session.cpp
@@ -196,6 +196,8 @@ namespace libtorrent { namespace detail
 		, m_abort(false)
 		, m_upload_rate(-1)
 		, m_download_rate(-1)
+		, m_max_uploads(-1)
+		, m_max_connections(-1)
 		, m_incoming_connection(false)
 	{
 #ifndef NDEBUG
@@ -694,15 +696,24 @@ namespace libtorrent { namespace detail
 				, m_torrents
 				, &torrent::m_dl_bandwidth_quota);
 
+			allocate_resources(m_max_uploads == -1
+				? std::numeric_limits::max()
+				: m_max_uploads
+				, m_torrents
+				, &torrent::m_uploads_quota);
+
+			allocate_resources(m_max_connections == -1
+				? std::numeric_limits::max()
+				: m_max_connections
+				, m_torrents
+				, &torrent::m_connections_quota);
+
 			for (std::map >::iterator i
 				= m_torrents.begin(); i != m_torrents.end(); ++i)
 			{
 				i->second->distribute_resources();
 			}
 
-			// TODO: there's a problem when removing torrents while
-			// they're waiting for tracker response. The requester-pointer
-			// will become invalid.
 			m_tracker_manager.tick();
 		}
 
@@ -1045,6 +1056,20 @@ namespace libtorrent
 		m_checker_thread.join();
 	}
 
+	void session::set_max_uploads(int limit)
+	{
+		assert(limit > 0 || limit == -1);
+		boost::mutex::scoped_lock l(m_impl.m_mutex);
+		m_impl.m_max_uploads = limit;
+	}
+
+	void session::set_max_connections(int limit)
+	{
+		assert(limit > 0 || limit == -1);
+		boost::mutex::scoped_lock l(m_impl.m_mutex);
+		m_impl.m_max_connections = limit;
+	}
+
 	void session::set_upload_rate_limit(int bytes_per_second)
 	{
 		assert(bytes_per_second > 0 || bytes_per_second == -1);
diff --git a/src/torrent.cpp b/src/torrent.cpp
index bba6c269d..98ca935df 100755
--- a/src/torrent.cpp
+++ b/src/torrent.cpp
@@ -178,6 +178,11 @@ namespace libtorrent
 		, m_download_bandwidth_limit(std::numeric_limits::max())
 		, m_save_path(complete(save_path))
 	{
+		m_uploads_quota.min = 2;
+		m_connections_quota.min = 2;
+		m_uploads_quota.max = std::numeric_limits::max();
+		m_connections_quota.max = std::numeric_limits::max();
+
 		m_policy.reset(new policy(this));
 		bencode(std::back_inserter(m_metadata), metadata["info"]);
 		init();
@@ -215,6 +220,11 @@ namespace libtorrent
 		, m_download_bandwidth_limit(std::numeric_limits::max())
 		, m_save_path(complete(save_path))
 	{
+		m_uploads_quota.min = 2;
+		m_connections_quota.min = 2;
+		m_uploads_quota.max = std::numeric_limits::max();
+		m_connections_quota.max = std::numeric_limits::max();
+
 		m_trackers.push_back(announce_entry(tracker_url));
 		m_requested_metadata.resize(256, 0);
 		m_policy.reset(new policy(this));
@@ -534,7 +544,7 @@ namespace libtorrent
 		req.event = m_event;
 		req.url = m_trackers[m_currently_trying_tracker].url;
 		req.num_want = std::max(
-			(m_policy->get_max_connections()
+			(m_connections_quota.given
 			- m_policy->num_peers()), 0);
 
 		// default initialize, these should be set by caller
@@ -761,6 +771,20 @@ namespace libtorrent
 	}
 #endif
 
+	void torrent::set_max_uploads(int limit)
+	{
+		assert(limit >= -1);
+		if (limit == -1) limit = std::numeric_limits::max();
+		m_uploads_quota.max = std::max(m_uploads_quota.min, limit);
+	}
+
+	void torrent::set_max_connections(int limit)
+	{
+		assert(limit >= -1);
+		if (limit == -1) limit = std::numeric_limits::max();
+		m_connections_quota.max = std::max(m_connections_quota.min, limit);
+	}
+
 	void torrent::set_upload_limit(int limit)
 	{
 		assert(limit >= -1);
@@ -807,12 +831,8 @@ namespace libtorrent
 			return;
 		}
 
-		m_time_scaler--;
-		if (m_time_scaler <= 0)
-		{
-			m_time_scaler = 10;
-			m_policy->pulse();
-		}
+		m_connections_quota.used = (int)m_connections.size();
+		m_uploads_quota.used = m_policy->num_uploads();
 
 		m_ul_bandwidth_quota.used = 0;
 		m_ul_bandwidth_quota.max = 0;
@@ -844,7 +864,6 @@ namespace libtorrent
 			m_dl_bandwidth_quota.max = saturated_add(
 				m_dl_bandwidth_quota.max
 				, p->m_dl_bandwidth_quota.max);
-
 		}
 
 		m_ul_bandwidth_quota.max
@@ -859,6 +878,13 @@ namespace libtorrent
 
 	void torrent::distribute_resources()
 	{
+		m_time_scaler--;
+		if (m_time_scaler <= 0)
+		{
+			m_time_scaler = 10;
+			m_policy->pulse();
+		}
+
 		// distribute allowed upload among the peers
 		allocate_resources(m_ul_bandwidth_quota.given
 			, m_connections
@@ -869,8 +895,16 @@ namespace libtorrent
 			, m_connections
 			, &peer_connection::m_dl_bandwidth_quota);
 
+		using boost::bind;
+
 		// tell all peers to reset their used quota. This is
 		// a new second and they can again use up their quota
+/*
+		std::for_each(m_connections.begin(), m_connections.end()
+			, bind(&peer_connection::reset_upload_quota
+				, bind(&std::pair::second, _1)));
+*/
+
 		for (std::map::iterator i = m_connections.begin();
 			i != m_connections.end(); ++i)
 		{
diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp
index a7ad358d2..7fc818d09 100755
--- a/src/torrent_handle.cpp
+++ b/src/torrent_handle.cpp
@@ -70,6 +70,8 @@ namespace std
 };
 #endif
 
+using boost::bind;
+
 namespace libtorrent
 {
 
@@ -180,9 +182,7 @@ namespace libtorrent
 		assert(max_uploads >= 2 || max_uploads == -1);
 
 		call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&policy::set_max_uploads
-				, boost::bind(&torrent::get_policy, _1)
-				, max_uploads));
+			, bind(&torrent::set_max_uploads, _1, max_uploads));
 	}
 
 	void torrent_handle::use_interface(const char* net_interface)
@@ -190,7 +190,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::use_interface, _1, net_interface));
+			, bind(&torrent::use_interface, _1, net_interface));
 	}
 
 	void torrent_handle::set_max_connections(int max_connections)
@@ -198,8 +198,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&policy::set_max_connections
-				, boost::bind(&torrent::get_policy, _1), max_connections));
+			, bind(&torrent::set_max_connections, _1, max_connections));
 	}
 
 	void torrent_handle::set_upload_limit(int limit)
@@ -209,7 +208,7 @@ namespace libtorrent
 		assert(limit >= -1);
 
 		call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::set_upload_limit, _1, limit));
+			, bind(&torrent::set_upload_limit, _1, limit));
 	}
 
 	void torrent_handle::set_download_limit(int limit)
@@ -219,7 +218,7 @@ namespace libtorrent
 		assert(limit >= -1);
 
 		call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::set_download_limit, _1, limit));
+			, bind(&torrent::set_download_limit, _1, limit));
 	}
 
 	bool torrent_handle::move_storage(boost::filesystem::path const& save_path)
@@ -227,7 +226,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		return call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::move_storage, _1, save_path));
+			, bind(&torrent::move_storage, _1, save_path));
 	}
 
 	bool torrent_handle::has_metadata() const
@@ -235,7 +234,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		return call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::valid_metadata, _1));
+			, bind(&torrent::valid_metadata, _1));
 	}
 
 	bool torrent_handle::is_seed() const
@@ -243,7 +242,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		return call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::is_seed, _1));
+			, bind(&torrent::is_seed, _1));
 	}
 
 	bool torrent_handle::is_paused() const
@@ -251,7 +250,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		return call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::is_paused, _1));
+			, bind(&torrent::is_paused, _1));
 	}
 
 	void torrent_handle::pause()
@@ -259,7 +258,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::pause, _1));
+			, bind(&torrent::pause, _1));
 	}
 
 	void torrent_handle::resume()
@@ -267,7 +266,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::resume, _1));
+			, bind(&torrent::resume, _1));
 	}
 
 	void torrent_handle::set_tracker_login(std::string const& name, std::string const& password)
@@ -275,7 +274,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::set_tracker_login, _1, name, password));
+			, bind(&torrent::set_tracker_login, _1, name, password));
 	}
 
 
@@ -318,7 +317,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		return call_member const&>(m_ses
-			, m_chk, m_info_hash, boost::bind(&torrent::trackers, _1));
+			, m_chk, m_info_hash, bind(&torrent::trackers, _1));
 	}
 
 	void torrent_handle::replace_trackers(std::vector const& urls)
@@ -326,7 +325,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::replace_trackers, _1, urls));
+			, bind(&torrent::replace_trackers, _1, urls));
 	}
 
 	const torrent_info& torrent_handle::get_torrent_info() const
@@ -335,7 +334,7 @@ namespace libtorrent
 
 		if (!has_metadata()) throw invalid_handle();
 		return call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::torrent_file, _1));
+			, bind(&torrent::torrent_file, _1));
 	}
 
 	bool torrent_handle::is_valid() const
@@ -481,7 +480,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		return call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::save_path, _1));
+			, bind(&torrent::save_path, _1));
 	}
 
 	std::vector const& torrent_handle::metadata() const
@@ -489,7 +488,7 @@ namespace libtorrent
 		INVARIANT_CHECK;
 
 		return call_member const&>(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::metadata, _1));
+			, bind(&torrent::metadata, _1));
 	}
 
 	void torrent_handle::connect_peer(const address& adr) const
@@ -530,7 +529,7 @@ namespace libtorrent
 			ratio = 1.f;
 
 		call_member(m_ses, m_chk, m_info_hash
-			, boost::bind(&torrent::set_ratio, _1, ratio));
+			, bind(&torrent::set_ratio, _1, ratio));
 	}
 
 	void torrent_handle::get_peer_info(std::vector& v) const
diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp
index 23af26d3b..366b43fde 100755
--- a/src/torrent_info.cpp
+++ b/src/torrent_info.cpp
@@ -141,6 +141,9 @@ namespace libtorrent
 	{
 	}
 
+	torrent_info::~torrent_info()
+	{}
+
 	void torrent_info::set_piece_size(int size)
 	{
 		// make sure the size is an even 2 exponential