Commit 17d234c6 authored by Maged Michael's avatar Maged Michael Committed by Facebook Github Bot

Hazard pointers: Fix leak in hazptr_priv destruction

Summary:
- Fixed leak in hazptr_priv destruction
- Updated tests to detect leak

Reviewed By: djwatson

Differential Revision: D5351280

fbshipit-source-id: 724810cbbe0565f0cbd41f9d2121abefd98487bd
parent a4a7fad4
...@@ -127,6 +127,7 @@ class hazptr_priv { ...@@ -127,6 +127,7 @@ class hazptr_priv {
hazptr_obj* head_{nullptr}; hazptr_obj* head_{nullptr};
hazptr_obj* tail_{nullptr}; hazptr_obj* tail_{nullptr};
int rcount_{0}; int rcount_{0};
bool active_{true};
public: public:
hazptr_priv(); hazptr_priv();
...@@ -608,6 +609,8 @@ inline hazptr_priv::hazptr_priv() { ...@@ -608,6 +609,8 @@ inline hazptr_priv::hazptr_priv() {
inline hazptr_priv::~hazptr_priv() { inline hazptr_priv::~hazptr_priv() {
DEBUG_PRINT(this); DEBUG_PRINT(this);
DCHECK(active_);
active_ = false;
if (tail_) { if (tail_) {
pushAllToDomain(); pushAllToDomain();
} }
...@@ -618,6 +621,10 @@ inline void hazptr_priv::push(hazptr_obj* obj) { ...@@ -618,6 +621,10 @@ inline void hazptr_priv::push(hazptr_obj* obj) {
if (tail_) { if (tail_) {
tail_->next_ = obj; tail_->next_ = obj;
} else { } else {
if (!active_) {
default_hazptr_domain().objRetire(obj);
return;
}
head_ = obj; head_ = obj;
} }
tail_ = obj; tail_ = obj;
......
...@@ -262,23 +262,32 @@ TEST_F(HazptrTest, VirtualTest) { ...@@ -262,23 +262,32 @@ TEST_F(HazptrTest, VirtualTest) {
} }
} }
TEST_F(HazptrTest, DestructionTest) { void destructionTest(hazptr_domain& domain) {
hazptr_domain myDomain0;
struct Thing : public hazptr_obj_base<Thing> { struct Thing : public hazptr_obj_base<Thing> {
Thing* next; Thing* next;
Thing(Thing* n) : next(n) {} hazptr_domain* domain;
int val;
Thing(int v, Thing* n, hazptr_domain* d) : next(n), domain(d), val(v) {}
~Thing() { ~Thing() {
DEBUG_PRINT("this: " << this << " next: " << next); DEBUG_PRINT("this: " << this << " val: " << val << " next: " << next);
if (next) { if (next) {
next->retire(); next->retire(*domain);
} }
} }
}; };
Thing* last{nullptr}; Thing* last{nullptr};
for (int i = 0; i < 2000; i++) { for (int i = 0; i < 2000; i++) {
last = new Thing(last); last = new Thing(i, last, &domain);
}
last->retire(domain);
}
TEST_F(HazptrTest, DestructionTest) {
{
hazptr_domain myDomain0;
destructionTest(myDomain0);
} }
last->retire(); destructionTest(default_hazptr_domain());
} }
TEST_F(HazptrTest, Move) { TEST_F(HazptrTest, Move) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment