factor out storage index free list from mmap_disk_io and posix_disk_io
This commit is contained in:
@ -257,6 +257,7 @@ set(libtorrent_aux_include_files
|
||||
session_udp_sockets.hpp
|
||||
set_socket_buffer.hpp
|
||||
socket_type.hpp
|
||||
storage_free_list.hpp
|
||||
storage_utils.hpp
|
||||
string_ptr.hpp
|
||||
strview_less.hpp
|
||||
|
1
Makefile
1
Makefile
@ -635,6 +635,7 @@ HEADERS = \
|
||||
aux_/set_socket_buffer.hpp \
|
||||
aux_/sha512.hpp \
|
||||
aux_/socket_type.hpp \
|
||||
aux_/storage_free_list.hpp \
|
||||
aux_/storage_utils.hpp \
|
||||
aux_/store_buffer.hpp \
|
||||
aux_/string_ptr.hpp \
|
||||
|
71
include/libtorrent/aux_/storage_free_list.hpp
Normal file
71
include/libtorrent/aux_/storage_free_list.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2021, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_STORAGE_FREE_LIST_HPP_INCLUDE
|
||||
#define TORRENT_STORAGE_FREE_LIST_HPP_INCLUDE
|
||||
|
||||
#include <vector>
|
||||
#include "libtorrent/storage_defs.hpp"
|
||||
|
||||
namespace libtorrent {
|
||||
namespace aux {
|
||||
|
||||
struct storage_free_list
|
||||
{
|
||||
// if we don't already have any free slots, use next
|
||||
storage_index_t new_index(storage_index_t const next)
|
||||
{
|
||||
// make sure we can remove this torrent without causing a memory
|
||||
// allocation, by triggering the allocation now instead
|
||||
m_free_slots.reserve(static_cast<std::uint32_t>(next) + 1);
|
||||
return m_free_slots.empty() ? next : pop();
|
||||
}
|
||||
|
||||
void add(storage_index_t const i) { m_free_slots.push_back(i); }
|
||||
|
||||
private:
|
||||
|
||||
storage_index_t pop()
|
||||
{
|
||||
TORRENT_ASSERT(!m_free_slots.empty());
|
||||
storage_index_t const ret = m_free_slots.back();
|
||||
m_free_slots.pop_back();
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<storage_index_t> m_free_slots;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -58,11 +58,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "libtorrent/aux_/alloca.hpp"
|
||||
#include "libtorrent/aux_/array.hpp"
|
||||
#include "libtorrent/add_torrent_params.hpp"
|
||||
#include "libtorrent/aux_/merkle.hpp"
|
||||
#include "libtorrent/aux_/numeric_cast.hpp"
|
||||
#include "libtorrent/settings_pack.hpp"
|
||||
#include "libtorrent/aux_/file_view_pool.hpp"
|
||||
#include "libtorrent/aux_/scope_end.hpp"
|
||||
#include "libtorrent/aux_/storage_free_list.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "libtorrent/aux_/windows.hpp"
|
||||
@ -139,14 +139,6 @@ namespace {
|
||||
if (!(j->flags & disk_interface::sequential_access)) ret |= aux::open_mode::random_access;
|
||||
return ret;
|
||||
}
|
||||
|
||||
storage_index_t pop(std::vector<storage_index_t>& q)
|
||||
{
|
||||
TORRENT_ASSERT(!q.empty());
|
||||
storage_index_t const ret = q.back();
|
||||
q.pop_back();
|
||||
return ret;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
using jobqueue_t = tailqueue<aux::disk_io_job>;
|
||||
@ -365,7 +357,7 @@ private:
|
||||
aux::vector<std::shared_ptr<mmap_storage>, storage_index_t> m_torrents;
|
||||
|
||||
// indices into m_torrents to empty slots
|
||||
std::vector<storage_index_t> m_free_slots;
|
||||
aux::storage_free_list m_free_slots;
|
||||
|
||||
std::atomic_flag m_jobs_aborted = ATOMIC_FLAG_INIT;
|
||||
|
||||
@ -406,19 +398,12 @@ TORRENT_EXPORT std::unique_ptr<disk_interface> mmap_disk_io_constructor(
|
||||
{
|
||||
TORRENT_ASSERT(params.files.is_valid());
|
||||
|
||||
storage_index_t const idx = m_free_slots.empty()
|
||||
? m_torrents.end_index()
|
||||
: pop(m_free_slots);
|
||||
storage_index_t const idx = m_free_slots.new_index(m_torrents.end_index());
|
||||
auto storage = std::make_shared<mmap_storage>(params, m_file_pool);
|
||||
storage->set_storage_index(idx);
|
||||
storage->set_owner(owner);
|
||||
if (idx == m_torrents.end_index())
|
||||
{
|
||||
// make sure there's always space in here to add another free slot.
|
||||
// stopping a torrent should never fail because it needs to allocate memory
|
||||
m_free_slots.reserve(m_torrents.size() + 1);
|
||||
m_torrents.emplace_back(std::move(storage));
|
||||
}
|
||||
else m_torrents[idx] = std::move(storage);
|
||||
return storage_holder(idx, *this);
|
||||
}
|
||||
@ -426,7 +411,7 @@ TORRENT_EXPORT std::unique_ptr<disk_interface> mmap_disk_io_constructor(
|
||||
void mmap_disk_io::remove_torrent(storage_index_t const idx)
|
||||
{
|
||||
m_torrents[idx].reset();
|
||||
m_free_slots.push_back(idx);
|
||||
m_free_slots.add(idx);
|
||||
}
|
||||
|
||||
#if TORRENT_USE_ASSERTS
|
||||
|
@ -46,7 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "libtorrent/file_storage.hpp"
|
||||
#include "libtorrent/hasher.hpp"
|
||||
#include "libtorrent/add_torrent_params.hpp"
|
||||
#include "libtorrent/aux_/merkle.hpp"
|
||||
#include "libtorrent/aux_/storage_free_list.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -54,14 +54,6 @@ namespace libtorrent {
|
||||
|
||||
namespace {
|
||||
|
||||
storage_index_t pop(std::vector<storage_index_t>& q)
|
||||
{
|
||||
TORRENT_ASSERT(!q.empty());
|
||||
storage_index_t const ret = q.back();
|
||||
q.pop_back();
|
||||
return ret;
|
||||
}
|
||||
|
||||
using aux::posix_storage;
|
||||
|
||||
} // anonymous namespace
|
||||
@ -89,10 +81,7 @@ namespace {
|
||||
{
|
||||
// make sure we can remove this torrent without causing a memory
|
||||
// allocation, by causing the allocation now instead
|
||||
m_free_slots.reserve(m_torrents.size() + 1);
|
||||
storage_index_t const idx = m_free_slots.empty()
|
||||
? m_torrents.end_index()
|
||||
: pop(m_free_slots);
|
||||
storage_index_t const idx = m_free_slots.new_index(m_torrents.end_index());
|
||||
auto storage = std::make_unique<posix_storage>(params);
|
||||
if (idx == m_torrents.end_index()) m_torrents.emplace_back(std::move(storage));
|
||||
else m_torrents[idx] = std::move(storage);
|
||||
@ -102,7 +91,7 @@ namespace {
|
||||
void remove_torrent(storage_index_t const idx) override
|
||||
{
|
||||
m_torrents[idx].reset();
|
||||
m_free_slots.push_back(idx);
|
||||
m_free_slots.add(idx);
|
||||
}
|
||||
|
||||
void abort(bool) override {}
|
||||
@ -398,7 +387,7 @@ namespace {
|
||||
aux::vector<std::unique_ptr<posix_storage>, storage_index_t> m_torrents;
|
||||
|
||||
// slots that are unused in the m_torrents vector
|
||||
std::vector<storage_index_t> m_free_slots;
|
||||
aux::storage_free_list m_free_slots;
|
||||
|
||||
settings_interface const& m_settings;
|
||||
|
||||
|
Reference in New Issue
Block a user