make iovec_t an alias for span<char>, in preparation for removing it altogether in favour of span
This commit is contained in:
parent
a693565df0
commit
749d0da875
|
@ -63,6 +63,7 @@ using namespace lt::detail; // for write_* and read_*
|
|||
|
||||
using namespace std::placeholders;
|
||||
|
||||
// TODO: this should take a span
|
||||
void generate_block(std::uint32_t* buffer, piece_index_t const piece, int start, int length)
|
||||
{
|
||||
std::uint32_t fill = (static_cast<int>(piece) << 8) | ((start / 0x4000) & 0xff);
|
||||
|
@ -867,7 +868,8 @@ void generate_data(char const* path, torrent_info const& ti)
|
|||
{
|
||||
generate_block(piece, i, j, 0x4000);
|
||||
int const left_in_piece = ti.piece_size(i) - j;
|
||||
iovec_t const b = { piece, size_t(std::min(left_in_piece, 0x4000))};
|
||||
iovec_t const b = { reinterpret_cast<char*>(piece)
|
||||
, size_t(std::min(left_in_piece, 0x4000))};
|
||||
storage_error error;
|
||||
st->writev(b, i, j, 0, error);
|
||||
if (error)
|
||||
|
|
|
@ -40,10 +40,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/units.hpp"
|
||||
#include "libtorrent/storage_defs.hpp" // for status_t
|
||||
|
||||
#ifndef TORRENT_WINDOWS
|
||||
#include <sys/uio.h> // for iovec
|
||||
#endif
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
class file_storage;
|
||||
|
@ -52,19 +48,14 @@ namespace libtorrent {
|
|||
struct stat_cache;
|
||||
struct add_torrent_params;
|
||||
|
||||
#ifdef TORRENT_WINDOWS
|
||||
struct iovec_t
|
||||
{
|
||||
void* iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
#else
|
||||
using iovec_t = ::iovec;
|
||||
#endif
|
||||
// TODO: 3 remove this typedef, and use span<char const> for disk write
|
||||
// operations
|
||||
using iovec_t = span<char>;
|
||||
|
||||
namespace aux {
|
||||
|
||||
TORRENT_EXTRA_EXPORT int copy_bufs(span<iovec_t const> bufs, int bytes, span<iovec_t> target);
|
||||
TORRENT_EXTRA_EXPORT int copy_bufs(span<iovec_t const> bufs
|
||||
, int bytes, span<iovec_t> target);
|
||||
TORRENT_EXTRA_EXPORT span<iovec_t> advance_bufs(span<iovec_t> bufs, int bytes);
|
||||
|
||||
// this identifies a read or write operation so that readwritev() knows
|
||||
|
|
|
@ -214,9 +214,6 @@ namespace libtorrent {
|
|||
static bool has_manage_volume_privs;
|
||||
#endif
|
||||
};
|
||||
|
||||
TORRENT_EXTRA_EXPORT int bufs_size(span<iovec_t const> bufs);
|
||||
|
||||
}
|
||||
|
||||
#endif // TORRENT_FILE_HPP_INCLUDED
|
||||
|
|
|
@ -1272,14 +1272,14 @@ void block_cache::insert_blocks(cached_piece_entry* pe, int block, span<iovec_t
|
|||
for (auto const& buf : iov)
|
||||
{
|
||||
// each iovec buffer has to be the size of a block (or the size of the last block)
|
||||
TORRENT_PIECE_ASSERT(int(buf.iov_len) == std::min(block_size()
|
||||
TORRENT_PIECE_ASSERT(int(buf.size()) == std::min(block_size()
|
||||
, pe->storage->files().piece_size(pe->piece) - block * block_size()), pe);
|
||||
|
||||
// no nullptrs allowed
|
||||
TORRENT_ASSERT(buf.iov_base != nullptr);
|
||||
TORRENT_ASSERT(buf.data() != nullptr);
|
||||
|
||||
#ifdef TORRENT_DEBUG_BUFFERS
|
||||
TORRENT_PIECE_ASSERT(is_disk_buffer(static_cast<char*>(buf.iov_base)), pe);
|
||||
TORRENT_PIECE_ASSERT(is_disk_buffer(buf.data()), pe);
|
||||
#endif
|
||||
|
||||
if (pe->blocks[block].buf && (flags & blocks_inc_refcount))
|
||||
|
@ -1290,13 +1290,13 @@ void block_cache::insert_blocks(cached_piece_entry* pe, int block, span<iovec_t
|
|||
// either free the block or insert it. Never replace a block
|
||||
if (pe->blocks[block].buf)
|
||||
{
|
||||
free_buffer(static_cast<char*>(buf.iov_base));
|
||||
free_buffer(buf.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
pe->blocks[block].buf = static_cast<char*>(buf.iov_base);
|
||||
pe->blocks[block].buf = buf.data();
|
||||
|
||||
TORRENT_PIECE_ASSERT(buf.iov_base != nullptr, pe);
|
||||
TORRENT_PIECE_ASSERT(buf.data() != nullptr, pe);
|
||||
TORRENT_PIECE_ASSERT(pe->blocks[block].dirty == false, pe);
|
||||
++pe->num_blocks;
|
||||
++m_read_cache_size;
|
||||
|
|
|
@ -195,17 +195,16 @@ namespace libtorrent {
|
|||
std::unique_lock<std::mutex> l(m_pool_mutex);
|
||||
for (auto& i : iov)
|
||||
{
|
||||
i.iov_base = allocate_buffer_impl(l, "pending read");
|
||||
i.iov_len = std::size_t(block_size());
|
||||
if (i.iov_base == nullptr)
|
||||
i = { allocate_buffer_impl(l, "pending read"), std::size_t(block_size())};
|
||||
if (i.data() == nullptr)
|
||||
{
|
||||
// uh oh. We failed to allocate the buffer!
|
||||
// we need to roll back and free all the buffers
|
||||
// we've already allocated
|
||||
for (auto j : iov)
|
||||
{
|
||||
if (j.iov_base == nullptr) break;
|
||||
char* buf = static_cast<char*>(j.iov_base);
|
||||
if (j.data() == nullptr) break;
|
||||
char* buf = j.data();
|
||||
TORRENT_ASSERT(is_disk_buffer(buf, l));
|
||||
free_buffer_impl(buf, l);
|
||||
remove_buffer_in_use(buf);
|
||||
|
@ -222,7 +221,7 @@ namespace libtorrent {
|
|||
std::unique_lock<std::mutex> l(m_pool_mutex);
|
||||
for (auto i : iov)
|
||||
{
|
||||
char* buf = static_cast<char*>(i.iov_base);
|
||||
char* buf = i.data();
|
||||
TORRENT_ASSERT(is_disk_buffer(buf, l));
|
||||
free_buffer_impl(buf, l);
|
||||
remove_buffer_in_use(buf);
|
||||
|
|
|
@ -631,8 +631,7 @@ namespace libtorrent {
|
|||
TORRENT_UNUSED(locked);
|
||||
|
||||
flushing[num_flushing++] = i + block_base_index;
|
||||
iov[iov_len].iov_base = pe->blocks[i].buf;
|
||||
iov[iov_len].iov_len = aux::numeric_cast<std::size_t>(std::min(block_size, size_left));
|
||||
iov[iov_len] = { pe->blocks[i].buf, aux::numeric_cast<std::size_t>(std::min(block_size, size_left)) };
|
||||
++iov_len;
|
||||
pe->blocks[i].pending = true;
|
||||
|
||||
|
@ -1302,9 +1301,10 @@ namespace libtorrent {
|
|||
|
||||
// if this is the last piece, adjust the size of the
|
||||
// last buffer to match up
|
||||
iov[iov_len - 1].iov_len = aux::numeric_cast<std::size_t>(std::min(int(piece_size - adjusted_offset)
|
||||
- (iov_len - 1) * block_size, block_size));
|
||||
TORRENT_ASSERT(iov[iov_len - 1].iov_len > 0);
|
||||
iov[iov_len - 1] = iov[iov_len - 1].first(aux::numeric_cast<std::size_t>(
|
||||
std::min(int(piece_size - adjusted_offset)
|
||||
- (iov_len - 1) * block_size, block_size)));
|
||||
TORRENT_ASSERT(iov[iov_len - 1].size() > 0);
|
||||
|
||||
// at this point, all the buffers are allocated and iov is initialized
|
||||
// and the blocks have their refcounters incremented, so no other thread
|
||||
|
@ -2162,8 +2162,7 @@ namespace libtorrent {
|
|||
std::uint32_t const file_flags = file_flags_for_job(j
|
||||
, m_settings.get_bool(settings_pack::coalesce_reads));
|
||||
|
||||
iovec_t iov;
|
||||
iov.iov_base = m_disk_cache.allocate_buffer("hashing");
|
||||
iovec_t iov = { m_disk_cache.allocate_buffer("hashing"), 0x4000 };
|
||||
hasher h;
|
||||
int ret = 0;
|
||||
int offset = 0;
|
||||
|
@ -2174,10 +2173,11 @@ namespace libtorrent {
|
|||
|
||||
time_point const start_time = clock_type::now();
|
||||
|
||||
iov.iov_len = aux::numeric_cast<std::size_t>(std::min(block_size, piece_size - offset));
|
||||
iov = iov.first(aux::numeric_cast<std::size_t>(std::min(block_size, piece_size - offset)));
|
||||
ret = j->storage->readv(iov, j->piece
|
||||
, offset, file_flags, j->error);
|
||||
if (ret < 0) break;
|
||||
iov = iov.first(std::size_t(ret));
|
||||
|
||||
if (!j->error.ec)
|
||||
{
|
||||
|
@ -2191,10 +2191,10 @@ namespace libtorrent {
|
|||
}
|
||||
|
||||
offset += block_size;
|
||||
h.update(static_cast<char const*>(iov.iov_base), int(iov.iov_len));
|
||||
h.update(iov);
|
||||
}
|
||||
|
||||
m_disk_cache.free_buffer(static_cast<char*>(iov.iov_base));
|
||||
m_disk_cache.free_buffer(iov.data());
|
||||
|
||||
sha1_hash piece_hash = h.final();
|
||||
std::memcpy(j->d.piece_hash, piece_hash.data(), 20);
|
||||
|
@ -2326,23 +2326,22 @@ namespace libtorrent {
|
|||
int next_locked_block = 0;
|
||||
for (int i = offset / block_size; i < blocks_in_piece; ++i)
|
||||
{
|
||||
iovec_t iov;
|
||||
iov.iov_len = aux::numeric_cast<std::size_t>(std::min(block_size, piece_size - offset));
|
||||
|
||||
if (next_locked_block < num_locked_blocks
|
||||
&& locked_blocks[next_locked_block] == i)
|
||||
{
|
||||
int const len = std::min(block_size, piece_size - offset);
|
||||
++next_locked_block;
|
||||
TORRENT_PIECE_ASSERT(pe->blocks[i].buf, pe);
|
||||
TORRENT_PIECE_ASSERT(offset == i * block_size, pe);
|
||||
offset += int(iov.iov_len);
|
||||
ph->h.update({pe->blocks[i].buf, iov.iov_len});
|
||||
offset += len;
|
||||
ph->h.update({pe->blocks[i].buf, aux::numeric_cast<std::size_t>(len)});
|
||||
}
|
||||
else
|
||||
{
|
||||
iov.iov_base = m_disk_cache.allocate_buffer("hashing");
|
||||
iovec_t const iov = { m_disk_cache.allocate_buffer("hashing")
|
||||
, aux::numeric_cast<std::size_t>(std::min(block_size, piece_size - offset))};
|
||||
|
||||
if (iov.iov_base == nullptr)
|
||||
if (iov.data() == nullptr)
|
||||
{
|
||||
l.lock();
|
||||
|
||||
|
@ -2374,19 +2373,19 @@ namespace libtorrent {
|
|||
{
|
||||
ret = status_t::fatal_disk_error;
|
||||
TORRENT_ASSERT(j->error.ec && j->error.operation != 0);
|
||||
m_disk_cache.free_buffer(static_cast<char*>(iov.iov_base));
|
||||
m_disk_cache.free_buffer(iov.data());
|
||||
break;
|
||||
}
|
||||
|
||||
// treat a short read as an error. The hash will be invalid, the
|
||||
// block cannot be cached and the main thread should skip the rest
|
||||
// of this file
|
||||
if (read_ret != int(iov.iov_len))
|
||||
if (read_ret != int(iov.size()))
|
||||
{
|
||||
ret = status_t::fatal_disk_error;
|
||||
j->error.ec = boost::asio::error::eof;
|
||||
j->error.operation = storage_error::read;
|
||||
m_disk_cache.free_buffer(static_cast<char*>(iov.iov_base));
|
||||
m_disk_cache.free_buffer(iov.data());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2403,8 +2402,8 @@ namespace libtorrent {
|
|||
}
|
||||
|
||||
TORRENT_PIECE_ASSERT(offset == i * block_size, pe);
|
||||
offset += int(iov.iov_len);
|
||||
ph->h.update({static_cast<char const*>(iov.iov_base), iov.iov_len});
|
||||
offset += int(iov.size());
|
||||
ph->h.update(iov);
|
||||
|
||||
l.lock();
|
||||
m_disk_cache.insert_blocks(pe, i, iov, j);
|
||||
|
|
84
src/file.cpp
84
src/file.cpp
|
@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
*/
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
@ -49,6 +50,18 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define _FILE_OFFSET_BITS 64
|
||||
#define _LARGE_FILES 1
|
||||
|
||||
#ifndef TORRENT_WINDOWS
|
||||
#include <sys/uio.h> // for iovec
|
||||
#else
|
||||
namespace {
|
||||
struct iovec
|
||||
{
|
||||
void* iov_base;
|
||||
std::size_t iov_len;
|
||||
};
|
||||
} // anonymous namespace
|
||||
#endif
|
||||
|
||||
// on mingw this is necessary to enable 64-bit time_t, specifically used for
|
||||
// the stat struct. Without this, modification times returned by stat may be
|
||||
// incorrect and consistently fail resume data
|
||||
|
@ -66,7 +79,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/aux_/alloca.hpp"
|
||||
#include "libtorrent/file.hpp"
|
||||
#include "libtorrent/aux_/path.hpp"
|
||||
|
@ -165,7 +177,7 @@ namespace {
|
|||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
int preadv(HANDLE fd, libtorrent::iovec_t const* bufs, int num_bufs, std::int64_t file_offset)
|
||||
int preadv(HANDLE fd, ::iovec const* bufs, int num_bufs, std::int64_t file_offset)
|
||||
{
|
||||
TORRENT_ALLOCA(ol, OVERLAPPED, num_bufs);
|
||||
std::memset(ol.data(), 0, sizeof(OVERLAPPED) * num_bufs);
|
||||
|
@ -235,7 +247,7 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int pwritev(HANDLE fd, libtorrent::iovec_t const* bufs, int num_bufs, std::int64_t file_offset)
|
||||
int pwritev(HANDLE fd, ::iovec const* bufs, int num_bufs, std::int64_t file_offset)
|
||||
{
|
||||
TORRENT_ALLOCA(ol, OVERLAPPED, num_bufs);
|
||||
std::memset(ol.data(), 0, sizeof(OVERLAPPED) * num_bufs);
|
||||
|
@ -330,12 +342,6 @@ static_assert((libtorrent::file::sparse & libtorrent::file::attribute_mask) == 0
|
|||
|
||||
namespace libtorrent {
|
||||
|
||||
template <typename T>
|
||||
std::unique_ptr<T, decltype(&std::free)> make_free_holder(T* ptr)
|
||||
{
|
||||
return std::unique_ptr<T, decltype(&std::free)>(ptr, &std::free);
|
||||
}
|
||||
|
||||
directory::directory(std::string const& path, error_code& ec)
|
||||
: m_done(false)
|
||||
{
|
||||
|
@ -796,8 +802,8 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
std::size_t offset = 0;
|
||||
for (auto buf : bufs)
|
||||
{
|
||||
std::memcpy(dst + offset, buf.iov_base, buf.iov_len);
|
||||
offset += buf.iov_len;
|
||||
std::memcpy(dst + offset, buf.data(), buf.size());
|
||||
offset += buf.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -806,8 +812,8 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
std::size_t offset = 0;
|
||||
for (auto buf : bufs)
|
||||
{
|
||||
std::memcpy(buf.iov_base, src + offset, buf.iov_len);
|
||||
offset += buf.iov_len;
|
||||
std::memcpy(buf.data(), src + offset, buf.size());
|
||||
offset += buf.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -815,10 +821,9 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
, iovec_t& tmp)
|
||||
{
|
||||
std::size_t const buf_size = aux::numeric_cast<std::size_t>(bufs_size(bufs));
|
||||
char* buf = static_cast<char*>(std::malloc(buf_size));
|
||||
char* buf = new char[buf_size];
|
||||
if (!buf) return false;
|
||||
tmp.iov_base = buf;
|
||||
tmp.iov_len = buf_size;
|
||||
tmp = { buf, buf_size };
|
||||
bufs = span<iovec_t const>(tmp);
|
||||
return true;
|
||||
}
|
||||
|
@ -827,21 +832,30 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
, char* const buf, bool const copy)
|
||||
{
|
||||
if (copy) scatter_copy(bufs, buf);
|
||||
std::free(buf);
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
bool coalesce_write_buffers(span<iovec_t const>& bufs
|
||||
, iovec_t& tmp)
|
||||
{
|
||||
std::size_t const buf_size = aux::numeric_cast<std::size_t>(bufs_size(bufs));
|
||||
char* buf = static_cast<char*>(std::malloc(buf_size));
|
||||
char* buf = new char[buf_size];
|
||||
if (!buf) return false;
|
||||
gather_copy(bufs, buf);
|
||||
tmp.iov_base = buf;
|
||||
tmp.iov_len = buf_size;
|
||||
tmp = { buf, buf_size };
|
||||
bufs = span<iovec_t const>(tmp);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
|
||||
namespace {
|
||||
int bufs_size(span<::iovec> bufs)
|
||||
{
|
||||
std::size_t size = 0;
|
||||
for (auto buf : bufs) size += buf.iov_len;
|
||||
return int(size);
|
||||
}
|
||||
}
|
||||
#endif // TORRENT_USE_PREADV
|
||||
|
||||
template <class Fun>
|
||||
|
@ -850,13 +864,22 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
{
|
||||
#if TORRENT_USE_PREADV
|
||||
|
||||
TORRENT_ALLOCA(vec, ::iovec, bufs.size());
|
||||
auto it = vec.begin();
|
||||
for (auto const& b : bufs)
|
||||
{
|
||||
it->iov_base = b.data();
|
||||
it->iov_len = b.size();
|
||||
++it;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
while (!bufs.empty())
|
||||
while (!vec.empty())
|
||||
{
|
||||
#ifdef IOV_MAX
|
||||
auto const nbufs = bufs.first((std::min)(int(bufs.size()), IOV_MAX));
|
||||
auto const nbufs = vec.first(std::min(int(vec.size()), IOV_MAX));
|
||||
#else
|
||||
auto const nbufs = bufs;
|
||||
auto const nbufs = vec;
|
||||
#endif
|
||||
|
||||
int tmp_ret = 0;
|
||||
|
@ -880,7 +903,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
const int expected_len = bufs_size(nbufs);
|
||||
if (tmp_ret < expected_len) break;
|
||||
|
||||
bufs = bufs.subspan(nbufs.size());
|
||||
vec = vec.subspan(nbufs.size());
|
||||
}
|
||||
return ret;
|
||||
|
||||
|
@ -889,7 +912,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
std::int64_t ret = 0;
|
||||
for (auto i : bufs)
|
||||
{
|
||||
std::int64_t const tmp_ret = f(fd, i.iov_base, i.iov_len, file_offset);
|
||||
std::int64_t const tmp_ret = f(fd, i.data(), i.size(), file_offset);
|
||||
if (tmp_ret < 0)
|
||||
{
|
||||
#ifdef TORRENT_WINDOWS
|
||||
|
@ -901,7 +924,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
}
|
||||
file_offset += tmp_ret;
|
||||
ret += tmp_ret;
|
||||
if (tmp_ret < int(i.iov_len)) break;
|
||||
if (tmp_ret < int(i.size())) break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -926,7 +949,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
|
||||
for (auto i : bufs)
|
||||
{
|
||||
int tmp_ret = f(fd, i.iov_base, i.iov_len);
|
||||
int tmp_ret = f(fd, i.data(), i.size());
|
||||
if (tmp_ret < 0)
|
||||
{
|
||||
#ifdef TORRENT_WINDOWS
|
||||
|
@ -938,7 +961,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
}
|
||||
file_offset += tmp_ret;
|
||||
ret += tmp_ret;
|
||||
if (tmp_ret < int(i.iov_len)) break;
|
||||
if (tmp_ret < int(i.size())) break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -968,7 +991,6 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
|
||||
#if TORRENT_USE_PREADV
|
||||
TORRENT_UNUSED(flags);
|
||||
|
||||
std::int64_t ret = iov(&::preadv, native_handle(), file_offset, bufs, ec);
|
||||
#else
|
||||
|
||||
|
@ -995,7 +1017,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
|
||||
if ((flags & file::coalesce_buffers))
|
||||
coalesce_read_buffers_end(bufs
|
||||
, static_cast<char*>(tmp.iov_base), !ec);
|
||||
, tmp.data(), !ec);
|
||||
|
||||
#endif
|
||||
return ret;
|
||||
|
@ -1049,7 +1071,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
|
|||
#endif
|
||||
|
||||
if (flags & file::coalesce_buffers)
|
||||
std::free(tmp.iov_base);
|
||||
delete[] tmp.data();
|
||||
|
||||
#endif
|
||||
#if TORRENT_USE_FDATASYNC \
|
||||
|
|
|
@ -96,8 +96,8 @@ namespace libtorrent {
|
|||
if (ec) return;
|
||||
|
||||
// parse header
|
||||
std::unique_ptr<std::uint32_t[]> header(new std::uint32_t[m_header_size]);
|
||||
iovec_t b = {header.get(), std::size_t(m_header_size)};
|
||||
std::vector<char> header(static_cast<std::size_t>(m_header_size));
|
||||
iovec_t b = header;
|
||||
int n = int(m_file.readv(0, b, ec));
|
||||
if (ec) return;
|
||||
|
||||
|
@ -105,7 +105,7 @@ namespace libtorrent {
|
|||
if (n < m_header_size) return;
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
char* ptr = reinterpret_cast<char*>(header.get());
|
||||
char* ptr = header.data();
|
||||
// we have a header. Parse it
|
||||
int const num_pieces_ = int(read_uint32(ptr));
|
||||
int const piece_size_ = int(read_uint32(ptr));
|
||||
|
@ -313,9 +313,10 @@ namespace libtorrent {
|
|||
l.unlock();
|
||||
|
||||
iovec_t v = {buf.get(), std::size_t(block_to_copy)};
|
||||
v.iov_len = std::size_t(m_file.readv(slot_offset + piece_offset, v, ec));
|
||||
auto bytes_read = std::size_t(m_file.readv(slot_offset + piece_offset, v, ec));
|
||||
v = v.first(bytes_read);
|
||||
TORRENT_ASSERT(!ec);
|
||||
if (ec || v.iov_len == 0) return;
|
||||
if (ec || v.size() == 0) return;
|
||||
|
||||
f(file_offset, {buf.get(), std::size_t(block_to_copy)});
|
||||
|
||||
|
@ -377,12 +378,11 @@ namespace libtorrent {
|
|||
open_file(file::read_write, ec);
|
||||
if (ec) return;
|
||||
|
||||
std::unique_ptr<std::uint32_t[]> header(new std::uint32_t[m_header_size]);
|
||||
std::vector<char> header(static_cast<std::size_t>(m_header_size));
|
||||
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
char* ptr = reinterpret_cast<char*>(header.get());
|
||||
|
||||
char* ptr = header.data();
|
||||
write_uint32(m_max_pieces, ptr);
|
||||
write_uint32(m_piece_size, ptr);
|
||||
|
||||
|
@ -393,9 +393,8 @@ namespace libtorrent {
|
|||
? slot_index_t(-1) : i->second);
|
||||
write_int32(static_cast<int>(slot), ptr);
|
||||
}
|
||||
std::memset(ptr, 0, std::size_t(m_header_size - (ptr - reinterpret_cast<char*>(header.get()))));
|
||||
|
||||
iovec_t b = {header.get(), std::size_t(m_header_size)};
|
||||
std::memset(ptr, 0, std::size_t(m_header_size - (ptr - header.data())));
|
||||
iovec_t b = header;
|
||||
m_file.writev(0, b, ec);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,8 +130,7 @@ namespace libtorrent {
|
|||
int bufs_size(span<iovec_t const> bufs)
|
||||
{
|
||||
std::size_t size = 0;
|
||||
for (auto buf : bufs)
|
||||
size += buf.iov_len;
|
||||
for (auto buf : bufs) size += buf.size();
|
||||
return int(size);
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace libtorrent {
|
|||
void clear_bufs(span<iovec_t const> bufs)
|
||||
{
|
||||
for (auto buf : bufs)
|
||||
std::memset(buf.iov_base, 0, buf.iov_len);
|
||||
std::memset(buf.data(), 0, buf.size());
|
||||
}
|
||||
|
||||
struct write_fileop final : aux::fileop
|
||||
|
@ -303,7 +303,7 @@ namespace libtorrent {
|
|||
iovec_t const v = {buf.data(), buf.size()};
|
||||
std::int64_t const ret = f->writev(file_offset, v, ec.ec);
|
||||
TORRENT_UNUSED(ret);
|
||||
TORRENT_ASSERT(ec || ret == std::int64_t(v.iov_len));
|
||||
TORRENT_ASSERT(ec || ret == std::int64_t(v.size()));
|
||||
}, fs.file_offset(i), fs.file_size(i), ec.ec);
|
||||
|
||||
if (ec)
|
||||
|
@ -817,8 +817,8 @@ namespace {
|
|||
int ret = 0;
|
||||
for (auto const& b : bufs)
|
||||
{
|
||||
std::memset(b.iov_base, 0, b.iov_len);
|
||||
ret += int(b.iov_len);
|
||||
std::memset(b.data(), 0, b.size());
|
||||
ret += int(b.size());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -827,7 +827,7 @@ namespace {
|
|||
{
|
||||
int ret = 0;
|
||||
for (auto const& b : bufs)
|
||||
ret += int(b.iov_len);
|
||||
ret += int(b.size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,34 +44,35 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace libtorrent { namespace aux {
|
||||
|
||||
int copy_bufs(span<iovec_t const> bufs, int const bytes, span<iovec_t> target)
|
||||
int copy_bufs(span<iovec_t const> bufs, int bytes
|
||||
, span<iovec_t> target)
|
||||
{
|
||||
int size = 0;
|
||||
for (int i = 0;; i++)
|
||||
TORRENT_ASSERT(bytes >= 0);
|
||||
auto dst = target.begin();
|
||||
int ret = 0;
|
||||
if (bytes == 0) return ret;
|
||||
for (iovec_t const& src : bufs)
|
||||
{
|
||||
std::size_t const idx = std::size_t(i);
|
||||
target[idx] = bufs[idx];
|
||||
size += int(bufs[idx].iov_len);
|
||||
if (size >= bytes)
|
||||
{
|
||||
TORRENT_ASSERT(target[idx].iov_len >= aux::numeric_cast<std::size_t>(size - bytes));
|
||||
target[idx].iov_len -= aux::numeric_cast<std::size_t>(size - bytes);
|
||||
return i + 1;
|
||||
}
|
||||
std::size_t const to_copy = std::min(src.size(), std::size_t(bytes));
|
||||
*dst = src.first(to_copy);
|
||||
bytes -= int(to_copy);
|
||||
++ret;
|
||||
++dst;
|
||||
if (bytes <= 0) return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
span<iovec_t> advance_bufs(span<iovec_t> bufs, int const bytes)
|
||||
{
|
||||
int size = 0;
|
||||
TORRENT_ASSERT(bytes >= 0);
|
||||
std::size_t size = 0;
|
||||
for (;;)
|
||||
{
|
||||
size += int(bufs.front().iov_len);
|
||||
if (size >= bytes)
|
||||
size += bufs.front().size();
|
||||
if (size >= std::size_t(bytes))
|
||||
{
|
||||
bufs.front().iov_base = reinterpret_cast<char*>(bufs.front().iov_base)
|
||||
+ bufs.front().iov_len - (size - bytes);
|
||||
bufs.front().iov_len = aux::numeric_cast<std::size_t>(size - bytes);
|
||||
bufs.front() = bufs.front().last(size - std::size_t(bytes));
|
||||
return bufs;
|
||||
}
|
||||
bufs = bufs.subspan(1);
|
||||
|
@ -83,14 +84,16 @@ namespace libtorrent { namespace aux {
|
|||
|
||||
int count_bufs(span<iovec_t const> bufs, int bytes)
|
||||
{
|
||||
int size = 0;
|
||||
int count = 1;
|
||||
if (bytes == 0) return 0;
|
||||
for (auto i = bufs.begin();; ++i, ++count)
|
||||
std::size_t size = 0;
|
||||
int count = 0;
|
||||
if (bytes == 0) return count;
|
||||
for (auto b : bufs)
|
||||
{
|
||||
size += int(i->iov_len);
|
||||
if (size >= bytes) return count;
|
||||
++count;
|
||||
size += b.size();
|
||||
if (size >= std::size_t(bytes)) return count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/disk_io_thread.hpp"
|
||||
#include "libtorrent/storage.hpp"
|
||||
#include "libtorrent/session.hpp"
|
||||
#include "libtorrent/aux_/path.hpp" // for bufs_size
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
|
|
@ -291,14 +291,14 @@ TORRENT_TEST(file)
|
|||
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
|
||||
TEST_EQUAL(ec, error_code());
|
||||
if (ec) std::printf("%s\n", ec.message().c_str());
|
||||
iovec_t b = {(void*)"test", 4};
|
||||
char test[] = "test";
|
||||
iovec_t b = {test, 4};
|
||||
TEST_EQUAL(f.writev(0, b, ec), 4);
|
||||
if (ec)
|
||||
std::printf("writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
|
||||
TEST_CHECK(!ec);
|
||||
char test_buf[5] = {0};
|
||||
b.iov_base = test_buf;
|
||||
b.iov_len = 4;
|
||||
b = { test_buf, 4 };
|
||||
TEST_EQUAL(f.readv(0, b, ec), 4);
|
||||
if (ec)
|
||||
std::printf("readv failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
|
||||
|
@ -321,7 +321,8 @@ TORRENT_TEST(hard_link)
|
|||
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
|
||||
TEST_EQUAL(ec, error_code());
|
||||
|
||||
iovec_t b = {(void*)"abcdefghijklmnopqrstuvwxyz", 26};
|
||||
char str[] = "abcdefghijklmnopqrstuvwxyz";
|
||||
iovec_t b = { str, 26 };
|
||||
TEST_EQUAL(f.writev(0, b, ec), 26);
|
||||
if (ec)
|
||||
std::printf("writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
|
||||
|
@ -340,9 +341,8 @@ TORRENT_TEST(hard_link)
|
|||
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
|
||||
TEST_EQUAL(ec, error_code());
|
||||
|
||||
char test_buf[27] = {0};
|
||||
b.iov_base = test_buf;
|
||||
b.iov_len = 27;
|
||||
char test_buf[27] = {};
|
||||
b = { test_buf, 27 };
|
||||
TEST_EQUAL(f.readv(0, b, ec), 26);
|
||||
if (ec)
|
||||
std::printf("readv failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
|
||||
|
@ -368,18 +368,18 @@ TORRENT_TEST(coalesce_buffer)
|
|||
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
|
||||
TEST_EQUAL(ec, error_code());
|
||||
if (ec) std::printf("%s\n", ec.message().c_str());
|
||||
iovec_t b[2] = {{(void*)"test", 4}, {(void*)"foobar", 6}};
|
||||
TEST_EQUAL(f.writev(0, {b, 2}, ec, file::coalesce_buffers), 4 + 6);
|
||||
char test[] = "test";
|
||||
char foobar[] = "foobar";
|
||||
iovec_t b[2] = {{test, 4}, {foobar, 6}};
|
||||
TEST_EQUAL(f.writev(0, b, ec, file::coalesce_buffers), 4 + 6);
|
||||
if (ec)
|
||||
std::printf("writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
|
||||
TEST_CHECK(!ec);
|
||||
char test_buf1[5] = {0};
|
||||
char test_buf2[7] = {0};
|
||||
b[0].iov_base = test_buf1;
|
||||
b[0].iov_len = 4;
|
||||
b[1].iov_base = test_buf2;
|
||||
b[1].iov_len = 6;
|
||||
TEST_EQUAL(f.readv(0, {b, 2}, ec), 4 + 6);
|
||||
b[0] = { test_buf1, 4 };
|
||||
b[1] = { test_buf2, 6 };
|
||||
TEST_EQUAL(f.readv(0, b, ec), 4 + 6);
|
||||
if (ec)
|
||||
{
|
||||
std::printf("readv failed: [%s] %s\n"
|
||||
|
|
|
@ -69,7 +69,7 @@ TORRENT_TEST(part_file)
|
|||
// write something to the metadata file
|
||||
for (int i = 0; i < 1024; ++i) buf[i] = i;
|
||||
|
||||
iovec_t v = {&buf, 1024};
|
||||
iovec_t v = buf;
|
||||
pf.writev(v, piece_index_t(10), 0, ec);
|
||||
if (ec) std::printf("part_file::writev: %s\n", ec.message().c_str());
|
||||
|
||||
|
@ -101,12 +101,12 @@ TORRENT_TEST(part_file)
|
|||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
iovec_t v = {&buf, 1024};
|
||||
iovec_t v = buf;
|
||||
pf.readv(v, piece_index_t(10), 0, ec);
|
||||
if (ec) std::printf("part_file::readv: %s\n", ec.message().c_str());
|
||||
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
TEST_CHECK(buf[i] == char(i));
|
||||
TEST_CHECK(buf[i] == static_cast<char>(i));
|
||||
|
||||
// test exporting the piece to a file
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ using namespace lt;
|
|||
|
||||
TORRENT_TEST(primitives)
|
||||
{
|
||||
using namespace lt;
|
||||
error_code ec;
|
||||
|
||||
// make sure the retry interval keeps growing
|
||||
|
|
|
@ -55,8 +55,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
using namespace std::placeholders;
|
||||
using namespace lt;
|
||||
|
||||
const int piece_size = 16 * 1024 * 16;
|
||||
const int half = piece_size / 2;
|
||||
std::size_t const piece_size = 16 * 1024 * 16;
|
||||
std::size_t const half = piece_size / 2;
|
||||
|
||||
void signal_bool(bool* b, char const* string)
|
||||
{
|
||||
|
@ -178,7 +178,7 @@ std::shared_ptr<default_storage> setup_torrent(file_storage& fs
|
|||
return s;
|
||||
}
|
||||
|
||||
std::vector<char> new_piece(int size)
|
||||
std::vector<char> new_piece(std::size_t const size)
|
||||
{
|
||||
std::vector<char> ret(size);
|
||||
std::generate(ret.begin(), ret.end(), random_byte);
|
||||
|
@ -245,54 +245,46 @@ void run_storage_tests(std::shared_ptr<torrent_info> info
|
|||
ret = s->writev(iov, piece_index_t(0), 0, 0, ec);
|
||||
if (ret != half) print_error("writev", ret, ec);
|
||||
|
||||
iov.iov_base = piece1.data() + half;
|
||||
iov.iov_len = half;
|
||||
iov = { piece1.data() + half, half };
|
||||
ret = s->writev(iov, piece_index_t(0), half, 0, ec);
|
||||
if (ret != half) print_error("writev", ret, ec);
|
||||
|
||||
// test unaligned read (where the bytes are aligned)
|
||||
iov.iov_base = piece + 3;
|
||||
iov.iov_len = piece_size - 9;
|
||||
iov = { piece + 3, piece_size - 9};
|
||||
ret = s->readv(iov, piece_index_t(0), 3, 0, ec);
|
||||
if (ret != piece_size - 9) print_error("readv",ret, ec);
|
||||
TEST_CHECK(std::equal(piece+3, piece + piece_size-9, piece1.data()+3));
|
||||
|
||||
// test unaligned read (where the bytes are not aligned)
|
||||
iov.iov_base = piece;
|
||||
iov.iov_len = piece_size - 9;
|
||||
iov = { piece, piece_size - 9};
|
||||
ret = s->readv(iov, piece_index_t(0), 3, 0, ec);
|
||||
TEST_CHECK(ret == piece_size - 9);
|
||||
if (ret != piece_size - 9) print_error("readv", ret, ec);
|
||||
TEST_CHECK(std::equal(piece, piece + piece_size-9, piece1.data()+3));
|
||||
|
||||
// verify piece 1
|
||||
iov.iov_base = piece;
|
||||
iov.iov_len = piece_size;
|
||||
iov = { piece, piece_size };
|
||||
ret = s->readv(iov, piece_index_t(0), 0, 0, ec);
|
||||
TEST_CHECK(ret == piece_size);
|
||||
if (ret != piece_size) print_error("readv", ret, ec);
|
||||
TEST_CHECK(std::equal(piece, piece + piece_size, piece1.data()));
|
||||
|
||||
// do the same with piece 0 and 2 (in slot 1 and 2)
|
||||
iov.iov_base = piece0.data();
|
||||
iov.iov_len = piece_size;
|
||||
iov = { piece0.data(), piece_size };
|
||||
ret = s->writev(iov, piece_index_t(1), 0, 0, ec);
|
||||
if (ret != piece_size) print_error("writev", ret, ec);
|
||||
|
||||
iov.iov_base = piece2.data();
|
||||
iov.iov_len = piece_size;
|
||||
iov = { piece2.data(), piece_size };
|
||||
ret = s->writev(iov, piece_index_t(2), 0, 0, ec);
|
||||
if (ret != piece_size) print_error("writev", ret, ec);
|
||||
|
||||
// verify piece 0 and 2
|
||||
iov.iov_base = piece;
|
||||
iov.iov_len = piece_size;
|
||||
iov = { piece, piece_size };
|
||||
ret = s->readv(iov, piece_index_t(1), 0, 0, ec);
|
||||
if (ret != piece_size) print_error("readv", ret, ec);
|
||||
TEST_CHECK(std::equal(piece, piece + piece_size, piece0.data()));
|
||||
|
||||
iov.iov_base = piece;
|
||||
iov.iov_len = piece_size;
|
||||
iov = { piece, piece_size };
|
||||
ret = s->readv(iov, piece_index_t(2), 0, 0, ec);
|
||||
if (ret != piece_size) print_error("readv", ret, ec);
|
||||
TEST_CHECK(std::equal(piece, piece + piece_size, piece2.data()));
|
||||
|
@ -558,8 +550,8 @@ void run_test(bool unbuffered)
|
|||
TEST_EQUAL(file_size(combine_path(base, "test6.tmp")), 841);
|
||||
std::printf("file: %d expected: %d last_file_size: %d, piece_size: %d\n"
|
||||
, int(file_size(combine_path(base, "test7.tmp")))
|
||||
, int(last_file_size - piece_size), last_file_size, piece_size);
|
||||
TEST_EQUAL(file_size(combine_path(base, "test7.tmp")), last_file_size - piece_size);
|
||||
, int(last_file_size - piece_size), last_file_size, int(piece_size));
|
||||
TEST_EQUAL(file_size(combine_path(base, "test7.tmp")), last_file_size - int(piece_size));
|
||||
remove_all(combine_path(test_path, "temp_storage"), ec);
|
||||
if (ec && ec != boost::system::errc::no_such_file_or_directory)
|
||||
std::cout << "remove_all '" << combine_path(test_path, "temp_storage")
|
||||
|
@ -931,20 +923,20 @@ void alloc_iov(iovec_t* iov, int num_bufs)
|
|||
{
|
||||
for (int i = 0; i < num_bufs; ++i)
|
||||
{
|
||||
iov[i].iov_base = malloc(num_bufs * (i + 1));
|
||||
iov[i].iov_len = num_bufs * (i + 1);
|
||||
iov[i] = { new char[num_bufs * (i + 1)]
|
||||
, static_cast<std::size_t>(num_bufs * (i + 1)) };
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this should take a span of iovec_ts
|
||||
void fill_pattern(iovec_t* iov, int num_bufs)
|
||||
{
|
||||
int counter = 0;
|
||||
for (int i = 0; i < num_bufs; ++i)
|
||||
{
|
||||
unsigned char* buf = (unsigned char*)iov[i].iov_base;
|
||||
for (int k = 0; k < int(iov[i].iov_len); ++k)
|
||||
for (char& v : iov[i])
|
||||
{
|
||||
buf[k] = counter & 0xff;
|
||||
v = counter & 0xff;
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
|
@ -961,22 +953,22 @@ bool check_pattern(std::vector<char> const& buf, int counter)
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO: this should take a span
|
||||
void fill_pattern2(iovec_t* iov, int num_bufs)
|
||||
{
|
||||
for (int i = 0; i < num_bufs; ++i)
|
||||
{
|
||||
unsigned char* buf = (unsigned char*)iov[i].iov_base;
|
||||
memset(buf, 0xfe, int(iov[i].iov_len));
|
||||
memset(iov[i].data(), 0xfe, iov[i].size());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this should take a span
|
||||
void free_iov(iovec_t* iov, int num_bufs)
|
||||
{
|
||||
for (int i = 0; i < num_bufs; ++i)
|
||||
{
|
||||
free(iov[i].iov_base);
|
||||
iov[i].iov_len = 0;
|
||||
iov[i].iov_base = nullptr;
|
||||
delete[] iov[i].data();
|
||||
iov[i] = { nullptr, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -999,10 +991,9 @@ TORRENT_TEST(iovec_copy_bufs)
|
|||
int counter = 0;
|
||||
for (int i = 0; i < num_bufs; ++i)
|
||||
{
|
||||
unsigned char* buf = (unsigned char*)iov2[i].iov_base;
|
||||
for (int k = 0; k < int(iov2[i].iov_len); ++k)
|
||||
for (char v : iov2[i])
|
||||
{
|
||||
TEST_EQUAL(int(buf[k]), (counter & 0xff));
|
||||
TEST_EQUAL(int(v), (counter & 0xff));
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
|
@ -1020,10 +1011,9 @@ TORRENT_TEST(iovec_clear_bufs)
|
|||
clear_bufs({iov, 10});
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
unsigned char* buf = (unsigned char*)iov[i].iov_base;
|
||||
for (int k = 0; k < int(iov[i].iov_len); ++k)
|
||||
for (char v : iov[i])
|
||||
{
|
||||
TEST_EQUAL(int(buf[k]), 0);
|
||||
TEST_EQUAL(int(v), 0);
|
||||
}
|
||||
}
|
||||
free_iov(iov, 10);
|
||||
|
@ -1064,10 +1054,9 @@ TORRENT_TEST(iovec_advance_bufs)
|
|||
int counter = 13;
|
||||
for (auto buf : iov)
|
||||
{
|
||||
unsigned char* buf_base = (unsigned char*)buf.iov_base;
|
||||
for (int k = 0; k < int(buf.iov_len); ++k)
|
||||
for (char v : buf)
|
||||
{
|
||||
TEST_EQUAL(int(buf_base[k]), (counter & 0xff));
|
||||
TEST_EQUAL(v, static_cast<char>(counter));
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
|
@ -1115,8 +1104,8 @@ struct test_fileop : aux::fileop
|
|||
int left = write_size;
|
||||
while (left > 0)
|
||||
{
|
||||
const int copy_size = (std::min)(left, int(bufs.front().iov_len));
|
||||
memcpy(&file[offset], bufs.front().iov_base, copy_size);
|
||||
const int copy_size = std::min(left, int(bufs.front().size()));
|
||||
memcpy(&file[offset], bufs.front().data(), copy_size);
|
||||
bufs = bufs.subspan(1);
|
||||
offset += copy_size;
|
||||
left -= copy_size;
|
||||
|
@ -1140,11 +1129,11 @@ struct test_read_fileop : aux::fileop
|
|||
const int read = local_size;
|
||||
while (local_size > 0)
|
||||
{
|
||||
unsigned char* p = (unsigned char*)bufs.front().iov_base;
|
||||
const int len = (std::min)(int(bufs.front().iov_len), local_size);
|
||||
for (int i = 0; i < len; ++i)
|
||||
int const len = std::min(int(bufs.front().size()), local_size);
|
||||
auto local_buf = bufs.front().first(len);
|
||||
for (char& v : local_buf)
|
||||
{
|
||||
p[i] = m_counter & 0xff;
|
||||
v = m_counter & 0xff;
|
||||
++m_counter;
|
||||
}
|
||||
local_size -= len;
|
||||
|
@ -1188,7 +1177,7 @@ int count_bufs(iovec_t const* bufs, int bytes)
|
|||
if (bytes == 0) return 0;
|
||||
for (iovec_t const* i = bufs;; ++i, ++count)
|
||||
{
|
||||
size += int(i->iov_len);
|
||||
size += int(i->size());
|
||||
if (size >= bytes) return count;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ struct test_storage : default_storage
|
|||
return 0;
|
||||
}
|
||||
|
||||
for (auto const& b : bufs) m_written += int(b.iov_len);
|
||||
for (auto const& b : bufs) m_written += int(b.size());
|
||||
l.unlock();
|
||||
return default_storage::writev(bufs, piece_index, offset, flags, se);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue