Use byte_slice for sending zmq messages - removes data copy within zmq

This commit is contained in:
Lee Clagett 2019-11-17 06:06:10 +00:00
parent 378cdeaeae
commit da99157462
11 changed files with 138 additions and 27 deletions

View file

@ -42,7 +42,12 @@ namespace epee
struct release_byte_slice
{
void operator()(byte_slice_data*) const noexcept;
//! For use with `zmq_message_init_data`, use second arg for buffer pointer.
static void call(void*, void* ptr) noexcept;
void operator()(byte_slice_data* ptr) const noexcept
{
call(nullptr, ptr);
}
};
/*! Inspired by slices in golang. Storage is thread-safe reference counted,
@ -140,6 +145,9 @@ namespace epee
\throw std::out_of_range If `size() < end`.
\return Slice starting at `data() + begin` of size `end - begin`. */
byte_slice get_slice(std::size_t begin, std::size_t end) const;
//! \post `empty()` \return Ownership of ref-counted buffer.
std::unique_ptr<byte_slice_data, release_byte_slice> take_buffer() noexcept;
};
} // epee

View file

@ -49,12 +49,16 @@ namespace epee
std::atomic<std::size_t> ref_count;
};
void release_byte_slice::operator()(byte_slice_data* ptr) const noexcept
void release_byte_slice::call(void*, void* ptr) noexcept
{
if (ptr && --(ptr->ref_count) == 0)
if (ptr)
{
ptr->~byte_slice_data();
free(ptr);
byte_slice_data* self = static_cast<byte_slice_data*>(ptr);
if (--(self->ref_count) == 0)
{
self->~byte_slice_data();
free(self);
}
}
}
@ -206,4 +210,11 @@ namespace epee
return {};
return {storage_.get(), {portion_.begin() + begin, end - begin}};
}
std::unique_ptr<byte_slice_data, release_byte_slice> byte_slice::take_buffer() noexcept
{
std::unique_ptr<byte_slice_data, release_byte_slice> out{std::move(storage_)};
portion_ = nullptr;
return out;
}
} // epee