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>
|
||||
add_torrent_impl(add_torrent_params& p, error_code& ec);
|
||||
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_impl(std::shared_ptr<torrent> tptr, int options) override;
|
||||
|
@ -1058,6 +1058,26 @@ namespace libtorrent
|
|||
std::shared_ptr<upnp> m_upnp;
|
||||
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:
|
||||
// 1: NAT-PMP
|
||||
// 2: UPnP
|
||||
|
|
|
@ -86,8 +86,6 @@ namespace libtorrent
|
|||
virtual void async_set_file_priority(piece_manager* storage
|
||||
, std::vector<std::uint8_t> const& prio
|
||||
, 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
|
||||
, std::function<void(disk_io_job const*)> handler) = 0;
|
||||
|
||||
|
|
|
@ -95,7 +95,6 @@ namespace libtorrent
|
|||
, flush_storage
|
||||
, trim_cache
|
||||
, file_priority
|
||||
, load_torrent
|
||||
, clear_piece
|
||||
, tick_storage
|
||||
, resolve_links
|
||||
|
@ -150,7 +149,6 @@ namespace libtorrent
|
|||
char* string;
|
||||
add_torrent_params const* check_resume_data;
|
||||
std::vector<std::uint8_t>* priorities;
|
||||
torrent_info* torrent_file;
|
||||
int delete_options;
|
||||
} buffer;
|
||||
|
||||
|
|
|
@ -324,8 +324,6 @@ namespace libtorrent
|
|||
void async_set_file_priority(piece_manager* storage
|
||||
, std::vector<std::uint8_t> const& prio
|
||||
, 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
|
||||
, 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_trim_cache(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_tick(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",
|
||||
"trim_cache",
|
||||
"set_file_priority",
|
||||
"load_torrent",
|
||||
"clear_piece",
|
||||
"tick_storage",
|
||||
"resolve_links"
|
||||
|
|
|
@ -1032,7 +1032,6 @@ namespace libtorrent
|
|||
&disk_io_thread::do_flush_storage,
|
||||
&disk_io_thread::do_trim_cache,
|
||||
&disk_io_thread::do_file_priority,
|
||||
&disk_io_thread::do_load_torrent,
|
||||
&disk_io_thread::do_clear_piece,
|
||||
&disk_io_thread::do_tick,
|
||||
};
|
||||
|
@ -1963,16 +1962,6 @@ namespace libtorrent
|
|||
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
|
||||
, std::function<void(disk_io_job const*)> handler)
|
||||
{
|
||||
|
@ -2882,28 +2871,6 @@ namespace libtorrent
|
|||
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
|
||||
// piece are completed or cancelled and the buffers for it
|
||||
// have been evicted
|
||||
|
|
|
@ -4497,8 +4497,18 @@ namespace aux {
|
|||
|
||||
if (string_begins_no_case("file://", params->url.c_str()) && !params->ti)
|
||||
{
|
||||
m_disk_thread.async_load_torrent(params
|
||||
, std::bind(&session_impl::on_async_load_torrent, this, _1));
|
||||
if (!m_torrent_load_thread)
|
||||
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();
|
||||
return;
|
||||
}
|
||||
|
@ -4507,22 +4517,19 @@ namespace aux {
|
|||
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);
|
||||
if (j->error.ec)
|
||||
if (!ec)
|
||||
{
|
||||
add_torrent(*params, ec);
|
||||
params->url.clear();
|
||||
}
|
||||
|
||||
if (ec)
|
||||
{
|
||||
m_alerts.emplace_alert<add_torrent_alert>(torrent_handle()
|
||||
, *params, j->error.ec);
|
||||
}
|
||||
else
|
||||
{
|
||||
params->url.clear();
|
||||
params->ti = std::shared_ptr<torrent_info>(j->buffer.torrent_file);
|
||||
|
||||
error_code ec;
|
||||
add_torrent(*params, ec);
|
||||
, *params, ec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/torrent.hpp"
|
||||
#include "libtorrent/peer_info.hpp"
|
||||
#include "libtorrent/extensions.hpp"
|
||||
#include "libtorrent/file.hpp" // for combine_path, current_working_directory
|
||||
#include "settings.hpp"
|
||||
#include <tuple>
|
||||
#include <iostream>
|
||||
|
@ -411,3 +412,28 @@ TORRENT_TEST(rename_file)
|
|||
|
||||
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