removed the session mutex for improved performance

This commit is contained in:
Arvid Norberg 2010-07-14 04:16:38 +00:00
parent 3310198dae
commit 4e576f93fd
21 changed files with 753 additions and 566 deletions

View File

@ -1,3 +1,4 @@
* removed the session mutex for improved performance
* added upload and download activity timer stats for torrents * added upload and download activity timer stats for torrents
* made the reuse-address flag configurable on the listen socket * made the reuse-address flag configurable on the listen socket
* moved UDP trackers over to use a single socket * moved UDP trackers over to use a single socket

View File

@ -480,23 +480,26 @@ class session: public boost::noncopyable
int num_uploads() const; int num_uploads() const;
int num_connections() const; int num_connections() const;
bool load_asnum_db(char const* file); void load_asnum_db(char const* file);
bool load_asnum_db(wchar_t const* file); void load_asnum_db(wchar_t const* file);
bool load_country_db(char const* file); void load_country_db(char const* file);
bool load_country_db(wchar_t const* file); void load_country_db(wchar_t const* file);
int as_for_ip(address const& adr); int as_for_ip(address const& adr);
void set_ip_filter(ip_filter const& f); void set_ip_filter(ip_filter const& f);
ip_filter const& get_ip_filter() const; ip_filter get_ip_filter() const;
session_status status() const; session_status status() const;
cache_status get_cache_status() const; cache_status get_cache_status() const;
bool is_listening() const; bool is_listening() const;
unsigned short listen_port() const; unsigned short listen_port() const;
enum { listen_reuse_address = 1 };
bool listen_on( bool listen_on(
std::pair<int, int> const& port_range std::pair<int, int> const& port_range
, char const* interface = 0); , char const* interface = 0
, int flags = 0);
std::auto_ptr<alert> pop_alert(); std::auto_ptr<alert> pop_alert();
alert const* wait_for_alert(time_duration max_wait); alert const* wait_for_alert(time_duration max_wait);
@ -706,12 +709,9 @@ There are 3 different modes:</p>
<dd>All pieces will be written to the place where they belong and sparse files <dd>All pieces will be written to the place where they belong and sparse files
will be used. This is the recommended, and default mode.</dd> will be used. This is the recommended, and default mode.</dd>
<dt>storage_mode_allocate</dt> <dt>storage_mode_allocate</dt>
<dd>Same as <tt class="docutils literal"><span class="pre">storage_mode_sparse</span></tt> except that files will be ftruncated on <dd>All pieces will be written to their final position, all files will be
startup (SetEndOfFile() on windows). For filesystem that supports sparse allocated in full when the torrent is first started. This is done with
files, this is in all practical aspects identical to sparse mode. For <tt class="docutils literal"><span class="pre">fallocate()</span></tt> and similar calls. This mode minimizes fragmentation.</dd>
filesystems that don't, it will allocate the data for the files. The mac
filesystem HFS+ doesn't support sparse files, it will allocate the files
with zeroes.</dd>
<dt>storage_mode_compact</dt> <dt>storage_mode_compact</dt>
<dd>The storage will grow as more pieces are downloaded, and pieces <dd>The storage will grow as more pieces are downloaded, and pieces
are rearranged to finally be in their correct places once the entire torrent has been are rearranged to finally be in their correct places once the entire torrent has been
@ -892,10 +892,10 @@ to 8 on windows.</p>
<h2>load_asnum_db() load_country_db() int as_for_ip()</h2> <h2>load_asnum_db() load_country_db() int as_for_ip()</h2>
<blockquote> <blockquote>
<pre class="literal-block"> <pre class="literal-block">
bool load_asnum_db(char const* file); void load_asnum_db(char const* file);
bool load_asnum_db(wchar_t const* file); void load_asnum_db(wchar_t const* file);
bool load_country_db(char const* file); void load_country_db(char const* file);
bool load_country_db(wchar_t const* file); void load_country_db(wchar_t const* file);
int as_for_ip(address const&amp; adr); int as_for_ip(address const&amp; adr);
</pre> </pre>
</blockquote> </blockquote>
@ -925,7 +925,7 @@ generated.</p>
<blockquote> <blockquote>
<dl class="docutils"> <dl class="docutils">
<dt>::</dt> <dt>::</dt>
<dd>ip_filter const&amp; get_ip_filter() const;</dd> <dd>ip_filter get_ip_filter() const;</dd>
</dl> </dl>
</blockquote> </blockquote>
<p>Returns the ip_filter currently in the session. See <a class="reference internal" href="#ip-filter">ip_filter</a>.</p> <p>Returns the ip_filter currently in the session. See <a class="reference internal" href="#ip-filter">ip_filter</a>.</p>
@ -1130,7 +1130,8 @@ bool is_listening() const;
unsigned short listen_port() const; unsigned short listen_port() const;
bool listen_on( bool listen_on(
std::pair&lt;int, int&gt; const&amp; port_range std::pair&lt;int, int&gt; const&amp; port_range
, char const* interface = 0); , char const* interface = 0
, int flags = 0);
</pre> </pre>
</blockquote> </blockquote>
<p><tt class="docutils literal"><span class="pre">is_listening()</span></tt> will tell you whether or not the session has successfully <p><tt class="docutils literal"><span class="pre">is_listening()</span></tt> will tell you whether or not the session has successfully
@ -1156,6 +1157,10 @@ want to listen on. If you don't specify an interface, libtorrent may attempt to
listen on multiple interfaces (typically 0.0.0.0 and ::). This means that if your listen on multiple interfaces (typically 0.0.0.0 and ::). This means that if your
IPv6 interface doesn't work, you may still see a <a class="reference internal" href="#listen-failed-alert">listen_failed_alert</a>, even though IPv6 interface doesn't work, you may still see a <a class="reference internal" href="#listen-failed-alert">listen_failed_alert</a>, even though
the IPv4 port succeeded.</p> the IPv4 port succeeded.</p>
<p>The <tt class="docutils literal"><span class="pre">flags</span></tt> parameter can either be 0 or <tt class="docutils literal"><span class="pre">session::listen_reuse_address</span></tt>, which
will set the reuse address socket option on the listen socket(s). By default, the
listen socket does not use reuse address. If you're running a service that needs
to run on a specific port no matter if it's in use, set this flag.</p>
<p>If you're also starting the DHT, it is a good idea to do that after you've called <p>If you're also starting the DHT, it is a good idea to do that after you've called
<tt class="docutils literal"><span class="pre">listen_on()</span></tt>, since the default listen port for the DHT is the same as the tcp <tt class="docutils literal"><span class="pre">listen_on()</span></tt>, since the default listen port for the DHT is the same as the tcp
listen socket. If you start the DHT first, it will assume the tcp port is free and listen socket. If you start the DHT first, it will assume the tcp port is free and
@ -1298,10 +1303,10 @@ it only has any effect if the proxy supports UDP.</p>
<h2>peer_proxy() web_seed_proxy() tracker_proxy() dht_proxy()</h2> <h2>peer_proxy() web_seed_proxy() tracker_proxy() dht_proxy()</h2>
<blockquote> <blockquote>
<pre class="literal-block"> <pre class="literal-block">
proxy_settings const&amp; peer_proxy() const; proxy_settings peer_proxy() const;
proxy_settings const&amp; web_seed_proxy() const; proxy_settings web_seed_proxy() const;
proxy_settings const&amp; tracker_proxy() const; proxy_settings tracker_proxy() const;
proxy_settings const&amp; dht_proxy() const; proxy_settings dht_proxy() const;
</pre> </pre>
</blockquote> </blockquote>
<p>These functions returns references to their respective current settings.</p> <p>These functions returns references to their respective current settings.</p>

View File

@ -193,14 +193,14 @@ The ``session`` class has the following synopsis::
int num_uploads() const; int num_uploads() const;
int num_connections() const; int num_connections() const;
bool load_asnum_db(char const* file); void load_asnum_db(char const* file);
bool load_asnum_db(wchar_t const* file); void load_asnum_db(wchar_t const* file);
bool load_country_db(char const* file); void load_country_db(char const* file);
bool load_country_db(wchar_t const* file); void load_country_db(wchar_t const* file);
int as_for_ip(address const& adr); int as_for_ip(address const& adr);
void set_ip_filter(ip_filter const& f); void set_ip_filter(ip_filter const& f);
ip_filter const& get_ip_filter() const; ip_filter get_ip_filter() const;
session_status status() const; session_status status() const;
cache_status get_cache_status() const; cache_status get_cache_status() const;
@ -647,10 +647,10 @@ load_asnum_db() load_country_db() int as_for_ip()
:: ::
bool load_asnum_db(char const* file); void load_asnum_db(char const* file);
bool load_asnum_db(wchar_t const* file); void load_asnum_db(wchar_t const* file);
bool load_country_db(char const* file); void load_country_db(char const* file);
bool load_country_db(wchar_t const* file); void load_country_db(wchar_t const* file);
int as_for_ip(address const& adr); int as_for_ip(address const& adr);
These functions are not available if ``TORRENT_DISABLE_GEO_IP`` is defined. They These functions are not available if ``TORRENT_DISABLE_GEO_IP`` is defined. They
@ -684,7 +684,7 @@ get_ip_filter()
--------------- ---------------
:: ::
ip_filter const& get_ip_filter() const; ip_filter get_ip_filter() const;
Returns the ip_filter currently in the session. See ip_filter_. Returns the ip_filter currently in the session. See ip_filter_.
@ -1114,10 +1114,10 @@ peer_proxy() web_seed_proxy() tracker_proxy() dht_proxy()
:: ::
proxy_settings const& peer_proxy() const; proxy_settings peer_proxy() const;
proxy_settings const& web_seed_proxy() const; proxy_settings web_seed_proxy() const;
proxy_settings const& tracker_proxy() const; proxy_settings tracker_proxy() const;
proxy_settings const& dht_proxy() const; proxy_settings dht_proxy() const;
These functions returns references to their respective current settings. These functions returns references to their respective current settings.

View File

@ -126,6 +126,8 @@ a list of entries.</p>
<li>torrent_handle::get_download_queue</li> <li>torrent_handle::get_download_queue</li>
<li>torrent_handle::piece_availability</li> <li>torrent_handle::piece_availability</li>
</ul> </ul>
<p><tt class="docutils literal"><span class="pre">create_torrent::add_node()</span></tt> takes two arguments, one string and one integer,
instead of a pair. The string is the address and the integer is the port.</p>
<p>For an example python program, see <tt class="docutils literal"><span class="pre">client.py</span></tt> in the <tt class="docutils literal"><span class="pre">bindings/python</span></tt> <p>For an example python program, see <tt class="docutils literal"><span class="pre">client.py</span></tt> in the <tt class="docutils literal"><span class="pre">bindings/python</span></tt>
directory.</p> directory.</p>
<p>A very simple example usage of the module would be something like this:</p> <p>A very simple example usage of the module would be something like this:</p>

View File

@ -34,7 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_ALERT_HPP_INCLUDED #define TORRENT_ALERT_HPP_INCLUDED
#include <memory> #include <memory>
#include <queue> #include <deque>
#include <string> #include <string>
#ifdef _MSC_VER #ifdef _MSC_VER
@ -145,15 +145,15 @@ namespace libtorrent {
size_t alert_queue_size_limit() const { return m_queue_size_limit; } size_t alert_queue_size_limit() const { return m_queue_size_limit; }
size_t set_alert_queue_size_limit(size_t queue_size_limit_); size_t set_alert_queue_size_limit(size_t queue_size_limit_);
void set_dispatch_function(boost::function<void(alert const&)> const&); void set_dispatch_function(boost::function<void(std::auto_ptr<alert>)> const&);
private: private:
std::queue<alert*> m_alerts; std::deque<alert*> m_alerts;
mutable mutex m_mutex; mutable mutex m_mutex;
condition m_condition; condition m_condition;
int m_alert_mask; int m_alert_mask;
size_t m_queue_size_limit; size_t m_queue_size_limit;
boost::function<void(alert const&)> m_dispatch; boost::function<void(std::auto_ptr<alert>)> m_dispatch;
io_service& m_ios; io_service& m_ios;
}; };

View File

@ -177,9 +177,18 @@ namespace libtorrent
void incoming_connection(boost::shared_ptr<socket_type> const& s); void incoming_connection(boost::shared_ptr<socket_type> const& s);
// must be locked to access the data #ifdef TORRENT_DEBUG
// in this struct #if defined BOOST_HAS_PTHREADS
mutable mutex m_mutex; pthread_t m_network_thread;
#endif
bool is_network_thread() const
{
#if defined BOOST_HAS_PTHREADS
return m_network_thread == pthread_self();
#endif
return true;
}
#endif
boost::weak_ptr<torrent> find_torrent(const sha1_hash& info_hash); boost::weak_ptr<torrent> find_torrent(const sha1_hash& info_hash);
peer_id const& get_peer_id() const { return m_peer_id; } peer_id const& get_peer_id() const { return m_peer_id; }
@ -190,7 +199,7 @@ namespace libtorrent
session_settings const& settings() const { return m_settings; } session_settings const& settings() const { return m_settings; }
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
void add_dht_node(std::pair<std::string, int> const& node); void add_dht_node_name(std::pair<std::string, int> const& node);
void add_dht_node(udp::endpoint n); void add_dht_node(udp::endpoint n);
void add_dht_router(std::pair<std::string, int> const& node); void add_dht_router(std::pair<std::string, int> const& node);
void set_dht_settings(dht_settings const& s); void set_dht_settings(dht_settings const& s);
@ -200,7 +209,7 @@ namespace libtorrent
void start_dht(entry const& startup_state); void start_dht(entry const& startup_state);
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
entry dht_state(mutex::scoped_lock& l) const; entry dht_state() const;
#endif #endif
void maybe_update_udp_mapping(int nat, int local_port, int external_port); void maybe_update_udp_mapping(int nat, int local_port, int external_port);
@ -252,7 +261,7 @@ namespace libtorrent
void set_alert_mask(int m); void set_alert_mask(int m);
size_t set_alert_queue_size_limit(size_t queue_size_limit_); size_t set_alert_queue_size_limit(size_t queue_size_limit_);
std::auto_ptr<alert> pop_alert(); std::auto_ptr<alert> pop_alert();
void set_alert_dispatch(boost::function<void(alert const&)> const&); void set_alert_dispatch(boost::function<void(std::auto_ptr<alert>)> const&);
alert const* wait_for_alert(time_duration max_wait); alert const* wait_for_alert(time_duration max_wait);
@ -292,8 +301,8 @@ namespace libtorrent
void announce_lsd(sha1_hash const& ih); void announce_lsd(sha1_hash const& ih);
void save_state(entry& e, boost::uint32_t flags, mutex::scoped_lock& l) const; void save_state(entry* e, boost::uint32_t flags) const;
void load_state(lazy_entry const& e); void load_state(lazy_entry const* e);
void set_peer_proxy(proxy_settings const& s) void set_peer_proxy(proxy_settings const& s)
{ {
@ -323,6 +332,7 @@ namespace libtorrent
} }
proxy_settings const& dht_proxy() const proxy_settings const& dht_proxy() const
{ return m_dht_proxy; } { return m_dht_proxy; }
bool is_dht_running() const { return m_dht; }
#endif #endif
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
@ -343,22 +353,22 @@ namespace libtorrent
std::string as_name_for_ip(address const& a); std::string as_name_for_ip(address const& a);
int as_for_ip(address const& a); int as_for_ip(address const& a);
std::pair<const int, int>* lookup_as(int as); std::pair<const int, int>* lookup_as(int as);
bool load_asnum_db(char const* file); void load_asnum_db(std::string file);
bool has_asnum_db() const { return m_asnum_db; } bool has_asnum_db() const { return m_asnum_db; }
bool load_country_db(char const* file); void load_country_db(std::string file);
bool has_country_db() const { return m_country_db; } bool has_country_db() const { return m_country_db; }
char const* country_for_ip(address const& a); char const* country_for_ip(address const& a);
#if TORRENT_USE_WSTRING #if TORRENT_USE_WSTRING
bool load_asnum_db(wchar_t const* file); void load_asnum_db(std::wstring file);
bool load_country_db(wchar_t const* file); void load_country_db(std::wstring file);
#endif // TORRENT_USE_WSTRING #endif // TORRENT_USE_WSTRING
#endif // TORRENT_DISABLE_GEO_IP #endif // TORRENT_DISABLE_GEO_IP
void start_lsd(); void start_lsd();
void start_natpmp(natpmp* n); natpmp* start_natpmp();
void start_upnp(upnp* u); upnp* start_upnp();
void stop_lsd(); void stop_lsd();
void stop_natpmp(); void stop_natpmp();
@ -387,11 +397,14 @@ namespace libtorrent
void set_external_address(address const& ip); void set_external_address(address const& ip);
address const& external_address() const { return m_external_address; } address const& external_address() const { return m_external_address; }
// used when posting synchronous function
// calls to session_impl and torrent objects
mutable libtorrent::mutex mut;
mutable libtorrent::condition cond;
// private: // private:
void update_disk_thread_settings(); void update_disk_thread_settings();
void on_dht_state_callback(condition& c
, entry& e, bool& done) const;
void on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih); void on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih);
void setup_socket_buffers(socket_type& s); void setup_socket_buffers(socket_type& s);
@ -794,6 +807,7 @@ namespace libtorrent
std::string m_logpath; std::string m_logpath;
public: public:
boost::shared_ptr<logger> m_logger; boost::shared_ptr<logger> m_logger;
private: private:
#endif #endif

View File

@ -289,6 +289,7 @@ namespace libtorrent
, int block_size = 16 * 1024); , int block_size = 16 * 1024);
~disk_io_thread(); ~disk_io_thread();
void abort();
void join(); void join();
// aborts read operations // aborts read operations

View File

@ -642,8 +642,6 @@ namespace libtorrent
, std::size_t bytes_transferred); , std::size_t bytes_transferred);
void on_receive_data(error_code const& error void on_receive_data(error_code const& error
, std::size_t bytes_transferred); , std::size_t bytes_transferred);
void on_receive_data_nolock(error_code const& error
, std::size_t bytes_transferred);
// this is the limit on the number of outstanding requests // this is the limit on the number of outstanding requests
// we have to this peer. This is initialized to the settings // we have to this peer. This is initialized to the settings

View File

@ -275,7 +275,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_ENCRYPTION #ifndef TORRENT_DISABLE_ENCRYPTION
void set_pe_settings(pe_settings const& settings); void set_pe_settings(pe_settings const& settings);
pe_settings const& get_pe_settings() const; pe_settings get_pe_settings() const;
#endif #endif
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
@ -284,11 +284,11 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_GEO_IP #ifndef TORRENT_DISABLE_GEO_IP
int as_for_ip(address const& addr); int as_for_ip(address const& addr);
bool load_asnum_db(char const* file); void load_asnum_db(char const* file);
bool load_country_db(char const* file); void load_country_db(char const* file);
#if TORRENT_USE_WSTRING #if TORRENT_USE_WSTRING
bool load_country_db(wchar_t const* file); void load_country_db(wchar_t const* file);
bool load_asnum_db(wchar_t const* file); void load_asnum_db(wchar_t const* file);
#endif #endif
#endif #endif
@ -302,7 +302,7 @@ namespace libtorrent
#endif #endif
void set_ip_filter(ip_filter const& f); void set_ip_filter(ip_filter const& f);
ip_filter const& get_ip_filter() const; ip_filter get_ip_filter() const;
void set_port_filter(port_filter const& f); void set_port_filter(port_filter const& f);
void set_peer_id(peer_id const& pid); void set_peer_id(peer_id const& pid);
@ -354,24 +354,24 @@ namespace libtorrent
void remove_torrent(const torrent_handle& h, int options = none); void remove_torrent(const torrent_handle& h, int options = none);
void set_settings(session_settings const& s); void set_settings(session_settings const& s);
session_settings const& settings(); session_settings settings();
void set_peer_proxy(proxy_settings const& s); void set_peer_proxy(proxy_settings const& s);
void set_web_seed_proxy(proxy_settings const& s); void set_web_seed_proxy(proxy_settings const& s);
void set_tracker_proxy(proxy_settings const& s); void set_tracker_proxy(proxy_settings const& s);
proxy_settings const& peer_proxy() const; proxy_settings peer_proxy() const;
proxy_settings const& web_seed_proxy() const; proxy_settings web_seed_proxy() const;
proxy_settings const& tracker_proxy() const; proxy_settings tracker_proxy() const;
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
void set_dht_proxy(proxy_settings const& s); void set_dht_proxy(proxy_settings const& s);
proxy_settings const& dht_proxy() const; proxy_settings dht_proxy() const;
#endif #endif
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
void set_i2p_proxy(proxy_settings const& s); void set_i2p_proxy(proxy_settings const& s);
proxy_settings const& i2p_proxy() const; proxy_settings i2p_proxy() const;
#endif #endif
int upload_rate_limit() const; int upload_rate_limit() const;
@ -400,7 +400,7 @@ namespace libtorrent
size_t set_alert_queue_size_limit(size_t queue_size_limit_); size_t set_alert_queue_size_limit(size_t queue_size_limit_);
alert const* wait_for_alert(time_duration max_wait); alert const* wait_for_alert(time_duration max_wait);
void set_alert_dispatch(boost::function<void(alert const&)> const& fun); void set_alert_dispatch(boost::function<void(std::auto_ptr<alert>)> const& fun);
connection_queue& get_connection_queue(); connection_queue& get_connection_queue();

View File

@ -172,8 +172,7 @@ namespace libtorrent
void on_resume_data_checked(int ret, disk_io_job const& j); void on_resume_data_checked(int ret, disk_io_job const& j);
void on_force_recheck(int ret, disk_io_job const& j); void on_force_recheck(int ret, disk_io_job const& j);
void on_piece_checked(int ret, disk_io_job const& j); void on_piece_checked(int ret, disk_io_job const& j);
void files_checked_lock(); void files_checked();
void files_checked(mutex::scoped_lock const&);
void start_checking(); void start_checking();
void start_announcing(); void start_announcing();
@ -228,6 +227,8 @@ namespace libtorrent
bool is_sequential_download() const bool is_sequential_download() const
{ return m_sequential_download; } { return m_sequential_download; }
void queue_up();
void queue_down();
void set_queue_position(int p); void set_queue_position(int p);
int queue_position() const { return m_sequence_number; } int queue_position() const { return m_sequence_number; }
@ -307,7 +308,7 @@ namespace libtorrent
void file_progress(std::vector<size_type>& fp, int flags = 0) const; void file_progress(std::vector<size_type>& fp, int flags = 0) const;
void use_interface(const char* net_interface); void use_interface(std::string net_interface);
tcp::endpoint get_interface() const { return m_net_interface; } tcp::endpoint get_interface() const { return m_net_interface; }
void connect_to_url_seed(std::list<web_seed_entry>::iterator url); void connect_to_url_seed(std::list<web_seed_entry>::iterator url);
@ -408,6 +409,7 @@ namespace libtorrent
bool want_more_peers() const; bool want_more_peers() const;
bool try_connect_peer(); bool try_connect_peer();
void give_connect_points(int points); void give_connect_points(int points);
void add_peer(tcp::endpoint const& adr, int source);
// the number of peers that belong to this torrent // the number of peers that belong to this torrent
int num_peers() const { return (int)m_connections.size(); } int num_peers() const { return (int)m_connections.size(); }

View File

@ -336,7 +336,7 @@ namespace libtorrent {
while (!m_alerts.empty()) while (!m_alerts.empty())
{ {
delete m_alerts.front(); delete m_alerts.front();
m_alerts.pop(); m_alerts.pop_front();
} }
} }
@ -367,21 +367,20 @@ namespace libtorrent {
return m_alerts.front(); return m_alerts.front();
} }
void alert_manager::set_dispatch_function(boost::function<void(alert const&)> const& fun) void alert_manager::set_dispatch_function(boost::function<void(std::auto_ptr<alert>)> const& fun)
{ {
mutex::scoped_lock lock(m_mutex); mutex::scoped_lock lock(m_mutex);
m_dispatch = fun; m_dispatch = fun;
std::queue<alert*> alerts = m_alerts; std::deque<alert*> alerts;
while (!m_alerts.empty()) m_alerts.pop(); m_alerts.swap(alerts);
lock.unlock(); lock.unlock();
while (!alerts.empty()) while (!alerts.empty())
{ {
m_dispatch(*alerts.front()); m_dispatch(std::auto_ptr<alert>(alerts.front()));
delete alerts.front(); alerts.pop_front();
alerts.pop();
} }
} }
@ -399,12 +398,12 @@ namespace libtorrent {
if (m_dispatch) if (m_dispatch)
{ {
TORRENT_ASSERT(m_alerts.empty()); TORRENT_ASSERT(m_alerts.empty());
m_ios.post(boost::bind(&dispatch_alert, m_dispatch, alert_.clone().release())); m_dispatch(std::auto_ptr<alert>(alert_.clone()));
return; return;
} }
if (m_alerts.size() >= m_queue_size_limit) return; if (m_alerts.size() >= m_queue_size_limit) return;
m_alerts.push(alert_.clone().release()); m_alerts.push_back(alert_.clone().release());
m_condition.signal(lock); m_condition.signal(lock);
m_condition.clear(lock); m_condition.clear(lock);
} }
@ -413,10 +412,11 @@ namespace libtorrent {
{ {
mutex::scoped_lock lock(m_mutex); mutex::scoped_lock lock(m_mutex);
TORRENT_ASSERT(!m_alerts.empty()); if (m_alerts.empty())
return std::auto_ptr<alert>(0);
alert* result = m_alerts.front(); alert* result = m_alerts.front();
m_alerts.pop(); m_alerts.pop_front();
return std::auto_ptr<alert>(result); return std::auto_ptr<alert>(result);
} }

View File

@ -368,7 +368,7 @@ namespace libtorrent
TORRENT_ASSERT(m_abort == true); TORRENT_ASSERT(m_abort == true);
} }
void disk_io_thread::join() void disk_io_thread::abort()
{ {
mutex::scoped_lock l(m_queue_mutex); mutex::scoped_lock l(m_queue_mutex);
disk_io_job j; disk_io_job j;
@ -376,10 +376,12 @@ namespace libtorrent
j.action = disk_io_job::abort_thread; j.action = disk_io_job::abort_thread;
m_jobs.insert(m_jobs.begin(), j); m_jobs.insert(m_jobs.begin(), j);
m_signal.signal(l); m_signal.signal(l);
l.unlock(); }
void disk_io_thread::join()
{
m_disk_io_thread.join(); m_disk_io_thread.join();
l.lock(); mutex::scoped_lock l(m_queue_mutex);
TORRENT_ASSERT(m_abort == true); TORRENT_ASSERT(m_abort == true);
m_jobs.clear(); m_jobs.clear();
} }

View File

@ -2392,7 +2392,7 @@ namespace libtorrent
void peer_connection::on_disk_write_complete(int ret, disk_io_job const& j void peer_connection::on_disk_write_complete(int ret, disk_io_job const& j
, peer_request p, boost::shared_ptr<torrent> t) , peer_request p, boost::shared_ptr<torrent> t)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -3168,7 +3168,7 @@ namespace libtorrent
void peer_connection::on_timeout() void peer_connection::on_timeout()
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(m_connecting); TORRENT_ASSERT(m_connecting);
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
@ -4061,7 +4061,7 @@ namespace libtorrent
void peer_connection::on_disk_read_complete(int ret, disk_io_job const& j, peer_request r) void peer_connection::on_disk_read_complete(int ret, disk_io_job const& j, peer_request r)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
m_reading_bytes -= r.length; m_reading_bytes -= r.length;
@ -4379,7 +4379,7 @@ namespace libtorrent
else else
{ {
m_channel_state[download_channel] = peer_info::bw_network; m_channel_state[download_channel] = peer_info::bw_network;
on_receive_data_nolock(ec, bytes_transferred); on_receive_data(ec, bytes_transferred);
} }
} }
@ -4636,14 +4636,7 @@ namespace libtorrent
void peer_connection::on_receive_data(const error_code& error void peer_connection::on_receive_data(const error_code& error
, std::size_t bytes_transferred) , std::size_t bytes_transferred)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
on_receive_data_nolock(error, bytes_transferred);
}
void peer_connection::on_receive_data_nolock(const error_code& error
, std::size_t bytes_transferred)
{
INVARIANT_CHECK; INVARIANT_CHECK;
// keep ourselves alive in until this function exits in // keep ourselves alive in until this function exits in
@ -4777,7 +4770,7 @@ namespace libtorrent
void peer_connection::on_connect(int ticket) void peer_connection::on_connect(int ticket)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
// in case we disconnect here, we need to // in case we disconnect here, we need to
// keep the connection alive until the // keep the connection alive until the
@ -4869,7 +4862,7 @@ namespace libtorrent
{ {
ptime completed = time_now(); ptime completed = time_now();
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -4932,7 +4925,7 @@ namespace libtorrent
void peer_connection::on_send_data(error_code const& error void peer_connection::on_send_data(error_code const& error
, std::size_t bytes_transferred) , std::size_t bytes_transferred)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;

View File

@ -229,6 +229,87 @@ namespace libtorrent
return set; return set;
} }
// wrapper around a function that's executed in the network thread
// ans synchronized in the client thread
template <class R>
void fun_ret(R* ret, bool* done, condition* e, mutex* m, boost::function<R(void)> f)
{
*ret = f();
mutex::scoped_lock l(*m);
*done = true;
e->signal(l);
}
void fun_wrap(bool* done, condition* e, mutex* m, boost::function<void(void)> f)
{
f();
mutex::scoped_lock l(*m);
*done = true;
e->signal(l);
}
#define TORRENT_ASYNC_CALL(x) \
m_impl->m_io_service.post(boost::bind(&session_impl:: x, m_impl.get()))
#define TORRENT_ASYNC_CALL1(x, a1) \
m_impl->m_io_service.post(boost::bind(&session_impl:: x, m_impl.get(), a1))
#define TORRENT_ASYNC_CALL2(x, a1, a2) \
m_impl->m_io_service.post(boost::bind(&session_impl:: x, m_impl.get(), a1, a2))
#define TORRENT_SYNC_CALL(x) \
bool done = false; \
mutex::scoped_lock l(m_impl->mut); \
m_impl->cond.clear(l); \
m_impl->m_io_service.post(boost::bind(&fun_wrap, &done, &m_impl->cond, &m_impl->mut, boost::function<void(void)>(boost::bind(&session_impl:: x, m_impl.get())))); \
do { m_impl->cond.wait(l); } while(!done)
#define TORRENT_SYNC_CALL1(x, a1) \
bool done = false; \
mutex::scoped_lock l(m_impl->mut); \
m_impl->cond.clear(l); \
m_impl->m_io_service.post(boost::bind(&fun_wrap, &done, &m_impl->cond, &m_impl->mut, boost::function<void(void)>(boost::bind(&session_impl:: x, m_impl.get(), a1)))); \
do { m_impl->cond.wait(l); } while(!done)
#define TORRENT_SYNC_CALL2(x, a1, a2) \
bool done = false; \
mutex::scoped_lock l(m_impl->mut); \
m_impl->cond.clear(l); \
m_impl->m_io_service.post(boost::bind(&fun_wrap, &done, &m_impl->cond, &m_impl->mut, boost::function<void(void)>(boost::bind(&session_impl:: x, m_impl.get(), a1, a2)))); \
do { m_impl->cond.wait(l); } while(!done)
#define TORRENT_SYNC_CALL_RET(type, x) \
bool done = false; \
type r; \
mutex::scoped_lock l(m_impl->mut); \
m_impl->cond.clear(l); \
m_impl->m_io_service.post(boost::bind(&fun_ret<type>, &r, &done, &m_impl->cond, &m_impl->mut, boost::function<type(void)>(boost::bind(&session_impl:: x, m_impl.get())))); \
do { m_impl->cond.wait(l); } while(!done)
#define TORRENT_SYNC_CALL_RET1(type, x, a1) \
bool done = false; \
type r; \
mutex::scoped_lock l(m_impl->mut); \
m_impl->cond.clear(l); \
m_impl->m_io_service.post(boost::bind(&fun_ret<type>, &r, &done, &m_impl->cond, &m_impl->mut, boost::function<type(void)>(boost::bind(&session_impl:: x, m_impl.get(), a1)))); \
do { m_impl->cond.wait(l); } while(!done)
#define TORRENT_SYNC_CALL_RET2(type, x, a1, a2) \
bool done = false; \
type r; \
mutex::scoped_lock l(m_impl->mut); \
m_impl->cond.clear(l); \
m_impl->m_io_service.post(boost::bind(&fun_ret<type>, &r, &done, &m_impl->cond, &m_impl->mut, boost::function<type(void)>(boost::bind(&session_impl:: x, m_impl.get(), a1, a2)))); \
do { m_impl->cond.wait(l); } while(!done)
#define TORRENT_SYNC_CALL_RET3(type, x, a1, a2, a3) \
bool done = false; \
type r; \
mutex::scoped_lock l(m_impl->mut); \
m_impl->cond.clear(l); \
m_impl->m_io_service.post(boost::bind(&fun_ret<type>, &r, &done, &m_impl->cond, &m_impl->mut, boost::function<type(void)>(boost::bind(&session_impl:: x, m_impl.get(), a1, a2, a3)))); \
do { m_impl->cond.wait(l); } while(!done)
session::session( session::session(
fingerprint const& id fingerprint const& id
, std::pair<int, int> listen_port_range , std::pair<int, int> listen_port_range
@ -310,7 +391,6 @@ namespace libtorrent
session::~session() session::~session()
{ {
mutex::scoped_lock l(m_impl->m_mutex);
#ifdef TORRENT_MEMDEBUG #ifdef TORRENT_MEMDEBUG
stop_malloc_debug(); stop_malloc_debug();
#endif #endif
@ -319,59 +399,55 @@ namespace libtorrent
// abort the session and let the destructor // abort the session and let the destructor
// of the proxy to syncronize // of the proxy to syncronize
if (!m_impl.unique()) if (!m_impl.unique())
m_impl->abort(); {
TORRENT_ASYNC_CALL(abort);
}
} }
void session::save_state(entry& e, boost::uint32_t flags) const void session::save_state(entry& e, boost::uint32_t flags) const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL2(save_state, &e, flags);
m_impl->save_state(e, flags, l);
} }
void session::load_state(lazy_entry const& e) void session::load_state(lazy_entry const& e)
{ {
mutex::scoped_lock l(m_impl->m_mutex); // this needs to be synchronized since the lifespan
m_impl->load_state(e); // of e is tied to the caller
TORRENT_SYNC_CALL1(load_state, &e);
} }
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
void session::add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext) void session::add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(add_extension, ext);
m_impl->add_extension(ext);
} }
#endif #endif
#ifndef TORRENT_DISABLE_GEO_IP #ifndef TORRENT_DISABLE_GEO_IP
bool session::load_asnum_db(char const* file) void session::load_asnum_db(char const* file)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(load_asnum_db, std::string(file));
return m_impl->load_asnum_db(file);
} }
bool session::load_country_db(char const* file) void session::load_country_db(char const* file)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(load_country_db, std::string(file));
return m_impl->load_country_db(file);
} }
int session::as_for_ip(address const& addr) int session::as_for_ip(address const& addr)
{ {
mutex::scoped_lock l(m_impl->m_mutex);
return m_impl->as_for_ip(addr); return m_impl->as_for_ip(addr);
} }
#if TORRENT_USE_WSTRING #if TORRENT_USE_WSTRING
bool session::load_asnum_db(wchar_t const* file) void session::load_asnum_db(wchar_t const* file)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(load_asnum_db, std::wstring(file));
return m_impl->load_asnum_db(file);
} }
bool session::load_country_db(wchar_t const* file) void session::load_country_db(wchar_t const* file)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(load_country_db, std::wstring(file));
return m_impl->load_country_db(file);
} }
#endif // TORRENT_USE_WSTRING #endif // TORRENT_USE_WSTRING
#endif // TORRENT_DISABLE_GEO_IP #endif // TORRENT_DISABLE_GEO_IP
@ -383,89 +459,80 @@ namespace libtorrent
bencode(std::back_inserter(buf), ses_state); bencode(std::back_inserter(buf), ses_state);
lazy_entry e; lazy_entry e;
lazy_bdecode(&buf[0], &buf[0] + buf.size(), e); lazy_bdecode(&buf[0], &buf[0] + buf.size(), e);
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL1(load_state, &e);
m_impl->load_state(e);
} }
entry session::state() const entry session::state() const
{ {
entry ret; entry ret;
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL2(save_state, &ret, 0xffffffff);
m_impl->save_state(ret, 0xffffffff, l);
return ret; return ret;
} }
#endif #endif
void session::set_ip_filter(ip_filter const& f) void session::set_ip_filter(ip_filter const& f)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_ip_filter, f);
m_impl->set_ip_filter(f);
} }
ip_filter const& session::get_ip_filter() const ip_filter session::get_ip_filter() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(ip_filter, get_ip_filter);
return m_impl->get_ip_filter(); return r;
} }
void session::set_port_filter(port_filter const& f) void session::set_port_filter(port_filter const& f)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_port_filter, f);
m_impl->set_port_filter(f);
} }
void session::set_peer_id(peer_id const& id) void session::set_peer_id(peer_id const& id)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_peer_id, id);
m_impl->set_peer_id(id);
} }
peer_id session::id() const peer_id session::id() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(peer_id, get_peer_id);
return m_impl->get_peer_id(); return r;
} }
io_service& session::get_io_service() io_service& session::get_io_service()
{ {
mutex::scoped_lock l(m_impl->m_mutex);
return m_impl->m_io_service; return m_impl->m_io_service;
} }
void session::set_key(int key) void session::set_key(int key)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_key, key);
m_impl->set_key(key);
} }
std::vector<torrent_handle> session::get_torrents() const std::vector<torrent_handle> session::get_torrents() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(std::vector<torrent_handle>, get_torrents);
return m_impl->get_torrents(); return r;
} }
torrent_handle session::find_torrent(sha1_hash const& info_hash) const torrent_handle session::find_torrent(sha1_hash const& info_hash) const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET1(torrent_handle, find_torrent_handle, info_hash);
return m_impl->find_torrent_handle(info_hash); return r;
} }
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
torrent_handle session::add_torrent(add_torrent_params const& params) torrent_handle session::add_torrent(add_torrent_params const& params)
{ {
mutex::scoped_lock l(m_impl->m_mutex);
error_code ec; error_code ec;
torrent_handle ret = m_impl->add_torrent(params, ec); TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, ec);
if (ec) throw libtorrent_exception(ec); if (ec) throw libtorrent_exception(ec);
return ret; return r;
} }
#endif #endif
torrent_handle session::add_torrent(add_torrent_params const& params, error_code& ec) torrent_handle session::add_torrent(add_torrent_params const& params, error_code& ec)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET2(torrent_handle, add_torrent, params, ec);
return m_impl->add_torrent(params, ec); return r;
} }
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
@ -542,58 +609,53 @@ namespace libtorrent
void session::remove_torrent(const torrent_handle& h, int options) void session::remove_torrent(const torrent_handle& h, int options)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL2(remove_torrent, h, options);
m_impl->remove_torrent(h, options);
} }
bool session::listen_on( bool session::listen_on(
std::pair<int, int> const& port_range std::pair<int, int> const& port_range
, const char* net_interface, int flags) , const char* net_interface, int flags)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET3(bool, listen_on, port_range, net_interface, flags);
return m_impl->listen_on(port_range, net_interface, flags); return r;
} }
unsigned short session::listen_port() const unsigned short session::listen_port() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(unsigned short, listen_port);
return m_impl->listen_port(); return r;
} }
session_status session::status() const session_status session::status() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(session_status, status);
return m_impl->status(); return r;
} }
void session::pause() void session::pause()
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL(pause);
m_impl->pause();
} }
void session::resume() void session::resume()
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL(resume);
m_impl->resume();
} }
bool session::is_paused() const bool session::is_paused() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(bool, is_paused);
return m_impl->is_paused(); return r;
} }
void session::get_cache_info(sha1_hash const& ih void session::get_cache_info(sha1_hash const& ih
, std::vector<cached_piece_info>& ret) const , std::vector<cached_piece_info>& ret) const
{ {
mutex::scoped_lock l(m_impl->m_mutex);
m_impl->m_disk_thread.get_cache_info(ih, ret); m_impl->m_disk_thread.get_cache_info(ih, ret);
} }
cache_status session::get_cache_status() const cache_status session::get_cache_status() const
{ {
mutex::scoped_lock l(m_impl->m_mutex);
return m_impl->m_disk_thread.status(); return m_impl->m_disk_thread.status();
} }
@ -601,53 +663,47 @@ namespace libtorrent
void session::start_dht() void session::start_dht()
{ {
mutex::scoped_lock l(m_impl->m_mutex);
// the state is loaded in load_state() // the state is loaded in load_state()
m_impl->start_dht(); TORRENT_ASYNC_CALL(start_dht);
} }
void session::stop_dht() void session::stop_dht()
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL(stop_dht);
m_impl->stop_dht();
} }
void session::set_dht_settings(dht_settings const& settings) void session::set_dht_settings(dht_settings const& settings)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_dht_settings, settings);
m_impl->set_dht_settings(settings);
} }
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
void session::start_dht(entry const& startup_state) void session::start_dht(entry const& startup_state)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(start_dht, startup_state);
m_impl->start_dht(startup_state);
} }
entry session::dht_state() const entry session::dht_state() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(entry, dht_state);
return m_impl->dht_state(l); return r;
} }
#endif #endif
void session::add_dht_node(std::pair<std::string, int> const& node) void session::add_dht_node(std::pair<std::string, int> const& node)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(add_dht_node_name, node);
m_impl->add_dht_node(node);
} }
void session::add_dht_router(std::pair<std::string, int> const& node) void session::add_dht_router(std::pair<std::string, int> const& node)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(add_dht_router, node);
m_impl->add_dht_router(node);
} }
bool session::is_dht_running() const bool session::is_dht_running() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(bool, is_dht_running);
return m_impl->m_dht; return r;
} }
#endif #endif
@ -655,230 +711,211 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_ENCRYPTION #ifndef TORRENT_DISABLE_ENCRYPTION
void session::set_pe_settings(pe_settings const& settings) void session::set_pe_settings(pe_settings const& settings)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_pe_settings, settings);
m_impl->set_pe_settings(settings);
} }
pe_settings const& session::get_pe_settings() const pe_settings session::get_pe_settings() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(pe_settings, get_pe_settings);
return m_impl->get_pe_settings(); return r;
} }
#endif #endif
bool session::is_listening() const bool session::is_listening() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(bool, is_listening);
return m_impl->is_listening(); return r;
} }
void session::set_settings(session_settings const& s) void session::set_settings(session_settings const& s)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_settings, s);
m_impl->set_settings(s);
} }
session_settings const& session::settings() session_settings session::settings()
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(session_settings, settings);
return m_impl->settings(); return r;
} }
void session::set_peer_proxy(proxy_settings const& s) void session::set_peer_proxy(proxy_settings const& s)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_peer_proxy, s);
m_impl->set_peer_proxy(s);
} }
void session::set_web_seed_proxy(proxy_settings const& s) void session::set_web_seed_proxy(proxy_settings const& s)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_web_seed_proxy, s);
m_impl->set_web_seed_proxy(s);
} }
void session::set_tracker_proxy(proxy_settings const& s) void session::set_tracker_proxy(proxy_settings const& s)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_tracker_proxy, s);
m_impl->set_tracker_proxy(s);
} }
proxy_settings const& session::peer_proxy() const proxy_settings session::peer_proxy() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(proxy_settings, peer_proxy);
return m_impl->peer_proxy(); return r;
} }
proxy_settings const& session::web_seed_proxy() const proxy_settings session::web_seed_proxy() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(proxy_settings, web_seed_proxy);
return m_impl->web_seed_proxy(); return r;
} }
proxy_settings const& session::tracker_proxy() const proxy_settings session::tracker_proxy() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(proxy_settings, tracker_proxy);
return m_impl->tracker_proxy(); return r;
} }
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
void session::set_dht_proxy(proxy_settings const& s) void session::set_dht_proxy(proxy_settings const& s)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_dht_proxy, s);
m_impl->set_dht_proxy(s);
} }
proxy_settings const& session::dht_proxy() const proxy_settings session::dht_proxy() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(proxy_settings, dht_proxy);
return m_impl->dht_proxy(); return r;
} }
#endif #endif
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
void session::set_i2p_proxy(proxy_settings const& s) void session::set_i2p_proxy(proxy_settings const& s)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_i2p_proxy, s);
m_impl->set_i2p_proxy(s);
} }
proxy_settings const& session::i2p_proxy() const proxy_settings session::i2p_proxy() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(proxy_settings, i2p_proxy);
return m_impl->i2p_proxy(); return r;
} }
#endif #endif
int session::max_uploads() const int session::max_uploads() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(int, max_uploads);
return m_impl->max_uploads(); return r;
} }
void session::set_max_uploads(int limit) void session::set_max_uploads(int limit)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_max_uploads, limit);
m_impl->set_max_uploads(limit);
} }
int session::max_connections() const int session::max_connections() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(int, max_connections);
return m_impl->max_connections(); return r;
} }
void session::set_max_connections(int limit) void session::set_max_connections(int limit)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_max_connections, limit);
m_impl->set_max_connections(limit);
} }
int session::max_half_open_connections() const int session::max_half_open_connections() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(int, max_half_open_connections);
return m_impl->max_half_open_connections(); return r;
} }
void session::set_max_half_open_connections(int limit) void session::set_max_half_open_connections(int limit)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_max_half_open_connections, limit);
m_impl->set_max_half_open_connections(limit);
} }
int session::local_upload_rate_limit() const int session::local_upload_rate_limit() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(int, local_upload_rate_limit);
return m_impl->local_upload_rate_limit(); return r;
} }
int session::local_download_rate_limit() const int session::local_download_rate_limit() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(int, local_download_rate_limit);
return m_impl->local_download_rate_limit(); return r;
} }
int session::upload_rate_limit() const int session::upload_rate_limit() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(int, upload_rate_limit);
return m_impl->upload_rate_limit(); return r;
} }
int session::download_rate_limit() const int session::download_rate_limit() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(int, download_rate_limit);
return m_impl->download_rate_limit(); return r;
} }
void session::set_local_upload_rate_limit(int bytes_per_second) void session::set_local_upload_rate_limit(int bytes_per_second)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_local_upload_rate_limit, bytes_per_second);
m_impl->set_local_upload_rate_limit(bytes_per_second);
} }
void session::set_local_download_rate_limit(int bytes_per_second) void session::set_local_download_rate_limit(int bytes_per_second)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_local_download_rate_limit, bytes_per_second);
m_impl->set_local_download_rate_limit(bytes_per_second);
} }
void session::set_upload_rate_limit(int bytes_per_second) void session::set_upload_rate_limit(int bytes_per_second)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_upload_rate_limit, bytes_per_second);
m_impl->set_upload_rate_limit(bytes_per_second);
} }
void session::set_download_rate_limit(int bytes_per_second) void session::set_download_rate_limit(int bytes_per_second)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_download_rate_limit, bytes_per_second);
m_impl->set_download_rate_limit(bytes_per_second);
} }
int session::num_uploads() const int session::num_uploads() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(int, num_uploads);
return m_impl->num_uploads(); return r;
} }
int session::num_connections() const int session::num_connections() const
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(int, num_connections);
return m_impl->num_connections(); return r;
} }
std::auto_ptr<alert> session::pop_alert() std::auto_ptr<alert> session::pop_alert()
{ {
mutex::scoped_lock l(m_impl->m_mutex);
return m_impl->pop_alert(); return m_impl->pop_alert();
} }
void session::set_alert_dispatch(boost::function<void(alert const&)> const& fun) void session::set_alert_dispatch(boost::function<void(std::auto_ptr<alert>)> const& fun)
{ {
// this function deliberately doesn't acquire the mutex TORRENT_ASYNC_CALL1(set_alert_dispatch, fun);
return m_impl->set_alert_dispatch(fun);
} }
alert const* session::wait_for_alert(time_duration max_wait) alert const* session::wait_for_alert(time_duration max_wait)
{ {
// this function deliberately doesn't acquire the mutex
return m_impl->wait_for_alert(max_wait); return m_impl->wait_for_alert(max_wait);
} }
void session::set_alert_mask(int m) void session::set_alert_mask(int m)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL1(set_alert_mask, m);
m_impl->set_alert_mask(m);
} }
size_t session::set_alert_queue_size_limit(size_t queue_size_limit_) size_t session::set_alert_queue_size_limit(size_t queue_size_limit_)
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET1(size_t, set_alert_queue_size_limit, queue_size_limit_);
return m_impl->set_alert_queue_size_limit(queue_size_limit_); return r;
} }
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
void session::set_severity_level(alert::severity_t s) void session::set_severity_level(alert::severity_t s)
{ {
mutex::scoped_lock l(m_impl->m_mutex);
int m = 0; int m = 0;
switch (s) switch (s)
{ {
@ -893,85 +930,44 @@ namespace libtorrent
default: break; default: break;
} }
m_impl->set_alert_mask(m); TORRENT_ASYNC_CALL1(set_alert_mask, m);
} }
#endif #endif
void session::start_lsd() void session::start_lsd()
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL(start_lsd);
m_impl->start_lsd();
} }
natpmp* session::start_natpmp() natpmp* session::start_natpmp()
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(natpmp*, start_natpmp);
if (m_impl->m_natpmp) return m_impl->m_natpmp.get(); return r;
// the natpmp constructor may fail and call the callbacks
// into the session_impl. We cannot hold the mutex then
l.unlock();
natpmp* n = new (std::nothrow) natpmp(m_impl->m_io_service
, m_impl->m_listen_interface.address()
, boost::bind(&session_impl::on_port_mapping
, m_impl.get(), _1, _2, _3, 0)
, boost::bind(&session_impl::on_port_map_log
, m_impl.get(), _1, 0));
l.lock();
if (n == 0) return 0;
m_impl->start_natpmp(n);
return n;
} }
upnp* session::start_upnp() upnp* session::start_upnp()
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_SYNC_CALL_RET(upnp*, start_upnp);
return r;
if (m_impl->m_upnp) return m_impl->m_upnp.get();
// the upnp constructor may fail and call the callbacks
// into the session_impl. We cannot hold the mutex then
l.unlock();
upnp* u = new (std::nothrow) upnp(m_impl->m_io_service
, m_impl->m_half_open
, m_impl->m_listen_interface.address()
, m_impl->m_settings.user_agent
, boost::bind(&session_impl::on_port_mapping
, m_impl.get(), _1, _2, _3, 1)
, boost::bind(&session_impl::on_port_map_log
, m_impl.get(), _1, 1)
, m_impl->m_settings.upnp_ignore_nonrouters);
l.lock();
if (u == 0) return 0;
m_impl->start_upnp(u);
return u;
} }
void session::stop_lsd() void session::stop_lsd()
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL(stop_lsd);
m_impl->stop_lsd();
} }
void session::stop_natpmp() void session::stop_natpmp()
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL(stop_natpmp);
m_impl->stop_natpmp();
} }
void session::stop_upnp() void session::stop_upnp()
{ {
mutex::scoped_lock l(m_impl->m_mutex); TORRENT_ASYNC_CALL(stop_upnp);
m_impl->stop_upnp();
} }
connection_queue& session::get_connection_queue() connection_queue& session::get_connection_queue()
{ {
mutex::scoped_lock l(m_impl->m_mutex);
return m_impl->m_half_open; return m_impl->m_half_open;
} }
} }

