src: memchunks: Don't use std::unique_ptr to avoid potential SO
This commit is contained in:
parent
7f31278c4c
commit
c57bf21306
|
@ -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;
|
||||
|
@ -76,9 +74,9 @@ 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;
|
||||
|
@ -86,11 +84,16 @@ template <typename T> 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<T> pool;
|
||||
T *pool;
|
||||
T *freelist;
|
||||
size_t poolsize;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue