diff --git a/include/seastar/net/api.hh b/include/seastar/net/api.hh index e08619ce1e6..49592f4df7c 100644 --- a/include/seastar/net/api.hh +++ b/include/seastar/net/api.hh @@ -131,13 +131,18 @@ public: class input_buffer_factory { public: + using buffer_t = temporary_buffer; + virtual ~input_buffer_factory() = default; /// Provide a rx buffer. Implementation is responsible for determining its size /// and memory. This is useful when a network stack implementation does not put /// extra requirements on these factors. The POSIX stack is the example here. /// \param allocator Memory allocator \c connected_socket implementation prefers. /// Maybe nullptr. - virtual temporary_buffer create(compat::polymorphic_allocator* allocator) = 0; + virtual buffer_t create(compat::polymorphic_allocator* allocator) = 0; + + // Give back to the factory unused part of a buffer obtained from it + virtual void return_unused(buffer_t&& buf) = 0; }; } /* namespace net */ diff --git a/src/net/posix-stack.cc b/src/net/posix-stack.cc index 5c080117880..2c27ea9e062 100644 --- a/src/net/posix-stack.cc +++ b/src/net/posix-stack.cc @@ -119,9 +119,11 @@ class posix_connected_socket_impl final : public connected_socket_impl, posix_co virtual data_source source(net::input_buffer_factory* ibf) override { if (!ibf) { static struct final : input_buffer_factory { - temporary_buffer create(compat::polymorphic_allocator* const allocator) override { + buffer_t create(compat::polymorphic_allocator* const allocator) override { return make_temporary_buffer(allocator, 8192); } + void return_unused(buffer_t&&) override { + } } default_posix_inbuf_factory{}; ibf = &default_posix_inbuf_factory; } @@ -327,9 +329,11 @@ future> posix_data_source_impl::get() { _buf = _buffer_factory->create(_buffer_allocator); return _fd->read_some(_buf.get_write(), _buf.size()).then([this] (size_t size) { - _buf.trim(size); - auto ret = std::move(_buf); - return make_ready_future>(std::move(ret)); + if (size < _buf.size()) { + _buffer_factory->return_unused(_buf.share(size, _buf.size() - size)); + _buf.trim(size); + } + return make_ready_future>(std::move(_buf)); }); }