From 749d0da87549d01ed02b66c1156a79a1af49bef1 Mon Sep 17 00:00:00 2001 From: arvidn Date: Sat, 29 Apr 2017 00:27:55 -0400 Subject: [PATCH] make iovec_t an alias for span, in preparation for removing it altogether in favour of span --- examples/connection_tester.cpp | 4 +- include/libtorrent/aux_/storage_utils.hpp | 19 ++--- include/libtorrent/file.hpp | 3 - src/block_cache.cpp | 12 ++-- src/disk_buffer_pool.cpp | 11 ++- src/disk_io_thread.cpp | 43 ++++++------ src/file.cpp | 84 ++++++++++++++--------- src/part_file.cpp | 21 +++--- src/path.cpp | 3 +- src/storage.cpp | 10 +-- src/storage_utils.cpp | 51 +++++++------- test/test_block_cache.cpp | 1 + test/test_file.cpp | 28 ++++---- test/test_part_file.cpp | 6 +- test/test_primitives.cpp | 1 - test/test_storage.cpp | 83 ++++++++++------------ test/test_transfer.cpp | 2 +- 17 files changed, 191 insertions(+), 191 deletions(-) diff --git a/examples/connection_tester.cpp b/examples/connection_tester.cpp index 469a1bf0e..5aae65083 100644 --- a/examples/connection_tester.cpp +++ b/examples/connection_tester.cpp @@ -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(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(piece) + , size_t(std::min(left_in_piece, 0x4000))}; storage_error error; st->writev(b, i, j, 0, error); if (error) diff --git a/include/libtorrent/aux_/storage_utils.hpp b/include/libtorrent/aux_/storage_utils.hpp index 3ae72f27e..21695b8c1 100644 --- a/include/libtorrent/aux_/storage_utils.hpp +++ b/include/libtorrent/aux_/storage_utils.hpp @@ -40,10 +40,6 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/units.hpp" #include "libtorrent/storage_defs.hpp" // for status_t -#ifndef TORRENT_WINDOWS -#include // 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 for disk write + // operations + using iovec_t = span; namespace aux { - TORRENT_EXTRA_EXPORT int copy_bufs(span bufs, int bytes, span target); + TORRENT_EXTRA_EXPORT int copy_bufs(span bufs + , int bytes, span target); TORRENT_EXTRA_EXPORT span advance_bufs(span bufs, int bytes); // this identifies a read or write operation so that readwritev() knows diff --git a/include/libtorrent/file.hpp b/include/libtorrent/file.hpp index 927c16855..f63234337 100644 --- a/include/libtorrent/file.hpp +++ b/include/libtorrent/file.hpp @@ -214,9 +214,6 @@ namespace libtorrent { static bool has_manage_volume_privs; #endif }; - - TORRENT_EXTRA_EXPORT int bufs_size(span bufs); - } #endif // TORRENT_FILE_HPP_INCLUDED diff --git a/src/block_cache.cpp b/src/block_cache.cpp index a7c1cf86e..30c71b437 100644 --- a/src/block_cache.cpp +++ b/src/block_cache.cpp @@ -1272,14 +1272,14 @@ void block_cache::insert_blocks(cached_piece_entry* pe, int block, spanstorage->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(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, spanblocks[block].buf) { - free_buffer(static_cast(buf.iov_base)); + free_buffer(buf.data()); } else { - pe->blocks[block].buf = static_cast(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; diff --git a/src/disk_buffer_pool.cpp b/src/disk_buffer_pool.cpp index 54fb59846..84da3d5ee 100644 --- a/src/disk_buffer_pool.cpp +++ b/src/disk_buffer_pool.cpp @@ -195,17 +195,16 @@ namespace libtorrent { std::unique_lock 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(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 l(m_pool_mutex); for (auto i : iov) { - char* buf = static_cast(i.iov_base); + char* buf = i.data(); TORRENT_ASSERT(is_disk_buffer(buf, l)); free_buffer_impl(buf, l); remove_buffer_in_use(buf); diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index 958fab3fe..92b13dc3d 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -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::min(block_size, size_left)); + iov[iov_len] = { pe->blocks[i].buf, aux::numeric_cast(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::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::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::min(block_size, piece_size - offset)); + iov = iov.first(aux::numeric_cast(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(iov.iov_base), int(iov.iov_len)); + h.update(iov); } - m_disk_cache.free_buffer(static_cast(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::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(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::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(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(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(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); diff --git a/src/file.cpp b/src/file.cpp index 349f0eacf..673af7c67 100644 --- a/src/file.cpp +++ b/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 // 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 - std::unique_ptr make_free_holder(T* ptr) - { - return std::unique_ptr(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(bufs_size(bufs)); - char* buf = static_cast(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(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& bufs , iovec_t& tmp) { std::size_t const buf_size = aux::numeric_cast(bufs_size(bufs)); - char* buf = static_cast(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(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 @@ -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(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 \ diff --git a/src/part_file.cpp b/src/part_file.cpp index c70630b0a..f97c4e537 100644 --- a/src/part_file.cpp +++ b/src/part_file.cpp @@ -96,8 +96,8 @@ namespace libtorrent { if (ec) return; // parse header - std::unique_ptr header(new std::uint32_t[m_header_size]); - iovec_t b = {header.get(), std::size_t(m_header_size)}; + std::vector header(static_cast(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(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 header(new std::uint32_t[m_header_size]); + std::vector header(static_cast(m_header_size)); using namespace libtorrent::detail; - char* ptr = reinterpret_cast(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(slot), ptr); } - std::memset(ptr, 0, std::size_t(m_header_size - (ptr - reinterpret_cast(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); } } diff --git a/src/path.cpp b/src/path.cpp index 4335db08d..2d785c0aa 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -130,8 +130,7 @@ namespace libtorrent { int bufs_size(span bufs) { std::size_t size = 0; - for (auto buf : bufs) - size += buf.iov_len; + for (auto buf : bufs) size += buf.size(); return int(size); } diff --git a/src/storage.cpp b/src/storage.cpp index 7f364e129..3dcb6c1bf 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -80,7 +80,7 @@ namespace libtorrent { void clear_bufs(span 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; } diff --git a/src/storage_utils.cpp b/src/storage_utils.cpp index 4894de5e2..252cbae76 100644 --- a/src/storage_utils.cpp +++ b/src/storage_utils.cpp @@ -44,34 +44,35 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { namespace aux { - int copy_bufs(span bufs, int const bytes, span target) + int copy_bufs(span bufs, int bytes + , span 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(size - bytes)); - target[idx].iov_len -= aux::numeric_cast(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 advance_bufs(span 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(bufs.front().iov_base) - + bufs.front().iov_len - (size - bytes); - bufs.front().iov_len = aux::numeric_cast(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 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; } } diff --git a/test/test_block_cache.cpp b/test/test_block_cache.cpp index 979bb643a..06b6b04cc 100644 --- a/test/test_block_cache.cpp +++ b/test/test_block_cache.cpp @@ -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 #include diff --git a/test/test_file.cpp b/test/test_file.cpp index 4ac5051cf..63991bc75 100644 --- a/test/test_file.cpp +++ b/test/test_file.cpp @@ -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" diff --git a/test/test_part_file.cpp b/test/test_part_file.cpp index 009db820e..0f8f0425e 100644 --- a/test/test_part_file.cpp +++ b/test/test_part_file.cpp @@ -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(i)); // test exporting the piece to a file diff --git a/test/test_primitives.cpp b/test/test_primitives.cpp index 3cb89f20b..e2ce3764d 100644 --- a/test/test_primitives.cpp +++ b/test/test_primitives.cpp @@ -44,7 +44,6 @@ using namespace lt; TORRENT_TEST(primitives) { - using namespace lt; error_code ec; // make sure the retry interval keeps growing diff --git a/test/test_storage.cpp b/test/test_storage.cpp index 218e1b376..237902641 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -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 setup_torrent(file_storage& fs return s; } -std::vector new_piece(int size) +std::vector new_piece(std::size_t const size) { std::vector ret(size); std::generate(ret.begin(), ret.end(), random_byte); @@ -245,54 +245,46 @@ void run_storage_tests(std::shared_ptr 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(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 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(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; } } diff --git a/test/test_transfer.cpp b/test/test_transfer.cpp index 6824e760c..6d6e0aa0a 100644 --- a/test/test_transfer.cpp +++ b/test/test_transfer.cpp @@ -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); }