From c57bf21306be891a16cf722045205fb0435043cb Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Mon, 22 May 2017 23:17:04 +0900 Subject: [PATCH] src: memchunks: Don't use std::unique_ptr to avoid potential SO --- src/memchunk.h | 21 ++++++++++++--------- src/memchunk_test.cc | 14 +++++++------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/memchunk.h b/src/memchunk.h index 44daf164..b5fec00b 100644 --- a/src/memchunk.h +++ b/src/memchunk.h @@ -50,23 +50,21 @@ namespace nghttp2 { #endif // !defined(IOV_MAX) || IOV_MAX >= DEFAULT_WR_IOVCNT template struct Memchunk { - Memchunk(std::unique_ptr next_chunk) - : pos(std::begin(buf)), - last(pos), - knext(std::move(next_chunk)), - next(nullptr) {} + Memchunk(Memchunk *next_chunk) + : pos(std::begin(buf)), last(pos), knext(next_chunk), next(nullptr) {} size_t len() const { return last - pos; } size_t left() const { return std::end(buf) - last; } void reset() { pos = last = std::begin(buf); } std::array buf; uint8_t *pos, *last; - std::unique_ptr knext; + Memchunk *knext; Memchunk *next; static const size_t size = N; }; template struct Pool { Pool() : pool(nullptr), freelist(nullptr), poolsize(0) {} + ~Pool() { clear(); } T *get() { if (freelist) { auto m = freelist; @@ -76,9 +74,9 @@ template struct Pool { return m; } - pool = make_unique(std::move(pool)); + pool = new T{pool}; poolsize += T::size; - return pool.get(); + return pool; } void recycle(T *m) { m->next = freelist; @@ -86,11 +84,16 @@ template struct Pool { } void clear() { freelist = nullptr; + for (auto p = pool; p;) { + auto knext = p->knext; + delete p; + p = knext; + } pool = nullptr; poolsize = 0; } using value_type = T; - std::unique_ptr pool; + T *pool; T *freelist; size_t poolsize; }; diff --git a/src/memchunk_test.cc b/src/memchunk_test.cc index 0ae48eb6..41854b7c 100644 --- a/src/memchunk_test.cc +++ b/src/memchunk_test.cc @@ -42,34 +42,34 @@ void test_pool_recycle(void) { auto m1 = pool.get(); - CU_ASSERT(m1 == pool.pool.get()); + CU_ASSERT(m1 == pool.pool); CU_ASSERT(MemchunkPool::value_type::size == pool.poolsize); CU_ASSERT(nullptr == pool.freelist); auto m2 = pool.get(); - CU_ASSERT(m2 == pool.pool.get()); + CU_ASSERT(m2 == pool.pool); CU_ASSERT(2 * MemchunkPool::value_type::size == pool.poolsize); CU_ASSERT(nullptr == pool.freelist); - CU_ASSERT(m1 == m2->knext.get()); - CU_ASSERT(nullptr == m1->knext.get()); + CU_ASSERT(m1 == m2->knext); + CU_ASSERT(nullptr == m1->knext); auto m3 = pool.get(); - CU_ASSERT(m3 == pool.pool.get()); + CU_ASSERT(m3 == pool.pool); CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize); CU_ASSERT(nullptr == pool.freelist); pool.recycle(m3); - CU_ASSERT(m3 == pool.pool.get()); + CU_ASSERT(m3 == pool.pool); CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize); CU_ASSERT(m3 == pool.freelist); auto m4 = pool.get(); CU_ASSERT(m3 == m4); - CU_ASSERT(m4 == pool.pool.get()); + CU_ASSERT(m4 == pool.pool); CU_ASSERT(3 * MemchunkPool::value_type::size == pool.poolsize); CU_ASSERT(nullptr == pool.freelist);