Skip to content

Commit

Permalink
src: memchunks: Don't use std::unique_ptr to avoid potential SO
Browse files Browse the repository at this point in the history
  • Loading branch information
tatsuhiro-t committed May 24, 2017
1 parent 7f31278 commit c57bf21
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 16 deletions.
21 changes: 12 additions & 9 deletions src/memchunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,21 @@ namespace nghttp2 {
#endif // !defined(IOV_MAX) || IOV_MAX >= DEFAULT_WR_IOVCNT

template <size_t N> struct Memchunk {
Memchunk(std::unique_ptr<Memchunk> 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<uint8_t, N> buf;
uint8_t *pos, *last;
std::unique_ptr<Memchunk> knext;
Memchunk *knext;
Memchunk *next;
static const size_t size = N;
};

template <typename T> struct Pool {
Pool() : pool(nullptr), freelist(nullptr), poolsize(0) {}
~Pool() { clear(); }
T *get() {
if (freelist) {
auto m = freelist;
Expand All @@ -76,21 +74,26 @@ template <typename T> struct Pool {
return m;
}

pool = make_unique<T>(std::move(pool));
pool = new T{pool};
poolsize += T::size;
return pool.get();
return pool;
}
void recycle(T *m) {
m->next = freelist;
freelist = m;
}
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<T> pool;
T *pool;
T *freelist;
size_t poolsize;
};
Expand Down
14 changes: 7 additions & 7 deletions src/memchunk_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit c57bf21

Please sign in to comment.