From ebc498f183cf1bd7ce408354f998d34480e91efd Mon Sep 17 00:00:00 2001 From: Jianfei Hu Date: Fri, 14 Feb 2020 13:43:27 -0800 Subject: [PATCH] buffer: draining any zero byte fragments (#9837) (#109) (#123) 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 Signed-off-by: Jianfei Hu Co-authored-by: Lizan Zhou --- 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 3f4d6a86f155..005ddcd05349 100644 --- a/source/common/buffer/buffer_impl.cc +++ b/source/common/buffer/buffer_impl.cc @@ -213,6 +213,11 @@ void OwnedImpl::drain(uint64_t size) { } } } + // 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 19e6daa06fb6..d1b6935546e4 100644 --- a/test/common/buffer/owned_impl_test.cc +++ b/test/common/buffer/owned_impl_test.cc @@ -70,6 +70,24 @@ TEST_P(OwnedImplTest, AddBufferFragmentWithCleanup) { EXPECT_TRUE(release_callback_called_); } +TEST_P(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_P(OwnedImplTest, AddBufferFragmentDynamicAllocation) { char input_stack[] = "hello world"; char* input = new char[11];