forked from premiere/premiere-libtorrent
moved async-load-torrent feature out of disk-io-thread (#1282)
moved async-load-torrent feature out of disk-io-thread into a generic worker thread
This commit is contained in:
parent
1c2a8fb96e
commit
b61ebca14a
|
@ -449,7 +449,7 @@ namespace libtorrent
|
||||||
std::pair<std::shared_ptr<torrent>, bool>
|
std::pair<std::shared_ptr<torrent>, bool>
|
||||||
add_torrent_impl(add_torrent_params& p, error_code& ec);
|
add_torrent_impl(add_torrent_params& p, error_code& ec);
|
||||||
void async_add_torrent(add_torrent_params* params);
|
void async_add_torrent(add_torrent_params* params);
|
||||||
void on_async_load_torrent(disk_io_job const* j);
|
void on_async_load_torrent(add_torrent_params* params, error_code ec);
|
||||||
|
|
||||||
void remove_torrent(torrent_handle const& h, int options) override;
|
void remove_torrent(torrent_handle const& h, int options) override;
|
||||||
void remove_torrent_impl(std::shared_ptr<torrent> tptr, int options) override;
|
void remove_torrent_impl(std::shared_ptr<torrent> tptr, int options) override;
|
||||||
|
@ -1058,6 +1058,26 @@ namespace libtorrent
|
||||||
std::shared_ptr<upnp> m_upnp;
|
std::shared_ptr<upnp> m_upnp;
|
||||||
std::shared_ptr<lsd> m_lsd;
|
std::shared_ptr<lsd> m_lsd;
|
||||||
|
|
||||||
|
struct work_thread_t
|
||||||
|
{
|
||||||
|
work_thread_t()
|
||||||
|
: work(new boost::asio::io_service::work(ios))
|
||||||
|
, thread([&] { ios.run(); })
|
||||||
|
{}
|
||||||
|
~work_thread_t()
|
||||||
|
{
|
||||||
|
work.reset();
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
work_thread_t(work_thread_t const&) = delete;
|
||||||
|
work_thread_t& operator=(work_thread_t const&) = delete;
|
||||||
|
|
||||||
|
boost::asio::io_service ios;
|
||||||
|
std::unique_ptr<boost::asio::io_service::work> work;
|
||||||
|
std::thread thread;
|
||||||
|
};
|
||||||
|
std::unique_ptr<work_thread_t> m_torrent_load_thread;
|
||||||
|
|
||||||
// mask is a bitmask of which protocols to remap on:
|
// mask is a bitmask of which protocols to remap on:
|
||||||
// 1: NAT-PMP
|
// 1: NAT-PMP
|
||||||
// 2: UPnP
|
// 2: UPnP
|
||||||
|
|
|
@ -86,8 +86,6 @@ namespace libtorrent
|
||||||
virtual void async_set_file_priority(piece_manager* storage
|
virtual void async_set_file_priority(piece_manager* storage
|
||||||
, std::vector<std::uint8_t> const& prio
|
, std::vector<std::uint8_t> const& prio
|
||||||
, std::function<void(disk_io_job const*)> handler) = 0;
|
, std::function<void(disk_io_job const*)> handler) = 0;
|
||||||
virtual void async_load_torrent(add_torrent_params* params
|
|
||||||
, std::function<void(disk_io_job const*)> handler) = 0;
|
|
||||||
virtual void async_tick_torrent(piece_manager* storage
|
virtual void async_tick_torrent(piece_manager* storage
|
||||||
, std::function<void(disk_io_job const*)> handler) = 0;
|
, std::function<void(disk_io_job const*)> handler) = 0;
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,6 @@ namespace libtorrent
|
||||||
, flush_storage
|
, flush_storage
|
||||||
, trim_cache
|
, trim_cache
|
||||||
, file_priority
|
, file_priority
|
||||||
, load_torrent
|
|
||||||
, clear_piece
|
, clear_piece
|
||||||
, tick_storage
|
, tick_storage
|
||||||
, resolve_links
|
, resolve_links
|
||||||
|
@ -150,7 +149,6 @@ namespace libtorrent
|
||||||
char* string;
|
char* string;
|
||||||
add_torrent_params const* check_resume_data;
|
add_torrent_params const* check_resume_data;
|
||||||
std::vector<std::uint8_t>* priorities;
|
std::vector<std::uint8_t>* priorities;
|
||||||
torrent_info* torrent_file;
|
|
||||||
int delete_options;
|
int delete_options;
|
||||||
} buffer;
|
} buffer;
|
||||||
|
|
||||||
|
|
|
@ -324,8 +324,6 @@ namespace libtorrent
|
||||||
void async_set_file_priority(piece_manager* storage
|
void async_set_file_priority(piece_manager* storage
|
||||||
, std::vector<std::uint8_t> const& prio
|
, std::vector<std::uint8_t> const& prio
|
||||||
, std::function<void(disk_io_job const*)> handler) override;
|
, std::function<void(disk_io_job const*)> handler) override;
|
||||||
void async_load_torrent(add_torrent_params* params
|
|
||||||
, std::function<void(disk_io_job const*)> handler) override;
|
|
||||||
void async_tick_torrent(piece_manager* storage
|
void async_tick_torrent(piece_manager* storage
|
||||||
, std::function<void(disk_io_job const*)> handler) override;
|
, std::function<void(disk_io_job const*)> handler) override;
|
||||||
|
|
||||||
|
@ -413,7 +411,6 @@ namespace libtorrent
|
||||||
int do_flush_storage(disk_io_job* j, jobqueue_t& completed_jobs);
|
int do_flush_storage(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||||
int do_trim_cache(disk_io_job* j, jobqueue_t& completed_jobs);
|
int do_trim_cache(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||||
int do_file_priority(disk_io_job* j, jobqueue_t& completed_jobs);
|
int do_file_priority(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||||
int do_load_torrent(disk_io_job* j, jobqueue_t& completed_jobs);
|
|
||||||
int do_clear_piece(disk_io_job* j, jobqueue_t& completed_jobs);
|
int do_clear_piece(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||||
int do_tick(disk_io_job* j, jobqueue_t& completed_jobs);
|
int do_tick(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||||
int do_resolve_links(disk_io_job* j, jobqueue_t& completed_jobs);
|
int do_resolve_links(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||||
|
|
|
@ -204,7 +204,6 @@ const char* const job_action_name[] =
|
||||||
"flush_storage",
|
"flush_storage",
|
||||||
"trim_cache",
|
"trim_cache",
|
||||||
"set_file_priority",
|
"set_file_priority",
|
||||||
"load_torrent",
|
|
||||||
"clear_piece",
|
"clear_piece",
|
||||||
"tick_storage",
|
"tick_storage",
|
||||||
"resolve_links"
|
"resolve_links"
|
||||||
|
|
|
@ -1032,7 +1032,6 @@ namespace libtorrent
|
||||||
&disk_io_thread::do_flush_storage,
|
&disk_io_thread::do_flush_storage,
|
||||||
&disk_io_thread::do_trim_cache,
|
&disk_io_thread::do_trim_cache,
|
||||||
&disk_io_thread::do_file_priority,
|
&disk_io_thread::do_file_priority,
|
||||||
&disk_io_thread::do_load_torrent,
|
|
||||||
&disk_io_thread::do_clear_piece,
|
&disk_io_thread::do_clear_piece,
|
||||||
&disk_io_thread::do_tick,
|
&disk_io_thread::do_tick,
|
||||||
};
|
};
|
||||||
|
@ -1963,16 +1962,6 @@ namespace libtorrent
|
||||||
add_fence_job(storage, j);
|
add_fence_job(storage, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disk_io_thread::async_load_torrent(add_torrent_params* params
|
|
||||||
, std::function<void(disk_io_job const*)> handler)
|
|
||||||
{
|
|
||||||
disk_io_job* j = allocate_job(disk_io_job::load_torrent);
|
|
||||||
j->requester = reinterpret_cast<void*>(params);
|
|
||||||
j->callback = std::move(handler);
|
|
||||||
|
|
||||||
add_job(j);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disk_io_thread::async_tick_torrent(piece_manager* storage
|
void disk_io_thread::async_tick_torrent(piece_manager* storage
|
||||||
, std::function<void(disk_io_job const*)> handler)
|
, std::function<void(disk_io_job const*)> handler)
|
||||||
{
|
{
|
||||||
|
@ -2882,28 +2871,6 @@ namespace libtorrent
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int disk_io_thread::do_load_torrent(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
|
||||||
{
|
|
||||||
add_torrent_params* params = reinterpret_cast<add_torrent_params*>(j->requester);
|
|
||||||
|
|
||||||
std::string filename = resolve_file_url(params->url);
|
|
||||||
std::unique_ptr<torrent_info> t{new torrent_info(filename, j->error.ec)};
|
|
||||||
if (j->error.ec)
|
|
||||||
{
|
|
||||||
j->buffer.torrent_file = nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// do this to trigger parsing of the info-dict here. It's better
|
|
||||||
// than to have it be done in the network thread. It has enough to
|
|
||||||
// do as it is.
|
|
||||||
std::string cert = t->ssl_cert();
|
|
||||||
j->buffer.torrent_file = t.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this job won't return until all outstanding jobs on this
|
// this job won't return until all outstanding jobs on this
|
||||||
// piece are completed or cancelled and the buffers for it
|
// piece are completed or cancelled and the buffers for it
|
||||||
// have been evicted
|
// have been evicted
|
||||||
|
|
|
@ -4497,8 +4497,18 @@ namespace aux {
|
||||||
|
|
||||||
if (string_begins_no_case("file://", params->url.c_str()) && !params->ti)
|
if (string_begins_no_case("file://", params->url.c_str()) && !params->ti)
|
||||||
{
|
{
|
||||||
m_disk_thread.async_load_torrent(params
|
if (!m_torrent_load_thread)
|
||||||
, std::bind(&session_impl::on_async_load_torrent, this, _1));
|
m_torrent_load_thread.reset(new work_thread_t());
|
||||||
|
|
||||||
|
m_torrent_load_thread->ios.post([params, this]
|
||||||
|
{
|
||||||
|
std::unique_ptr<add_torrent_params> holder2(params);
|
||||||
|
error_code ec;
|
||||||
|
params->ti = std::make_shared<torrent_info>(resolve_file_url(params->url), ec);
|
||||||
|
this->m_io_service.post(std::bind(&session_impl::on_async_load_torrent
|
||||||
|
, this, params, ec));
|
||||||
|
holder2.release();
|
||||||
|
});
|
||||||
holder.release();
|
holder.release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4507,22 +4517,19 @@ namespace aux {
|
||||||
add_torrent(*params, ec);
|
add_torrent(*params, ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::on_async_load_torrent(disk_io_job const* j)
|
void session_impl::on_async_load_torrent(add_torrent_params* params, error_code ec)
|
||||||
{
|
{
|
||||||
add_torrent_params* params = reinterpret_cast<add_torrent_params*>(j->requester);
|
|
||||||
std::unique_ptr<add_torrent_params> holder(params);
|
std::unique_ptr<add_torrent_params> holder(params);
|
||||||
if (j->error.ec)
|
if (!ec)
|
||||||
|
{
|
||||||
|
add_torrent(*params, ec);
|
||||||
|
params->url.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ec)
|
||||||
{
|
{
|
||||||
m_alerts.emplace_alert<add_torrent_alert>(torrent_handle()
|
m_alerts.emplace_alert<add_torrent_alert>(torrent_handle()
|
||||||
, *params, j->error.ec);
|
, *params, ec);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
params->url.clear();
|
|
||||||
params->ti = std::shared_ptr<torrent_info>(j->buffer.torrent_file);
|
|
||||||
|
|
||||||
error_code ec;
|
|
||||||
add_torrent(*params, ec);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/torrent.hpp"
|
#include "libtorrent/torrent.hpp"
|
||||||
#include "libtorrent/peer_info.hpp"
|
#include "libtorrent/peer_info.hpp"
|
||||||
#include "libtorrent/extensions.hpp"
|
#include "libtorrent/extensions.hpp"
|
||||||
|
#include "libtorrent/file.hpp" // for combine_path, current_working_directory
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -411,3 +412,28 @@ TORRENT_TEST(rename_file)
|
||||||
|
|
||||||
TEST_EQUAL(info->files().file_path(0), "tmp1");
|
TEST_EQUAL(info->files().file_path(0), "tmp1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(async_load)
|
||||||
|
{
|
||||||
|
settings_pack pack = settings();
|
||||||
|
lt::session ses(pack);
|
||||||
|
|
||||||
|
add_torrent_params p;
|
||||||
|
p.flags &= ~add_torrent_params::flag_paused;
|
||||||
|
p.flags &= ~add_torrent_params::flag_auto_managed;
|
||||||
|
std::string dir = parent_path(current_working_directory());
|
||||||
|
|
||||||
|
p.url = "file://" + combine_path(combine_path(dir, "test_torrents"), "base.torrent");
|
||||||
|
p.save_path = ".";
|
||||||
|
ses.async_add_torrent(p);
|
||||||
|
|
||||||
|
alert const* a = wait_for_alert(ses, add_torrent_alert::alert_type);
|
||||||
|
TEST_CHECK(a);
|
||||||
|
if (a == nullptr) return;
|
||||||
|
auto const* ta = alert_cast<add_torrent_alert const>(a);
|
||||||
|
TEST_CHECK(ta);
|
||||||
|
if (ta == nullptr) return;
|
||||||
|
TEST_CHECK(!ta->error);
|
||||||
|
TEST_CHECK(ta->params.ti->name() == "temp");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue