From e0dd91b53d19e4da2d453a76ca681a58b4c0068f Mon Sep 17 00:00:00 2001 From: alyssawilk Date: Mon, 27 Jan 2020 12:22:37 -0500 Subject: [PATCH] buffer: draining any zero byte fragments (#9837) Given that we allow creating zero byte fragments, it'd be good to proactively drain them. For example if someone is doing timing instrumentation and wants to know when Network::Connection data is written to the kernel, it could be useful to have a zero byte sentinel. Risk Level: Low (I don't think anyone is adding zero byte fragments yet) Testing: new unit test Docs Changes: n/a Release Notes: n/a Signed-off-by: Alyssa Wilk --- source/common/buffer/buffer_impl.cc | 5 +++++ test/common/buffer/owned_impl_test.cc | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/source/common/buffer/buffer_impl.cc b/source/common/buffer/buffer_impl.cc index f8e18b4f2e55..23e2bcdf91df 100644 --- a/source/common/buffer/buffer_impl.cc +++ b/source/common/buffer/buffer_impl.cc @@ -148,6 +148,11 @@ void OwnedImpl::drain(uint64_t size) { size = 0; } } + // Make sure to drain any zero byte fragments that might have been added as + // sentinels for flushed data. + while (!slices_.empty() && slices_.front()->dataSize() == 0) { + slices_.pop_front(); + } } uint64_t OwnedImpl::getRawSlices(RawSlice* out, uint64_t out_size) const { diff --git a/test/common/buffer/owned_impl_test.cc b/test/common/buffer/owned_impl_test.cc index 14fd7145e0ac..8be60ef91ae3 100644 --- a/test/common/buffer/owned_impl_test.cc +++ b/test/common/buffer/owned_impl_test.cc @@ -65,6 +65,24 @@ TEST_F(OwnedImplTest, AddBufferFragmentWithCleanup) { EXPECT_TRUE(release_callback_called_); } +TEST_F(OwnedImplTest, AddEmptyFragment) { + char input[] = "hello world"; + BufferFragmentImpl frag1(input, 11, [](const void*, size_t, const BufferFragmentImpl*) {}); + BufferFragmentImpl frag2("", 0, [this](const void*, size_t, const BufferFragmentImpl*) { + release_callback_called_ = true; + }); + Buffer::OwnedImpl buffer; + buffer.addBufferFragment(frag1); + EXPECT_EQ(11, buffer.length()); + + buffer.addBufferFragment(frag2); + EXPECT_EQ(11, buffer.length()); + + buffer.drain(11); + EXPECT_EQ(0, buffer.length()); + EXPECT_TRUE(release_callback_called_); +} + TEST_F(OwnedImplTest, AddBufferFragmentDynamicAllocation) { char input_stack[] = "hello world"; char* input = new char[11];