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
|
#endif // !defined(IOV_MAX) || IOV_MAX >= DEFAULT_WR_IOVCNT
|
||||||
|
|
||||||
template <size_t N> struct Memchunk {
|
template <size_t N> struct Memchunk {
|
||||||
Memchunk(std::unique_ptr<Memchunk> next_chunk)
|
Memchunk(Memchunk *next_chunk)
|
||||||
: pos(std::begin(buf)),
|
: pos(std::begin(buf)), last(pos), knext(next_chunk), next(nullptr) {}
|
||||||
last(pos),
|
|
||||||
knext(std::move(next_chunk)),
|
|
||||||
next(nullptr) {}
|
|
||||||
size_t len() const { return last - pos; }
|
size_t len() const { return last - pos; }
|
||||||
size_t left() const { return std::end(buf) - last; }
|
size_t left() const { return std::end(buf) - last; }
|
||||||
void reset() { pos = last = std::begin(buf); }
|
void reset() { pos = last = std::begin(buf); }
|
||||||
std::array<uint8_t, N> buf;
|
std::array<uint8_t, N> buf;
|
||||||
uint8_t *pos, *last;
|
uint8_t *pos, *last;
|
||||||
std::unique_ptr<Memchunk> knext;
|
Memchunk *knext;
|
||||||
Memchunk *next;
|
Memchunk *next;
|
||||||
static const size_t size = N;
|
static const size_t size = N;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> struct Pool {
|
template <typename T> struct Pool {
|
||||||
Pool() : pool(nullptr), freelist(nullptr), poolsize(0) {}
|
Pool() : pool(nullptr), freelist(nullptr), poolsize(0) {}
|
||||||
|
~Pool() { clear(); }
|
||||||
T *get() {
|
T *get() {
|
||||||
if (freelist) {
|
if (freelist) {
|
||||||
auto m = freelist;
|
auto m = freelist;
|
||||||
|
@ -76,9 +74,9 @@ template <typename T> struct Pool {
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
pool = make_unique<T>(std::move(pool));
|
pool = new T{pool};
|
||||||
poolsize += T::size;
|
poolsize += T::size;
|
||||||
return pool.get();
|
return pool;
|
||||||
}
|
}
|
||||||
void recycle(T *m) {
|
void recycle(T *m) {
|
||||||
m->next = freelist;
|
m->next = freelist;
|
||||||
|
@ -86,11 +84,16 @@ template <typename T> struct Pool {
|
||||||
}
|
}
|
||||||
void clear() {
|
void clear() {
|
||||||
freelist = nullptr;
|
freelist = nullptr;
|
||||||
|
for (auto p = pool; p;) {
|
||||||
|
auto knext = p->knext;
|
||||||
|
delete p;
|
||||||
|
p = knext;
|
||||||
|
}
|
||||||
pool = nullptr;
|
pool = nullptr;
|
||||||
poolsize = 0;
|
poolsize = 0;
|
||||||
}
|
}
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
std::unique_ptr<T> pool;
|
T *pool;
|
||||||
T *freelist;
|
T *freelist;
|
||||||
size_t poolsize;
|
size_t poolsize;
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,34 +42,34 @@ void test_pool_recycle(void) {
|
||||||
|
|
||||||
auto m1 = pool.get();
|
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(MemchunkPool::value_type::size == pool.poolsize);
|
||||||
CU_ASSERT(nullptr == pool.freelist);
|
CU_ASSERT(nullptr == pool.freelist);
|
||||||
|
|
||||||
auto m2 = pool.get();
|
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(2 * MemchunkPool::value_type::size == pool.poolsize);
|
||||||
CU_ASSERT(nullptr == pool.freelist);
|
CU_ASSERT(nullptr == pool.freelist);
|
||||||
CU_ASSERT(m1 == m2->knext.get());
|
CU_ASSERT(m1 == m2->knext);
|
||||||
CU_ASSERT(nullptr == m1->knext.get());
|
CU_ASSERT(nullptr == m1->knext);
|
||||||
|
|
||||||
auto m3 = pool.get();
|
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(3 * MemchunkPool::value_type::size == pool.poolsize);
|
||||||
CU_ASSERT(nullptr == pool.freelist);
|
CU_ASSERT(nullptr == pool.freelist);
|
||||||
|
|
||||||
pool.recycle(m3);
|
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(3 * MemchunkPool::value_type::size == pool.poolsize);
|
||||||
CU_ASSERT(m3 == pool.freelist);
|
CU_ASSERT(m3 == pool.freelist);
|
||||||
|
|
||||||
auto m4 = pool.get();
|
auto m4 = pool.get();
|
||||||
|
|
||||||
CU_ASSERT(m3 == m4);
|
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(3 * MemchunkPool::value_type::size == pool.poolsize);
|
||||||
CU_ASSERT(nullptr == pool.freelist);
|
CU_ASSERT(nullptr == pool.freelist);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue