From 17d234c6a02351b52f5ab4d9e4b91a31dc030042 Mon Sep 17 00:00:00 2001 From: Maged Michael Date: Thu, 29 Jun 2017 21:21:32 -0700 Subject: [PATCH] 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 --- folly/experimental/hazptr/hazptr-impl.h | 7 ++++++ folly/experimental/hazptr/test/HazptrTest.cpp | 23 +++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/folly/experimental/hazptr/hazptr-impl.h b/folly/experimental/hazptr/hazptr-impl.h index 6b19bd8a..70123659 100644 --- a/folly/experimental/hazptr/hazptr-impl.h +++ b/folly/experimental/hazptr/hazptr-impl.h @@ -127,6 +127,7 @@ class hazptr_priv { hazptr_obj* head_{nullptr}; hazptr_obj* tail_{nullptr}; int rcount_{0}; + bool active_{true}; public: hazptr_priv(); @@ -608,6 +609,8 @@ inline hazptr_priv::hazptr_priv() { inline hazptr_priv::~hazptr_priv() { DEBUG_PRINT(this); + DCHECK(active_); + active_ = false; if (tail_) { pushAllToDomain(); } @@ -618,6 +621,10 @@ inline void hazptr_priv::push(hazptr_obj* obj) { if (tail_) { tail_->next_ = obj; } else { + if (!active_) { + default_hazptr_domain().objRetire(obj); + return; + } head_ = obj; } tail_ = obj; diff --git a/folly/experimental/hazptr/test/HazptrTest.cpp b/folly/experimental/hazptr/test/HazptrTest.cpp index d40e9275..a669db8b 100644 --- a/folly/experimental/hazptr/test/HazptrTest.cpp +++ b/folly/experimental/hazptr/test/HazptrTest.cpp @@ -262,23 +262,32 @@ TEST_F(HazptrTest, VirtualTest) { } } -TEST_F(HazptrTest, DestructionTest) { - hazptr_domain myDomain0; +void destructionTest(hazptr_domain& domain) { struct Thing : public hazptr_obj_base { 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() { - DEBUG_PRINT("this: " << this << " next: " << next); + DEBUG_PRINT("this: " << this << " val: " << val << " next: " << next); if (next) { - next->retire(); + next->retire(*domain); } } }; Thing* last{nullptr}; 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) { -- 2.34.1