View File

@ -750,8 +750,10 @@ namespace aux {
m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this))); m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this)));
} }
void session_impl::save_state(entry& e, boost::uint32_t flags, mutex::scoped_lock& l) const void session_impl::save_state(entry* eptr, boost::uint32_t flags) const
{ {
entry& e = *eptr;
if (flags & session::save_settings) if (flags & session::save_settings)
{ {
// TODO: move these to session_settings // TODO: move these to session_settings
@ -780,12 +782,7 @@ namespace aux {
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
if (m_dht && (flags & session::save_dht_state)) if (m_dht && (flags & session::save_dht_state))
{ {
condition cond; e["dht state"] = m_dht->state();
entry& state = e["dht state"];
bool done = false;
m_io_service.post(boost::bind(&session_impl::on_dht_state_callback
, this, boost::ref(cond), boost::ref(state), boost::ref(done)));
while (!done) cond.wait(l);
} }
#endif #endif
@ -814,29 +811,29 @@ namespace aux {
} }
void session_impl::load_state(lazy_entry const& e) void session_impl::load_state(lazy_entry const* e)
{ {
lazy_entry const* settings; lazy_entry const* settings;
if (e.type() != lazy_entry::dict_t) return; if (e->type() != lazy_entry::dict_t) return;
set_upload_rate_limit(e.dict_find_int_value("upload_rate_limit", 0)); set_upload_rate_limit(e->dict_find_int_value("upload_rate_limit", 0));
set_download_rate_limit(e.dict_find_int_value("download_rate_limit", 0)); set_download_rate_limit(e->dict_find_int_value("download_rate_limit", 0));
set_local_upload_rate_limit(e.dict_find_int_value("local_upload_rate_limit", 0)); set_local_upload_rate_limit(e->dict_find_int_value("local_upload_rate_limit", 0));
set_local_download_rate_limit(e.dict_find_int_value("local_download_rate_limit", 0)); set_local_download_rate_limit(e->dict_find_int_value("local_download_rate_limit", 0));
set_max_uploads(e.dict_find_int_value("max_uploads", 0)); set_max_uploads(e->dict_find_int_value("max_uploads", 0));
set_max_half_open_connections(e.dict_find_int_value("max_half_open_connections", 0)); set_max_half_open_connections(e->dict_find_int_value("max_half_open_connections", 0));
set_max_connections(e.dict_find_int_value("max_connections", 0)); set_max_connections(e->dict_find_int_value("max_connections", 0));
for (int i = 0; i < sizeof(all_settings)/sizeof(all_settings[0]); ++i) for (int i = 0; i < sizeof(all_settings)/sizeof(all_settings[0]); ++i)
{ {
session_category const& c = all_settings[i]; session_category const& c = all_settings[i];
settings = e.dict_find_dict(c.name); settings = e->dict_find_dict(c.name);
if (!settings) continue; if (!settings) continue;
load_struct(*settings, reinterpret_cast<char*>(this) + c.offset, c.map, c.num_entries); load_struct(*settings, reinterpret_cast<char*>(this) + c.offset, c.map, c.num_entries);
} }
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
settings = e.dict_find_dict("dht"); settings = e->dict_find_dict("dht");
if (settings) if (settings)
{ {
dht_settings s; dht_settings s;
@ -844,7 +841,7 @@ namespace aux {
, sizeof(dht_settings_map)/sizeof(dht_settings_map[0])); , sizeof(dht_settings_map)/sizeof(dht_settings_map[0]));
set_dht_settings(s); set_dht_settings(s);
} }
settings = e.dict_find_dict("dht state"); settings = e->dict_find_dict("dht state");
if (settings) if (settings)
{ {
m_dht_state = *settings; m_dht_state = *settings;
@ -853,7 +850,7 @@ namespace aux {
#endif #endif
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
settings = e.dict_find_dict("i2p"); settings = e->dict_find_dict("i2p");
if (settings) if (settings)
{ {
proxy_settings s; proxy_settings s;
@ -863,7 +860,7 @@ namespace aux {
} }
#endif #endif
#ifndef TORRENT_DISABLE_GEO_IP #ifndef TORRENT_DISABLE_GEO_IP
settings = e.dict_find_dict("AS map"); settings = e->dict_find_dict("AS map");
if (settings) if (settings)
{ {
for (int i = 0; i < settings->dict_size(); ++i) for (int i = 0; i < settings->dict_size(); ++i)
@ -1115,6 +1112,15 @@ namespace aux {
// the uTP connections cannot be closed gracefully // the uTP connections cannot be closed gracefully
m_udp_socket.close(); m_udp_socket.close();
m_external_udp_port = 0; m_external_udp_port = 0;
#ifndef TORRENT_DISABLE_GEO_IP
if (m_asnum_db) GeoIP_delete(m_asnum_db);
if (m_country_db) GeoIP_delete(m_country_db);
m_asnum_db = 0;
m_country_db = 0;
#endif
m_disk_thread.abort();
} }
void session_impl::set_port_filter(port_filter const& f) void session_impl::set_port_filter(port_filter const& f)
@ -1635,13 +1641,12 @@ namespace aux {
void session_impl::on_accept_connection(shared_ptr<socket_type> const& s void session_impl::on_accept_connection(shared_ptr<socket_type> const& s
, weak_ptr<socket_acceptor> listen_socket, error_code const& e) , weak_ptr<socket_acceptor> listen_socket, error_code const& e)
{ {
TORRENT_ASSERT(is_network_thread());
boost::shared_ptr<socket_acceptor> listener = listen_socket.lock(); boost::shared_ptr<socket_acceptor> listener = listen_socket.lock();
if (!listener) return; if (!listener) return;
if (e == asio::error::operation_aborted) return; if (e == asio::error::operation_aborted) return;
mutex::scoped_lock l(m_mutex);
if (m_abort) return; if (m_abort) return;
error_code ec; error_code ec;
@ -1918,8 +1923,8 @@ namespace aux {
// wake them up // wake them up
void session_impl::on_disk_queue() void session_impl::on_disk_queue()
{ {
mutex::scoped_lock l(m_mutex); TORRENT_ASSERT(is_network_thread());
for (connection_map::iterator i = m_connections.begin(); for (connection_map::iterator i = m_connections.begin();
i != m_connections.end();) i != m_connections.end();)
{ {
@ -1948,7 +1953,7 @@ namespace aux {
void session_impl::on_tick(error_code const& e) void session_impl::on_tick(error_code const& e)
{ {
mutex::scoped_lock l(m_mutex); TORRENT_ASSERT(is_network_thread());
ptime now = time_now_hires(); ptime now = time_now_hires();
aux::g_current_time = now; aux::g_current_time = now;
@ -2438,9 +2443,9 @@ namespace aux {
void session_impl::on_dht_announce(error_code const& e) void session_impl::on_dht_announce(error_code const& e)
{ {
TORRENT_ASSERT(is_network_thread());
if (e) return; if (e) return;
mutex::scoped_lock l(m_mutex);
if (m_abort) return; if (m_abort) return;
// announce to DHT every 15 minutes // announce to DHT every 15 minutes
@ -2464,9 +2469,9 @@ namespace aux {
void session_impl::on_lsd_announce(error_code const& e) void session_impl::on_lsd_announce(error_code const& e)
{ {
TORRENT_ASSERT(is_network_thread());
if (e) return; if (e) return;
mutex::scoped_lock l(m_mutex);
if (m_abort) return; if (m_abort) return;
// announce on local network every 5 minutes // announce on local network every 5 minutes
@ -2944,6 +2949,12 @@ namespace aux {
void session_impl::main_thread() void session_impl::main_thread()
{ {
#ifdef TORRENT_DEBUG
#if defined BOOST_HAS_PTHREADS
m_network_thread = pthread_self();
#endif
#endif
TORRENT_ASSERT(is_network_thread());
eh_initializer(); eh_initializer();
bool stop_loop = false; bool stop_loop = false;
@ -2961,7 +2972,6 @@ namespace aux {
} }
m_io_service.reset(); m_io_service.reset();
mutex::scoped_lock l(m_mutex);
stop_loop = m_abort; stop_loop = m_abort;
} }
@ -2969,7 +2979,6 @@ namespace aux {
(*m_logger) << time_now_string() << " locking mutex\n"; (*m_logger) << time_now_string() << " locking mutex\n";
#endif #endif
mutex::scoped_lock l(m_mutex);
/* /*
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
for (torrent_map::iterator i = m_torrents.begin(); for (torrent_map::iterator i = m_torrents.begin();
@ -2993,6 +3002,8 @@ namespace aux {
// session is locked! // session is locked!
boost::weak_ptr<torrent> session_impl::find_torrent(sha1_hash const& info_hash) boost::weak_ptr<torrent> session_impl::find_torrent(sha1_hash const& info_hash)
{ {
TORRENT_ASSERT(is_network_thread());
std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator i std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator i
= m_torrents.find(info_hash); = m_torrents.find(info_hash);
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
@ -3274,7 +3285,7 @@ namespace aux {
void session_impl::on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih) void session_impl::on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih)
{ {
mutex::scoped_lock l(m_mutex); TORRENT_ASSERT(is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -3308,7 +3319,8 @@ namespace aux {
void session_impl::on_port_mapping(int mapping, int port void session_impl::on_port_mapping(int mapping, int port
, error_code const& ec, int map_transport) , error_code const& ec, int map_transport)
{ {
mutex::scoped_lock l(m_mutex); TORRENT_ASSERT(is_network_thread());
TORRENT_ASSERT(map_transport >= 0 && map_transport <= 1); TORRENT_ASSERT(map_transport >= 0 && map_transport <= 1);
if (mapping == m_udp_mapping[map_transport] && port != 0) if (mapping == m_udp_mapping[map_transport] && port != 0)
@ -3521,30 +3533,15 @@ namespace aux {
m_dht_settings = settings; m_dht_settings = settings;
} }
void session_impl::on_dht_state_callback(condition& c
, entry& e, bool& done) const
{
mutex::scoped_lock l(m_mutex);
if (m_dht) e = m_dht->state();
done = true;
c.signal(l);
}
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
entry session_impl::dht_state(mutex::scoped_lock& l) const entry session_impl::dht_state() const
{ {
condition cond;
if (!m_dht) return entry(); if (!m_dht) return entry();
entry e; return m_dht->state();
bool done = false;
m_io_service.post(boost::bind(&session_impl::on_dht_state_callback
, this, boost::ref(cond), boost::ref(e), boost::ref(done)));
while (!done) cond.wait(l);
return e;
} }
#endif #endif
void session_impl::add_dht_node(std::pair<std::string, int> const& node) void session_impl::add_dht_node_name(std::pair<std::string, int> const& node)
{ {
TORRENT_ASSERT(m_dht); TORRENT_ASSERT(m_dht);
m_dht->add_node(node); m_dht->add_node(node);
@ -3584,22 +3581,15 @@ namespace aux {
session_impl::~session_impl() session_impl::~session_impl()
{ {
mutex::scoped_lock l(m_mutex); #if defined BOOST_HAS_PTHREADS
TORRENT_ASSERT(!is_network_thread());
#endif
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
(*m_logger) << time_now_string() << "\n\n *** shutting down session *** \n\n"; (*m_logger) << time_now_string() << "\n\n *** shutting down session *** \n\n";
#endif #endif
abort(); m_io_service.post(boost::bind(&session_impl::abort, this));
TORRENT_ASSERT(m_connections.empty());
#ifndef TORRENT_DISABLE_GEO_IP
if (m_asnum_db) GeoIP_delete(m_asnum_db);
if (m_country_db) GeoIP_delete(m_country_db);
m_asnum_db = 0;
m_country_db = 0;
#endif
l.unlock();
// we need to wait for the disk-io thread to // we need to wait for the disk-io thread to
// die first, to make sure it won't post any // die first, to make sure it won't post any
// more messages to the io_service containing references // more messages to the io_service containing references
@ -3702,7 +3692,7 @@ namespace aux {
m_upload_channel.throttle(bytes_per_second); m_upload_channel.throttle(bytes_per_second);
} }
void session_impl::set_alert_dispatch(boost::function<void(alert const&)> const& fun) void session_impl::set_alert_dispatch(boost::function<void(std::auto_ptr<alert>)> const& fun)
{ {
m_alerts.set_dispatch_function(fun); m_alerts.set_dispatch_function(fun);
} }
@ -3712,9 +3702,7 @@ namespace aux {
// too expensive // too expensive
// INVARIANT_CHECK; // INVARIANT_CHECK;
if (m_alerts.pending()) return m_alerts.get();
return m_alerts.get();
return std::auto_ptr<alert>(0);
} }
alert const* session_impl::wait_for_alert(time_duration max_wait) alert const* session_impl::wait_for_alert(time_duration max_wait)
@ -3765,10 +3753,22 @@ namespace aux {
m_lsd->use_broadcast(true); m_lsd->use_broadcast(true);
} }
void session_impl::start_natpmp(natpmp* n) natpmp* session_impl::start_natpmp()
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
if (m_natpmp) return m_natpmp.get();
// the natpmp constructor may fail and call the callbacks
// into the session_impl.
natpmp* n = new (std::nothrow) natpmp(m_io_service
, m_listen_interface.address()
, boost::bind(&session_impl::on_port_mapping
, this, _1, _2, _3, 0)
, boost::bind(&session_impl::on_port_map_log
, this, _1, 0));
if (n == 0) return 0;
m_natpmp = n; m_natpmp = n;
if (m_listen_interface.port() > 0) if (m_listen_interface.port() > 0)
@ -3783,10 +3783,25 @@ namespace aux {
} }
} }
void session_impl::start_upnp(upnp* u) upnp* session_impl::start_upnp()
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
if (m_upnp) return m_upnp.get();
// the upnp constructor may fail and call the callbacks
upnp* u = new (std::nothrow) upnp(m_io_service
, m_half_open
, m_listen_interface.address()
, m_settings.user_agent
, boost::bind(&session_impl::on_port_mapping
, this, _1, _2, _3, 1)
, boost::bind(&session_impl::on_port_map_log
, this, _1, 1)
, m_settings.upnp_ignore_nonrouters);
if (u == 0) return 0;
m_upnp = u; m_upnp = u;
m_upnp->discover_device(); m_upnp->discover_device();

View File

@ -167,7 +167,7 @@ namespace
void on_read_failed_block(piece_block b, address a, int ret, disk_io_job const& j) void on_read_failed_block(piece_block b, address a, int ret, disk_io_job const& j)
{ {
mutex::scoped_lock l(m_torrent.session().m_mutex); TORRENT_ASSERT(m_torrent.session().is_network_thread());
disk_buffer_holder buffer(m_torrent.session(), j.buffer); disk_buffer_holder buffer(m_torrent.session(), j.buffer);
@ -248,7 +248,7 @@ namespace
void on_read_ok_block(std::pair<piece_block, block_entry> b, int ret, disk_io_job const& j) void on_read_ok_block(std::pair<piece_block, block_entry> b, int ret, disk_io_job const& j)
{ {
mutex::scoped_lock l(m_torrent.session().m_mutex); TORRENT_ASSERT(m_torrent.session().is_network_thread());
disk_buffer_holder buffer(m_torrent.session(), j.buffer); disk_buffer_holder buffer(m_torrent.session(), j.buffer);

View File

@ -636,7 +636,7 @@ namespace libtorrent
void torrent::on_disk_read_complete(int ret, disk_io_job const& j, peer_request r, read_piece_struct* rp) void torrent::on_disk_read_complete(int ret, disk_io_job const& j, peer_request r, read_piece_struct* rp)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
disk_buffer_holder buffer(m_ses, j.buffer); disk_buffer_holder buffer(m_ses, j.buffer);
@ -716,7 +716,7 @@ namespace libtorrent
void torrent::on_disk_write_complete(int ret, disk_io_job const& j void torrent::on_disk_write_complete(int ret, disk_io_job const& j
, peer_request p) , peer_request p)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -864,7 +864,7 @@ namespace libtorrent
if (m_seed_mode) if (m_seed_mode)
{ {
m_ses.m_io_service.post(boost::bind(&torrent::files_checked_lock, shared_from_this())); m_ses.m_io_service.post(boost::bind(&torrent::files_checked, shared_from_this()));
std::vector<char>().swap(m_resume_data); std::vector<char>().swap(m_resume_data);
lazy_entry().swap(m_resume_entry); lazy_entry().swap(m_resume_entry);
return; return;
@ -937,7 +937,7 @@ namespace libtorrent
void torrent::on_resume_data_checked(int ret, disk_io_job const& j) void torrent::on_resume_data_checked(int ret, disk_io_job const& j)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
if (ret == piece_manager::fatal_disk_error) if (ret == piece_manager::fatal_disk_error)
{ {
@ -1120,7 +1120,7 @@ namespace libtorrent
} }
} }
files_checked(l); files_checked();
} }
else else
{ {
@ -1191,7 +1191,7 @@ namespace libtorrent
void torrent::on_force_recheck(int ret, disk_io_job const& j) void torrent::on_force_recheck(int ret, disk_io_job const& j)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
if (ret == piece_manager::fatal_disk_error) if (ret == piece_manager::fatal_disk_error)
{ {
@ -1201,7 +1201,7 @@ namespace libtorrent
if (ret == 0) if (ret == 0)
{ {
// if there are no files, just start // if there are no files, just start
files_checked(l); files_checked();
} }
else else
{ {
@ -1223,7 +1223,7 @@ namespace libtorrent
void torrent::on_piece_checked(int ret, disk_io_job const& j) void torrent::on_piece_checked(int ret, disk_io_job const& j)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
if (ret == piece_manager::disk_check_aborted) if (ret == piece_manager::disk_check_aborted)
@ -1263,15 +1263,15 @@ namespace libtorrent
if (ret == piece_manager::need_full_check) return; if (ret == piece_manager::need_full_check) return;
dequeue_torrent_check(); dequeue_torrent_check();
files_checked(l); files_checked();
} }
void torrent::use_interface(const char* net_interface) void torrent::use_interface(std::string net_interface)
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
error_code ec; error_code ec;
address a(address::from_string(net_interface, ec)); address a(address::from_string(net_interface.c_str(), ec));
if (ec) return; if (ec) return;
m_net_interface = tcp::endpoint(a, 0); m_net_interface = tcp::endpoint(a, 0);
} }
@ -1287,7 +1287,7 @@ namespace libtorrent
void torrent::on_tracker_announce() void torrent::on_tracker_announce()
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
m_waiting_tracker = false; m_waiting_tracker = false;
if (m_abort) return; if (m_abort) return;
announce_with_tracker(); announce_with_tracker();
@ -1537,7 +1537,7 @@ namespace libtorrent
void torrent::tracker_warning(tracker_request const& req, std::string const& msg) void torrent::tracker_warning(tracker_request const& req, std::string const& msg)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -1548,7 +1548,7 @@ namespace libtorrent
void torrent::tracker_scrape_response(tracker_request const& req void torrent::tracker_scrape_response(tracker_request const& req
, int complete, int incomplete, int downloaded) , int complete, int incomplete, int downloaded)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(req.kind == tracker_request::scrape_request); TORRENT_ASSERT(req.kind == tracker_request::scrape_request);
@ -1574,7 +1574,7 @@ namespace libtorrent
, int incomplete , int incomplete
, address const& external_ip) , address const& external_ip)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(r.kind == tracker_request::announce_request); TORRENT_ASSERT(r.kind == tracker_request::announce_request);
@ -1756,7 +1756,7 @@ namespace libtorrent
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
void torrent::on_i2p_resolve(error_code const& ec, char const* dest) void torrent::on_i2p_resolve(error_code const& ec, char const* dest)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -1773,7 +1773,7 @@ namespace libtorrent
void torrent::on_peer_name_lookup(error_code const& e, tcp::resolver::iterator host void torrent::on_peer_name_lookup(error_code const& e, tcp::resolver::iterator host
, peer_id pid) , peer_id pid)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -2572,7 +2572,7 @@ namespace libtorrent
void torrent::on_files_deleted(int ret, disk_io_job const& j) void torrent::on_files_deleted(int ret, disk_io_job const& j)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
if (ret != 0) if (ret != 0)
{ {
@ -2589,7 +2589,7 @@ namespace libtorrent
void torrent::on_files_released(int ret, disk_io_job const& j) void torrent::on_files_released(int ret, disk_io_job const& j)
{ {
/* /*
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
if (alerts().should_post<torrent_paused_alert>()) if (alerts().should_post<torrent_paused_alert>())
{ {
@ -2606,7 +2606,7 @@ namespace libtorrent
void torrent::on_save_resume_data(int ret, disk_io_job const& j) void torrent::on_save_resume_data(int ret, disk_io_job const& j)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
if (!j.resume_data) if (!j.resume_data)
{ {
@ -2623,7 +2623,7 @@ namespace libtorrent
void torrent::on_file_renamed(int ret, disk_io_job const& j) void torrent::on_file_renamed(int ret, disk_io_job const& j)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
if (ret == 0) if (ret == 0)
{ {
@ -2641,7 +2641,7 @@ namespace libtorrent
void torrent::on_torrent_paused(int ret, disk_io_job const& j) void torrent::on_torrent_paused(int ret, disk_io_job const& j)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
if (alerts().should_post<torrent_paused_alert>()) if (alerts().should_post<torrent_paused_alert>())
alerts().post_alert(torrent_paused_alert(get_handle())); alerts().post_alert(torrent_paused_alert(get_handle()));
@ -3348,7 +3348,7 @@ namespace libtorrent
void torrent::on_proxy_name_lookup(error_code const& e, tcp::resolver::iterator host void torrent::on_proxy_name_lookup(error_code const& e, tcp::resolver::iterator host
, std::list<web_seed_entry>::iterator web) , std::list<web_seed_entry>::iterator web)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -3411,7 +3411,7 @@ namespace libtorrent
void torrent::on_name_lookup(error_code const& e, tcp::resolver::iterator host void torrent::on_name_lookup(error_code const& e, tcp::resolver::iterator host
, std::list<web_seed_entry>::iterator web, tcp::endpoint proxy) , std::list<web_seed_entry>::iterator web, tcp::endpoint proxy)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -3564,7 +3564,7 @@ namespace libtorrent
void torrent::on_country_lookup(error_code const& error, tcp::resolver::iterator i void torrent::on_country_lookup(error_code const& error, tcp::resolver::iterator i
, intrusive_ptr<peer_connection> p) const , intrusive_ptr<peer_connection> p) const
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -4688,14 +4688,9 @@ namespace libtorrent
return index; return index;
} }
void torrent::files_checked_lock() void torrent::files_checked()
{
mutex::scoped_lock l(m_ses.m_mutex);
files_checked(l);
}
void torrent::files_checked(mutex::scoped_lock const& l)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(m_torrent_file->is_valid()); TORRENT_ASSERT(m_torrent_file->is_valid());
if (m_abort) return; if (m_abort) return;
@ -4799,6 +4794,7 @@ namespace libtorrent
void torrent::move_storage(std::string const& save_path) void torrent::move_storage(std::string const& save_path)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
if (m_owning_storage.get()) if (m_owning_storage.get())
@ -4818,7 +4814,7 @@ namespace libtorrent
void torrent::on_storage_moved(int ret, disk_io_job const& j) void torrent::on_storage_moved(int ret, disk_io_job const& j)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
if (ret == 0) if (ret == 0)
{ {
@ -4847,17 +4843,20 @@ namespace libtorrent
torrent_handle torrent::get_handle() torrent_handle torrent::get_handle()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
return torrent_handle(shared_from_this()); return torrent_handle(shared_from_this());
} }
session_settings const& torrent::settings() const session_settings const& torrent::settings() const
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
return m_ses.settings(); return m_ses.settings();
} }
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
void torrent::check_invariant() const void torrent::check_invariant() const
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
if (is_paused()) TORRENT_ASSERT(num_peers() == 0); if (is_paused()) TORRENT_ASSERT(num_peers() == 0);
if (!should_check_files()) if (!should_check_files())
@ -5005,10 +5004,25 @@ namespace libtorrent
#endif #endif
void torrent::set_sequential_download(bool sd) void torrent::set_sequential_download(bool sd)
{ m_sequential_download = sd; } {
TORRENT_ASSERT(m_ses.is_network_thread());
m_sequential_download = sd;
}
void torrent::queue_up()
{
set_queue_position(queue_position() == 0
? queue_position() : queue_position() - 1);
}
void torrent::queue_down()
{
set_queue_position(queue_position() + 1);
}
void torrent::set_queue_position(int p) void torrent::set_queue_position(int p)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT((p == -1) == is_finished() TORRENT_ASSERT((p == -1) == is_finished()
|| (!m_auto_managed && p == -1) || (!m_auto_managed && p == -1)
|| (m_abort && p == -1)); || (m_abort && p == -1));
@ -5080,6 +5094,7 @@ namespace libtorrent
void torrent::set_max_uploads(int limit) void torrent::set_max_uploads(int limit)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(limit >= -1); TORRENT_ASSERT(limit >= -1);
if (limit <= 0) limit = (std::numeric_limits<int>::max)(); if (limit <= 0) limit = (std::numeric_limits<int>::max)();
m_max_uploads = limit; m_max_uploads = limit;
@ -5087,6 +5102,7 @@ namespace libtorrent
void torrent::set_max_connections(int limit) void torrent::set_max_connections(int limit)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(limit >= -1); TORRENT_ASSERT(limit >= -1);
if (limit <= 0) limit = (std::numeric_limits<int>::max)(); if (limit <= 0) limit = (std::numeric_limits<int>::max)();
m_max_connections = limit; m_max_connections = limit;
@ -5094,6 +5110,7 @@ namespace libtorrent
void torrent::set_peer_upload_limit(tcp::endpoint ip, int limit) void torrent::set_peer_upload_limit(tcp::endpoint ip, int limit)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(limit >= -1); TORRENT_ASSERT(limit >= -1);
peer_iterator i = std::find_if(m_connections.begin(), m_connections.end() peer_iterator i = std::find_if(m_connections.begin(), m_connections.end()
, boost::bind(&peer_connection::remote, _1) == ip); , boost::bind(&peer_connection::remote, _1) == ip);
@ -5103,6 +5120,7 @@ namespace libtorrent
void torrent::set_peer_download_limit(tcp::endpoint ip, int limit) void torrent::set_peer_download_limit(tcp::endpoint ip, int limit)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(limit >= -1); TORRENT_ASSERT(limit >= -1);
peer_iterator i = std::find_if(m_connections.begin(), m_connections.end() peer_iterator i = std::find_if(m_connections.begin(), m_connections.end()
, boost::bind(&peer_connection::remote, _1) == ip); , boost::bind(&peer_connection::remote, _1) == ip);
@ -5112,6 +5130,7 @@ namespace libtorrent
void torrent::set_upload_limit(int limit) void torrent::set_upload_limit(int limit)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(limit >= -1); TORRENT_ASSERT(limit >= -1);
if (limit <= 0) limit = 0; if (limit <= 0) limit = 0;
m_bandwidth_channel[peer_connection::upload_channel].throttle(limit); m_bandwidth_channel[peer_connection::upload_channel].throttle(limit);
@ -5119,6 +5138,7 @@ namespace libtorrent
int torrent::upload_limit() const int torrent::upload_limit() const
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
int limit = m_bandwidth_channel[peer_connection::upload_channel].throttle(); int limit = m_bandwidth_channel[peer_connection::upload_channel].throttle();
if (limit == (std::numeric_limits<int>::max)()) limit = -1; if (limit == (std::numeric_limits<int>::max)()) limit = -1;
return limit; return limit;
@ -5126,6 +5146,7 @@ namespace libtorrent
void torrent::set_download_limit(int limit) void torrent::set_download_limit(int limit)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(limit >= -1); TORRENT_ASSERT(limit >= -1);
if (limit <= 0) limit = 0; if (limit <= 0) limit = 0;
m_bandwidth_channel[peer_connection::download_channel].throttle(limit); m_bandwidth_channel[peer_connection::download_channel].throttle(limit);
@ -5133,6 +5154,7 @@ namespace libtorrent
int torrent::download_limit() const int torrent::download_limit() const
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
int limit = m_bandwidth_channel[peer_connection::download_channel].throttle(); int limit = m_bandwidth_channel[peer_connection::download_channel].throttle();
if (limit == (std::numeric_limits<int>::max)()) limit = -1; if (limit == (std::numeric_limits<int>::max)()) limit = -1;
return limit; return limit;
@ -5140,6 +5162,7 @@ namespace libtorrent
void torrent::delete_files() void torrent::delete_files()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
#if defined TORRENT_VERBOSE_LOGGING #if defined TORRENT_VERBOSE_LOGGING
for (peer_iterator i = m_connections.begin(); for (peer_iterator i = m_connections.begin();
i != m_connections.end(); ++i) i != m_connections.end(); ++i)
@ -5161,6 +5184,7 @@ namespace libtorrent
void torrent::clear_error() void torrent::clear_error()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
if (!m_error) return; if (!m_error) return;
bool checking_files = should_check_files(); bool checking_files = should_check_files();
if (m_ses.m_auto_manage_time_scaler > 2) if (m_ses.m_auto_manage_time_scaler > 2)
@ -5175,6 +5199,7 @@ namespace libtorrent
void torrent::set_error(error_code const& ec, std::string const& error_file) void torrent::set_error(error_code const& ec, std::string const& error_file)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
bool checking_files = should_check_files(); bool checking_files = should_check_files();
m_error = ec; m_error = ec;
m_error_file = error_file; m_error_file = error_file;
@ -5189,6 +5214,7 @@ namespace libtorrent
void torrent::auto_managed(bool a) void torrent::auto_managed(bool a)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
if (m_auto_managed == a) return; if (m_auto_managed == a) return;
@ -5214,6 +5240,7 @@ namespace libtorrent
// the higher seed rank, the more important to seed // the higher seed rank, the more important to seed
int torrent::seed_rank(session_settings const& s) const int torrent::seed_rank(session_settings const& s) const
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
enum flags enum flags
{ {
seed_ratio_not_met = 0x400000, seed_ratio_not_met = 0x400000,
@ -5276,6 +5303,7 @@ namespace libtorrent
// this is an async operation triggered by the client // this is an async operation triggered by the client
void torrent::save_resume_data() void torrent::save_resume_data()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
if (!m_owning_storage.get()) if (!m_owning_storage.get())
@ -5304,6 +5332,7 @@ namespace libtorrent
bool torrent::should_check_files() const bool torrent::should_check_files() const
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
// #error should m_allow_peers really affect checking? // #error should m_allow_peers really affect checking?
return (m_state == torrent_status::checking_files return (m_state == torrent_status::checking_files
|| m_state == torrent_status::queued_for_checking) || m_state == torrent_status::queued_for_checking)
@ -5314,23 +5343,27 @@ namespace libtorrent
void torrent::flush_cache() void torrent::flush_cache()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
m_storage->async_release_files( m_storage->async_release_files(
boost::bind(&torrent::on_cache_flushed, shared_from_this(), _1, _2)); boost::bind(&torrent::on_cache_flushed, shared_from_this(), _1, _2));
} }
void torrent::on_cache_flushed(int ret, disk_io_job const& j) void torrent::on_cache_flushed(int ret, disk_io_job const& j)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
if (alerts().should_post<cache_flushed_alert>()) if (alerts().should_post<cache_flushed_alert>())
alerts().post_alert(cache_flushed_alert(get_handle())); alerts().post_alert(cache_flushed_alert(get_handle()));
} }
bool torrent::is_paused() const bool torrent::is_paused() const
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
return !m_allow_peers || m_ses.is_paused(); return !m_allow_peers || m_ses.is_paused();
} }
void torrent::pause() void torrent::pause()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
if (!m_allow_peers) return; if (!m_allow_peers) return;
@ -5352,6 +5385,7 @@ namespace libtorrent
void torrent::do_pause() void torrent::do_pause()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
if (!is_paused()) return; if (!is_paused()) return;
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
@ -5397,6 +5431,7 @@ namespace libtorrent
void torrent::set_allow_peers(bool b) void torrent::set_allow_peers(bool b)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
if (m_allow_peers == b) return; if (m_allow_peers == b) return;
bool checking_files = should_check_files(); bool checking_files = should_check_files();
@ -5421,6 +5456,7 @@ namespace libtorrent
void torrent::resume() void torrent::resume()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
if (m_allow_peers if (m_allow_peers
@ -5439,6 +5475,7 @@ namespace libtorrent
void torrent::do_resume() void torrent::do_resume()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
if (is_paused()) return; if (is_paused()) return;
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
@ -5465,6 +5502,7 @@ namespace libtorrent
void torrent::update_tracker_timer(ptime now) void torrent::update_tracker_timer(ptime now)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
if (!m_announcing) return; if (!m_announcing) return;
ptime next_announce = max_time(); ptime next_announce = max_time();
@ -5511,6 +5549,7 @@ namespace libtorrent
void torrent::start_announcing() void torrent::start_announcing()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
if (is_paused()) return; if (is_paused()) return;
// if we don't have metadata, we need to announce // if we don't have metadata, we need to announce
// before checking files, to get peers to // before checking files, to get peers to
@ -5552,6 +5591,7 @@ namespace libtorrent
void torrent::stop_announcing() void torrent::stop_announcing()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
if (!m_announcing) return; if (!m_announcing) return;
error_code ec; error_code ec;
@ -5571,6 +5611,7 @@ namespace libtorrent
void torrent::second_tick(stat& accumulator, int tick_interval_ms) void torrent::second_tick(stat& accumulator, int tick_interval_ms)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
ptime now = time_now(); ptime now = time_now();
@ -5749,6 +5790,7 @@ namespace libtorrent
void torrent::refresh_explicit_cache(int cache_size) void torrent::refresh_explicit_cache(int cache_size)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
if (!ready_for_connections()) return; if (!ready_for_connections()) return;
// rotate the cached pieces // rotate the cached pieces
@ -5835,6 +5877,7 @@ namespace libtorrent
void torrent::get_suggested_pieces(std::vector<int>& s) const void torrent::get_suggested_pieces(std::vector<int>& s) const
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
if (settings().suggest_mode == session_settings::no_piece_suggestions) if (settings().suggest_mode == session_settings::no_piece_suggestions)
{ {
s.clear(); s.clear();
@ -5869,6 +5912,7 @@ namespace libtorrent
void torrent::add_stats(stat const& s) void torrent::add_stats(stat const& s)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
// these stats are propagated to the session // these stats are propagated to the session
// stats the next time second_tick is called // stats the next time second_tick is called
m_stat += s; m_stat += s;
@ -5876,6 +5920,7 @@ namespace libtorrent
void torrent::request_time_critical_pieces() void torrent::request_time_critical_pieces()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
// build a list of peers and sort it by download_queue_time // build a list of peers and sort it by download_queue_time
std::vector<peer_connection*> peers; std::vector<peer_connection*> peers;
peers.reserve(m_connections.size()); peers.reserve(m_connections.size());
@ -5975,6 +6020,7 @@ namespace libtorrent
std::set<std::string> torrent::web_seeds(web_seed_entry::type_t type) const std::set<std::string> torrent::web_seeds(web_seed_entry::type_t type) const
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
std::set<std::string> ret; std::set<std::string> ret;
for (std::list<web_seed_entry>::const_iterator i = m_web_seeds.begin() for (std::list<web_seed_entry>::const_iterator i = m_web_seeds.begin()
, end(m_web_seeds.end()); i != end; ++i) , end(m_web_seeds.end()); i != end; ++i)
@ -5987,6 +6033,7 @@ namespace libtorrent
void torrent::retry_web_seed(peer_connection* p, int retry) void torrent::retry_web_seed(peer_connection* p, int retry)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
std::list<web_seed_entry>::iterator i = std::find_if(m_web_seeds.begin(), m_web_seeds.end() std::list<web_seed_entry>::iterator i = std::find_if(m_web_seeds.begin(), m_web_seeds.end()
, (boost::bind(&web_seed_entry::connection, _1) == p)); , (boost::bind(&web_seed_entry::connection, _1) == p));
@ -5998,6 +6045,7 @@ namespace libtorrent
bool torrent::try_connect_peer() bool torrent::try_connect_peer()
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(want_more_peers()); TORRENT_ASSERT(want_more_peers());
if (m_deficit_counter < 100) return false; if (m_deficit_counter < 100) return false;
m_deficit_counter -= 100; m_deficit_counter -= 100;
@ -6007,14 +6055,23 @@ namespace libtorrent
void torrent::give_connect_points(int points) void torrent::give_connect_points(int points)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(points <= 100); TORRENT_ASSERT(points <= 100);
TORRENT_ASSERT(points > 0); TORRENT_ASSERT(points > 0);
TORRENT_ASSERT(want_more_peers()); TORRENT_ASSERT(want_more_peers());
m_deficit_counter += points; m_deficit_counter += points;
} }
void torrent::add_peer(tcp::endpoint const& adr, int source)
{
TORRENT_ASSERT(m_ses.is_network_thread());
peer_id id(0);
m_policy.add_peer(adr, id, source, 0);
}
void torrent::async_verify_piece(int piece_index, boost::function<void(int)> const& f) void torrent::async_verify_piece(int piece_index, boost::function<void(int)> const& f)
{ {
TORRENT_ASSERT(m_ses.is_network_thread());
// INVARIANT_CHECK; // INVARIANT_CHECK;
TORRENT_ASSERT(m_storage); TORRENT_ASSERT(m_storage);
@ -6044,7 +6101,7 @@ namespace libtorrent
void torrent::on_piece_verified(int ret, disk_io_job const& j void torrent::on_piece_verified(int ret, disk_io_job const& j
, boost::function<void(int)> f) , boost::function<void(int)> f)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
// return value: // return value:
// 0: success, piece passed hash check // 0: success, piece passed hash check
@ -6472,7 +6529,7 @@ namespace libtorrent
, int response_code, error_code const& ec, const std::string& msg , int response_code, error_code const& ec, const std::string& msg
, int retry_interval) , int retry_interval)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK; INVARIANT_CHECK;

View File

@ -61,6 +61,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/session_impl.hpp" #include "libtorrent/aux_/session_impl.hpp"
#include "libtorrent/invariant_check.hpp" #include "libtorrent/invariant_check.hpp"
#include "libtorrent/utf8.hpp" #include "libtorrent/utf8.hpp"
#include "libtorrent/thread.hpp"
#if defined(_MSC_VER) && _MSC_VER < 1300 #if defined(_MSC_VER) && _MSC_VER < 1300
namespace std namespace std
@ -72,50 +73,124 @@ namespace std
using libtorrent::aux::session_impl; using libtorrent::aux::session_impl;
#ifdef BOOST_NO_EXCEPTIONS
#define TORRENT_FORWARD(call) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) return; \
mutex::scoped_lock l(t->session().m_mutex); \
t->call
#define TORRENT_FORWARD_RETURN(call, def) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) return def; \
mutex::scoped_lock l(t->session().m_mutex); \
return t->call
#define TORRENT_FORWARD_RETURN2(call, def) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) return def; \
mutex::scoped_lock l(t->session().m_mutex); \
t->call
#else
#define TORRENT_FORWARD(call) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) throw_invalid_handle(); \
mutex::scoped_lock l(t->session().m_mutex); \
t->call
#define TORRENT_FORWARD_RETURN(call, def) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) throw_invalid_handle(); \
mutex::scoped_lock l(t->session().m_mutex); \
return t->call
#define TORRENT_FORWARD_RETURN2(call, def) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) throw_invalid_handle(); \
mutex::scoped_lock l(t->session().m_mutex); \
t->call
#endif
namespace libtorrent namespace libtorrent
{ {
template <class R>
void fun_ret(R* ret, bool* done, condition* e, mutex* m, boost::function<R(void)> f)
{
*ret = f();
mutex::scoped_lock l(*m);
*done = true;
e->signal(l);
}
// defined in session.cpp
void fun_wrap(bool* done, condition* e, mutex* m, boost::function<void(void)> f);
#define TORRENT_ASYNC_CALL(x) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) return; \
session_impl& ses = t->session(); \
ses.m_io_service.post(boost::bind(&torrent:: x, t))
#define TORRENT_ASYNC_CALL1(x, a1) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) return; \
session_impl& ses = t->session(); \
ses.m_io_service.post(boost::bind(&torrent:: x, t, a1))
#define TORRENT_ASYNC_CALL2(x, a1, a2) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) return; \
session_impl& ses = t->session(); \
ses.m_io_service.post(boost::bind(&torrent:: x, t, a1, a2))
#define TORRENT_ASYNC_CALL3(x, a1, a2, a3) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) return; \
session_impl& ses = t->session(); \
ses.m_io_service.post(boost::bind(&torrent:: x, t, a1, a2, a3))
#define TORRENT_SYNC_CALL(x) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) return; \
bool done = false; \
session_impl& ses = t->session(); \
mutex::scoped_lock l(ses.mut); \
ses.cond.clear(l); \
ses.m_io_service.post(boost::bind(&fun_wrap, &done, &ses.cond, &ses.mut, boost::function<void(void)>(boost::bind(&torrent:: x, t)))); \
do { ses.cond.wait(l); } while(!done)
#define TORRENT_SYNC_CALL1(x, a1) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (t) { \
bool done = false; \
session_impl& ses = t->session(); \
mutex::scoped_lock l(ses.mut); \
ses.cond.clear(l); \
ses.m_io_service.post(boost::bind(&fun_wrap, &done, &ses.cond, &ses.mut, boost::function<void(void)>(boost::bind(&torrent:: x, t, a1)))); \
t.reset(); \
do { ses.cond.wait(l); } while(!done); }
#define TORRENT_SYNC_CALL2(x, a1, a2) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (t) { \
bool done = false; \
session_impl& ses = t->session(); \
mutex::scoped_lock l(ses.mut); \
ses.cond.clear(l); \
ses.m_io_service.post(boost::bind(&fun_wrap, &done, &ses.cond, &ses.mut, boost::function<void(void)>(boost::bind(&torrent:: x, t, a1, a2)))); \
t.reset(); \
do { ses.cond.wait(l); } while(!done); }
#define TORRENT_SYNC_CALL3(x, a1, a2, a3) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (t) { \
bool done = false; \
session_impl& ses = t->session(); \
mutex::scoped_lock l(ses.mut); \
ses.cond.clear(l); \
ses.m_io_service.post(boost::bind(&fun_wrap, &done, &ses.cond, &ses.mut, boost::function<void(void)>(boost::bind(&torrent:: x, t, a1, a2, a3)))); \
t.reset(); \
do { ses.cond.wait(l); } while(!done); }
#define TORRENT_SYNC_CALL_RET(type, def, x) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) return def; \
bool done = false; \
session_impl& ses = t->session(); \
type r; \
mutex::scoped_lock l(ses.mut); \
ses.cond.clear(l); \
ses.m_io_service.post(boost::bind(&fun_ret<type>, &r, &done, &ses.cond, &ses.mut, boost::function<type(void)>(boost::bind(&torrent:: x, t)))); \
t.reset(); \
do { ses.cond.wait(l); } while(!done)
#define TORRENT_SYNC_CALL_RET1(type, def, x, a1) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) return def; \
bool done = false; \
session_impl& ses = t->session(); \
type r; \
mutex::scoped_lock l(ses.mut); \
ses.cond.clear(l); \
ses.m_io_service.post(boost::bind(&fun_ret<type>, &r, &done, &ses.cond, &ses.mut, boost::function<type(void)>(boost::bind(&torrent:: x, t, a1)))); \
t.reset(); \
do { ses.cond.wait(l); } while(!done)
#define TORRENT_SYNC_CALL_RET2(type, def, x, a1, a2) \
boost::shared_ptr<torrent> t = m_torrent.lock(); \
if (!t) return def; \
bool done = false; \
session_impl& ses = t->session(); \
type r; \
mutex::scoped_lock l(ses.mut); \
ses.cond.clear(l); \
ses.m_io_service.post(boost::bind(&fun_ret<type>, &r, &done, &ses.cond, &ses.mut, boost::function<type(void)>(boost::bind(&torrent:: x, t, a1, a2)))); \
t.reset(); \
do { ses.cond.wait(l); } while(!done)
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
void throw_invalid_handle() void throw_invalid_handle()
{ {
@ -134,86 +209,91 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
const static sha1_hash empty; const static sha1_hash empty;
TORRENT_FORWARD_RETURN(torrent_file().info_hash(), empty); TORRENT_SYNC_CALL_RET(sha1_hash, empty, info_hash);
return r;
} }
int torrent_handle::max_uploads() const int torrent_handle::max_uploads() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(max_uploads(), 0); TORRENT_SYNC_CALL_RET(int, 0, max_uploads);
return r;
} }
void torrent_handle::set_max_uploads(int max_uploads) const void torrent_handle::set_max_uploads(int max_uploads) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(max_uploads >= 2 || max_uploads == -1); TORRENT_ASSERT(max_uploads >= 2 || max_uploads == -1);
TORRENT_FORWARD(set_max_uploads(max_uploads)); TORRENT_ASYNC_CALL1(set_max_uploads, max_uploads);
} }
void torrent_handle::use_interface(const char* net_interface) const void torrent_handle::use_interface(const char* net_interface) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(use_interface(net_interface)); TORRENT_ASYNC_CALL1(use_interface, std::string(net_interface));
} }
int torrent_handle::max_connections() const int torrent_handle::max_connections() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(max_connections(), 0); TORRENT_SYNC_CALL_RET(int, 0, max_connections);
return r;
} }
void torrent_handle::set_max_connections(int max_connections) const void torrent_handle::set_max_connections(int max_connections) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(max_connections >= 2 || max_connections == -1); TORRENT_ASSERT(max_connections >= 2 || max_connections == -1);
TORRENT_FORWARD(set_max_connections(max_connections)); TORRENT_ASYNC_CALL1(set_max_connections, max_connections);
} }
void torrent_handle::set_peer_upload_limit(tcp::endpoint ip, int limit) const void torrent_handle::set_peer_upload_limit(tcp::endpoint ip, int limit) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(limit >= -1); TORRENT_ASSERT(limit >= -1);
TORRENT_FORWARD(set_peer_upload_limit(ip, limit)); TORRENT_ASYNC_CALL2(set_peer_upload_limit, ip, limit);
} }
void torrent_handle::set_peer_download_limit(tcp::endpoint ip, int limit) const void torrent_handle::set_peer_download_limit(tcp::endpoint ip, int limit) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(limit >= -1); TORRENT_ASSERT(limit >= -1);
TORRENT_FORWARD(set_peer_download_limit(ip, limit)); TORRENT_ASYNC_CALL2(set_peer_download_limit, ip, limit);
} }
void torrent_handle::set_upload_limit(int limit) const void torrent_handle::set_upload_limit(int limit) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(limit >= -1); TORRENT_ASSERT(limit >= -1);
TORRENT_FORWARD(set_upload_limit(limit)); TORRENT_ASYNC_CALL1(set_upload_limit, limit);
} }
int torrent_handle::upload_limit() const int torrent_handle::upload_limit() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(upload_limit(), 0); TORRENT_SYNC_CALL_RET(int, 0, upload_limit);
return r;
} }
void torrent_handle::set_download_limit(int limit) const void torrent_handle::set_download_limit(int limit) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(limit >= -1); TORRENT_ASSERT(limit >= -1);
TORRENT_FORWARD(set_download_limit(limit)); TORRENT_ASYNC_CALL1(set_download_limit, limit);
} }
int torrent_handle::download_limit() const int torrent_handle::download_limit() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(download_limit(), 0); TORRENT_SYNC_CALL_RET(int, 0, download_limit);
return r;
} }
void torrent_handle::move_storage( void torrent_handle::move_storage(
std::string const& save_path) const std::string const& save_path) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(move_storage(save_path)); TORRENT_ASYNC_CALL1(move_storage, save_path);
} }
#if TORRENT_USE_WSTRING #if TORRENT_USE_WSTRING
@ -223,7 +303,7 @@ namespace libtorrent
INVARIANT_CHECK; INVARIANT_CHECK;
std::string utf8; std::string utf8;
wchar_utf8(save_path, utf8); wchar_utf8(save_path, utf8);
TORRENT_FORWARD(move_storage(utf8)); TORRENT_ASYNC_CALL1(move_storage, utf8);
} }
void torrent_handle::rename_file(int index, std::wstring const& new_name) const void torrent_handle::rename_file(int index, std::wstring const& new_name) const
@ -231,14 +311,14 @@ namespace libtorrent
INVARIANT_CHECK; INVARIANT_CHECK;
std::string utf8; std::string utf8;
wchar_utf8(new_name, utf8); wchar_utf8(new_name, utf8);
TORRENT_FORWARD(rename_file(index, utf8)); TORRENT_ASYNC_CALL2(rename_file, index, utf8);
} }
#endif // TORRENT_USE_WSTRING #endif // TORRENT_USE_WSTRING
void torrent_handle::rename_file(int index, std::string const& new_name) const void torrent_handle::rename_file(int index, std::string const& new_name) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(rename_file(index, new_name)); TORRENT_ASYNC_CALL2(rename_file, index, new_name);
} }
void torrent_handle::add_extension( void torrent_handle::add_extension(
@ -246,141 +326,148 @@ namespace libtorrent
, void* userdata) , void* userdata)
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(add_extension(ext, userdata)); TORRENT_ASYNC_CALL2(add_extension, ext, userdata);
} }
bool torrent_handle::has_metadata() const bool torrent_handle::has_metadata() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(valid_metadata(), false); TORRENT_SYNC_CALL_RET(bool, false, valid_metadata);
return r;
} }
bool torrent_handle::set_metadata(char const* metadata, int size) const bool torrent_handle::set_metadata(char const* metadata, int size) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(set_metadata(metadata, size), false); TORRENT_SYNC_CALL_RET2(bool, false, set_metadata, metadata, size);
return r;
} }
bool torrent_handle::is_seed() const bool torrent_handle::is_seed() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(is_seed(), false); TORRENT_SYNC_CALL_RET(bool, false, is_seed);
return r;
} }
bool torrent_handle::is_finished() const bool torrent_handle::is_finished() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(is_finished(), false); TORRENT_SYNC_CALL_RET(bool, false, is_finished);
return r;
} }
bool torrent_handle::is_paused() const bool torrent_handle::is_paused() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(is_torrent_paused(), false); TORRENT_SYNC_CALL_RET(bool, false, is_torrent_paused);
return r;
} }
void torrent_handle::pause() const void torrent_handle::pause() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(pause()); TORRENT_ASYNC_CALL(pause);
} }
void torrent_handle::set_upload_mode(bool b) const void torrent_handle::set_upload_mode(bool b) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(set_upload_mode(b)); TORRENT_ASYNC_CALL1(set_upload_mode, b);
} }
void torrent_handle::flush_cache() const void torrent_handle::flush_cache() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(flush_cache()); TORRENT_ASYNC_CALL(flush_cache);
} }
void torrent_handle::save_resume_data() const void torrent_handle::save_resume_data() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(save_resume_data()); TORRENT_ASYNC_CALL(save_resume_data);
} }
bool torrent_handle::need_save_resume_data() const bool torrent_handle::need_save_resume_data() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(need_save_resume_data(), false); TORRENT_SYNC_CALL_RET(bool, false, need_save_resume_data);
return r;
} }
void torrent_handle::force_recheck() const void torrent_handle::force_recheck() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(force_recheck()); TORRENT_ASYNC_CALL(force_recheck);
} }
void torrent_handle::resume() const void torrent_handle::resume() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(resume()); TORRENT_ASYNC_CALL(resume);
} }
bool torrent_handle::is_auto_managed() const bool torrent_handle::is_auto_managed() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(is_auto_managed(), true); TORRENT_SYNC_CALL_RET(bool, false, is_auto_managed);
return r;
} }
void torrent_handle::auto_managed(bool m) const void torrent_handle::auto_managed(bool m) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(auto_managed(m)); TORRENT_ASYNC_CALL1(auto_managed, m);
} }
void torrent_handle::set_priority(int p) const void torrent_handle::set_priority(int p) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(set_priority(p)); TORRENT_ASYNC_CALL1(set_priority, p);
} }
int torrent_handle::queue_position() const int torrent_handle::queue_position() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(queue_position(), -1); TORRENT_SYNC_CALL_RET(int, -1, queue_position);
return r;
} }
void torrent_handle::queue_position_up() const void torrent_handle::queue_position_up() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(set_queue_position(t->queue_position() == 0 TORRENT_ASYNC_CALL(queue_down);
? t->queue_position() : t->queue_position() - 1));
} }
void torrent_handle::queue_position_down() const void torrent_handle::queue_position_down() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(set_queue_position(t->queue_position() + 1)); TORRENT_ASYNC_CALL(queue_up);
} }
void torrent_handle::queue_position_top() const void torrent_handle::queue_position_top() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(set_queue_position(0)); TORRENT_ASYNC_CALL1(set_queue_position, 0);
} }
void torrent_handle::queue_position_bottom() const void torrent_handle::queue_position_bottom() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(set_queue_position((std::numeric_limits<int>::max)())); TORRENT_ASYNC_CALL1(set_queue_position, INT_MAX);
} }
void torrent_handle::clear_error() const void torrent_handle::clear_error() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(clear_error()); TORRENT_ASYNC_CALL(clear_error);
} }
void torrent_handle::set_tracker_login(std::string const& name void torrent_handle::set_tracker_login(std::string const& name
, std::string const& password) const , std::string const& password) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(set_tracker_login(name, password)); TORRENT_ASYNC_CALL2(set_tracker_login, name, password);
} }
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
@ -388,7 +475,7 @@ namespace libtorrent
void torrent_handle::file_progress(std::vector<float>& progress) const void torrent_handle::file_progress(std::vector<float>& progress) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(file_progress(progress)); TORRENT_SYNC_CALL1(file_progress, boost::ref(progress));
} }
#endif #endif
#endif #endif
@ -396,88 +483,93 @@ namespace libtorrent
void torrent_handle::file_progress(std::vector<size_type>& progress, int flags) const void torrent_handle::file_progress(std::vector<size_type>& progress, int flags) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(file_progress(progress, flags)); TORRENT_SYNC_CALL2(file_progress, boost::ref(progress), flags);
} }
torrent_status torrent_handle::status(boost::uint32_t flags) const torrent_status torrent_handle::status(boost::uint32_t flags) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(status(flags), torrent_status()); TORRENT_SYNC_CALL_RET1(torrent_status, torrent_status(), status, flags);
return r;
} }
void torrent_handle::set_sequential_download(bool sd) const void torrent_handle::set_sequential_download(bool sd) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(set_sequential_download(sd)); TORRENT_ASYNC_CALL1(set_sequential_download, sd);
} }
bool torrent_handle::is_sequential_download() const bool torrent_handle::is_sequential_download() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(is_sequential_download(), false); TORRENT_SYNC_CALL_RET(bool, false, is_sequential_download);
return r;
} }
std::string torrent_handle::name() const std::string torrent_handle::name() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(name(), ""); TORRENT_SYNC_CALL_RET(std::string, "", name);
return r;
} }
void torrent_handle::piece_availability(std::vector<int>& avail) const void torrent_handle::piece_availability(std::vector<int>& avail) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(piece_availability(avail)); TORRENT_SYNC_CALL1(piece_availability, boost::ref(avail));
} }
void torrent_handle::piece_priority(int index, int priority) const void torrent_handle::piece_priority(int index, int priority) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(set_piece_priority(index, priority)); TORRENT_ASYNC_CALL2(set_piece_priority, index, priority);
} }
int torrent_handle::piece_priority(int index) const int torrent_handle::piece_priority(int index) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(piece_priority(index), 0); TORRENT_SYNC_CALL_RET1(int, 0, piece_priority, index);
return r;
} }
void torrent_handle::prioritize_pieces(std::vector<int> const& pieces) const void torrent_handle::prioritize_pieces(std::vector<int> const& pieces) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(prioritize_pieces(pieces)); TORRENT_ASYNC_CALL1(prioritize_pieces, pieces);
} }
std::vector<int> torrent_handle::piece_priorities() const std::vector<int> torrent_handle::piece_priorities() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
std::vector<int> ret; std::vector<int> ret;
TORRENT_FORWARD_RETURN2(piece_priorities(ret), ret); TORRENT_SYNC_CALL1(piece_priorities, boost::ref(ret));
return ret; return ret;
} }
void torrent_handle::file_priority(int index, int priority) const void torrent_handle::file_priority(int index, int priority) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(set_file_priority(index, priority)); TORRENT_ASYNC_CALL2(set_file_priority, index, priority);
} }
int torrent_handle::file_priority(int index) const int torrent_handle::file_priority(int index) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(file_priority(index), 0); TORRENT_SYNC_CALL_RET1(int, 0, file_priority, index);
return r;
} }
void torrent_handle::prioritize_files(std::vector<int> const& files) const void torrent_handle::prioritize_files(std::vector<int> const& files) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(prioritize_files(files)); TORRENT_ASYNC_CALL1(prioritize_files, files);
} }
std::vector<int> torrent_handle::file_priorities() const std::vector<int> torrent_handle::file_priorities() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
std::vector<int> ret; std::vector<int> ret;
TORRENT_FORWARD_RETURN2(file_priorities(ret), ret); TORRENT_SYNC_CALL1(file_priorities, ret);
return ret; return ret;
} }
@ -487,33 +579,34 @@ namespace libtorrent
void torrent_handle::filter_piece(int index, bool filter) const void torrent_handle::filter_piece(int index, bool filter) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(filter_piece(index, filter)); TORRENT_ASYNC_CALL2(filter_piece, index, filter);
} }
void torrent_handle::filter_pieces(std::vector<bool> const& pieces) const void torrent_handle::filter_pieces(std::vector<bool> const& pieces) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(filter_pieces(pieces)); TORRENT_ASYNC_CALL1(filter_pieces, pieces);
} }
bool torrent_handle::is_piece_filtered(int index) const bool torrent_handle::is_piece_filtered(int index) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(is_piece_filtered(index), false); TORRENT_SYNC_CALL_RET1(bool, false, is_piece_filtered, index);
return r;
} }
std::vector<bool> torrent_handle::filtered_pieces() const std::vector<bool> torrent_handle::filtered_pieces() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
std::vector<bool> ret; std::vector<bool> ret;
TORRENT_FORWARD_RETURN2(filtered_pieces(ret), ret); TORRENT_SYNC_CALL1(filtered_pieces, ret);
return ret; return ret;
} }
void torrent_handle::filter_files(std::vector<bool> const& files) const void torrent_handle::filter_files(std::vector<bool> const& files) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(filter_files(files)); TORRENT_ASYNC_CALL1(filter_files, files);
} }
// ============ end deprecation =============== // ============ end deprecation ===============
@ -523,76 +616,80 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
const static std::vector<announce_entry> empty; const static std::vector<announce_entry> empty;
TORRENT_FORWARD_RETURN(trackers(), empty); TORRENT_SYNC_CALL_RET(std::vector<announce_entry>, empty, trackers);
return r;
} }
void torrent_handle::add_url_seed(std::string const& url) const void torrent_handle::add_url_seed(std::string const& url) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(add_web_seed(url, web_seed_entry::url_seed)); TORRENT_ASYNC_CALL2(add_web_seed, url, web_seed_entry::url_seed);
} }
void torrent_handle::remove_url_seed(std::string const& url) const void torrent_handle::remove_url_seed(std::string const& url) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(remove_web_seed(url, web_seed_entry::url_seed)); TORRENT_ASYNC_CALL2(remove_web_seed, url, web_seed_entry::url_seed);
} }
std::set<std::string> torrent_handle::url_seeds() const std::set<std::string> torrent_handle::url_seeds() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
const static std::set<std::string> empty; const static std::set<std::string> empty;
TORRENT_FORWARD_RETURN(web_seeds(web_seed_entry::url_seed), empty); TORRENT_SYNC_CALL_RET1(std::set<std::string>, empty, web_seeds, web_seed_entry::url_seed);
return r;
} }
void torrent_handle::add_http_seed(std::string const& url) const void torrent_handle::add_http_seed(std::string const& url) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(add_web_seed(url, web_seed_entry::http_seed)); TORRENT_ASYNC_CALL2(add_web_seed, url, web_seed_entry::http_seed);
} }
void torrent_handle::remove_http_seed(std::string const& url) const void torrent_handle::remove_http_seed(std::string const& url) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(remove_web_seed(url, web_seed_entry::http_seed)); TORRENT_ASYNC_CALL2(remove_web_seed, url, web_seed_entry::http_seed);
} }
std::set<std::string> torrent_handle::http_seeds() const std::set<std::string> torrent_handle::http_seeds() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
const static std::set<std::string> empty; const static std::set<std::string> empty;
TORRENT_FORWARD_RETURN(web_seeds(web_seed_entry::http_seed), empty); TORRENT_SYNC_CALL_RET1(std::set<std::string>, empty, web_seeds, web_seed_entry::http_seed);
return r;
} }
void torrent_handle::replace_trackers( void torrent_handle::replace_trackers(
std::vector<announce_entry> const& urls) const std::vector<announce_entry> const& urls) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(replace_trackers(urls)); TORRENT_ASYNC_CALL1(replace_trackers, urls);
} }
void torrent_handle::add_tracker(announce_entry const& url) const void torrent_handle::add_tracker(announce_entry const& url) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(add_tracker(url)); TORRENT_ASYNC_CALL1(add_tracker, url);
} }
void torrent_handle::add_piece(int piece, char const* data, int flags) const void torrent_handle::add_piece(int piece, char const* data, int flags) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(add_piece(piece, data, flags)); TORRENT_SYNC_CALL3(add_piece, piece, data, flags);
} }
void torrent_handle::read_piece(int piece) const void torrent_handle::read_piece(int piece) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(read_piece(piece)); TORRENT_ASYNC_CALL1(read_piece, piece);
} }
storage_interface* torrent_handle::get_storage_impl() const storage_interface* torrent_handle::get_storage_impl() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(get_storage(), 0); TORRENT_SYNC_CALL_RET(storage_interface*, 0, get_storage);
return r;
} }
torrent_info const& torrent_handle::get_torrent_info() const torrent_info const& torrent_handle::get_torrent_info() const
@ -608,7 +705,7 @@ namespace libtorrent
#else #else
throw_invalid_handle(); throw_invalid_handle();
#endif #endif
mutex::scoped_lock l(t->session().m_mutex); // mutex::scoped_lock l(t->session().m_mutex);
if (!t->valid_metadata()) if (!t->valid_metadata())
#ifdef BOOST_NO_EXCEPTIONS #ifdef BOOST_NO_EXCEPTIONS
return empty; return empty;
@ -630,8 +727,18 @@ namespace libtorrent
INVARIANT_CHECK; INVARIANT_CHECK;
entry ret(entry::dictionary_t); entry ret(entry::dictionary_t);
TORRENT_FORWARD_RETURN2(write_resume_data(ret), ret); TORRENT_SYNC_CALL1(write_resume_data, boost::ref(ret));
t->filesystem().write_resume_data(ret); if (t)
{
bool done = false;
session_impl& ses = t->session();
mutex::scoped_lock l(ses.mut);
ses.cond.clear(l);
ses.m_io_service.post(boost::bind(&fun_wrap, &done, &ses.cond
, &ses.mut, boost::function<void(void)>(boost::bind(
&piece_manager::write_resume_data, &t->filesystem(), boost::ref(ret)))));
do { ses.cond.wait(l); } while(!done);
}
return ret; return ret;
} }
@ -640,64 +747,54 @@ namespace libtorrent
std::string torrent_handle::save_path() const std::string torrent_handle::save_path() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(save_path(), std::string()); TORRENT_SYNC_CALL_RET(std::string, "", save_path);
return r;
} }
void torrent_handle::connect_peer(tcp::endpoint const& adr, int source) const void torrent_handle::connect_peer(tcp::endpoint const& adr, int source) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASYNC_CALL2(add_peer, adr, source);
boost::shared_ptr<torrent> t = m_torrent.lock();
if (!t)
#ifdef BOOST_NO_EXCEPTIONS
return;
#else
throw_invalid_handle();
#endif
mutex::scoped_lock l(t->session().m_mutex);
peer_id id;
std::fill(id.begin(), id.end(), 0);
t->get_policy().add_peer(adr, id, source, 0);
} }
void torrent_handle::force_reannounce( void torrent_handle::force_reannounce(
boost::posix_time::time_duration duration) const boost::posix_time::time_duration duration) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(force_tracker_request(time_now() + seconds(duration.total_seconds()))); TORRENT_ASYNC_CALL1(force_tracker_request, time_now() + seconds(duration.total_seconds()));
} }
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
void torrent_handle::force_dht_announce() const void torrent_handle::force_dht_announce() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(dht_announce()); TORRENT_ASYNC_CALL(dht_announce);
} }
#endif #endif
void torrent_handle::force_reannounce() const void torrent_handle::force_reannounce() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(force_tracker_request()); TORRENT_ASYNC_CALL1(force_tracker_request, time_now());
} }
void torrent_handle::scrape_tracker() const void torrent_handle::scrape_tracker() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(scrape_tracker()); TORRENT_ASYNC_CALL(scrape_tracker);
} }
bool torrent_handle::super_seeding() const bool torrent_handle::super_seeding() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(super_seeding(), false); TORRENT_SYNC_CALL_RET(bool, false, super_seeding);
return r;
} }
void torrent_handle::super_seeding(bool on) const void torrent_handle::super_seeding(bool on) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(super_seeding(on)); TORRENT_ASYNC_CALL1(super_seeding, on);
} }
void torrent_handle::set_ratio(float ratio) const void torrent_handle::set_ratio(float ratio) const
@ -707,45 +804,46 @@ namespace libtorrent
TORRENT_ASSERT(ratio >= 0.f); TORRENT_ASSERT(ratio >= 0.f);
if (ratio < 1.f && ratio > 0.f) if (ratio < 1.f && ratio > 0.f)
ratio = 1.f; ratio = 1.f;
TORRENT_FORWARD(set_ratio(ratio)); TORRENT_ASYNC_CALL1(set_ratio, ratio);
} }
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
void torrent_handle::resolve_countries(bool r) void torrent_handle::resolve_countries(bool r)
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(resolve_countries(r)); TORRENT_ASYNC_CALL1(resolve_countries, r);
} }
bool torrent_handle::resolve_countries() const bool torrent_handle::resolve_countries() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD_RETURN(resolving_countries(), false); TORRENT_SYNC_CALL_RET(bool, false, resolving_countries);
return r;
} }
#endif #endif
void torrent_handle::get_full_peer_list(std::vector<peer_list_entry>& v) const void torrent_handle::get_full_peer_list(std::vector<peer_list_entry>& v) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(get_full_peer_list(v)); TORRENT_SYNC_CALL1(get_full_peer_list, boost::ref(v));
} }
void torrent_handle::get_peer_info(std::vector<peer_info>& v) const void torrent_handle::get_peer_info(std::vector<peer_info>& v) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(get_peer_info(v)); TORRENT_SYNC_CALL1(get_peer_info, boost::ref(v));
} }
void torrent_handle::get_download_queue(std::vector<partial_piece_info>& queue) const void torrent_handle::get_download_queue(std::vector<partial_piece_info>& queue) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(get_download_queue(queue)); TORRENT_SYNC_CALL1(get_download_queue, boost::ref(queue));
} }
void torrent_handle::set_piece_deadline(int index, int deadline, int flags) const void torrent_handle::set_piece_deadline(int index, int deadline, int flags) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_FORWARD(set_piece_deadline(index, deadline, flags)); TORRENT_ASYNC_CALL3(set_piece_deadline, index, deadline, flags);
} }
} }

View File

@ -172,13 +172,13 @@ namespace libtorrent
void tracker_manager::sent_bytes(int bytes) void tracker_manager::sent_bytes(int bytes)
{ {
// mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
m_ses.m_stat.sent_tracker_bytes(bytes); m_ses.m_stat.sent_tracker_bytes(bytes);
} }
void tracker_manager::received_bytes(int bytes) void tracker_manager::received_bytes(int bytes)
{ {
mutex::scoped_lock l(m_ses.m_mutex); TORRENT_ASSERT(m_ses.is_network_thread());
m_ses.m_stat.received_tracker_bytes(bytes); m_ses.m_stat.received_tracker_bytes(bytes);
} }

View File

@ -384,6 +384,7 @@ void run_elevator_test()
// this is not guaranteed, but very very likely // this is not guaranteed, but very very likely
TEST_CHECK(turns > 20); TEST_CHECK(turns > 20);
dio.abort();
dio.join(); dio.join();
} }
} }
@ -574,6 +575,7 @@ void run_storage_tests(boost::intrusive_ptr<torrent_info> info
ios.poll(ec); ios.poll(ec);
if (ec) std::cerr << "poll: " << ec.message() << std::endl; if (ec) std::cerr << "poll: " << ec.message() << std::endl;
io.abort();
io.join(); io.join();
remove_all(combine_path(test_path, "temp_storage2"), ec); remove_all(combine_path(test_path, "temp_storage2"), ec);
if (ec) std::cerr << "remove_all: " << ec.message() << std::endl; if (ec) std::cerr << "remove_all: " << ec.message() << std::endl;
@ -723,6 +725,7 @@ void test_check_files(std::string const& test_path
TEST_EQUAL(pieces[1], false); TEST_EQUAL(pieces[1], false);
TEST_EQUAL(pieces[2], false); TEST_EQUAL(pieces[2], false);
TEST_EQUAL(pieces[3], true); TEST_EQUAL(pieces[3], true);
io.abort();
io.join(); io.join();
} }

View File

@ -112,9 +112,9 @@ void test_rate()
} }
void print_alert(alert const& a) void print_alert(std::auto_ptr<alert>)
{ {
std::cout << "ses1 (alert dispatch function): " << a.message() << std::endl; std::cout << "ses1 (alert dispatch function): "/* << a.message() */ << std::endl;
} }
// simulate a full disk // simulate a full disk