From: Dave Watson <davejwatson@fb.com> Date: Wed, 26 Apr 2017 16:56:26 +0000 (-0700) Subject: Fix virtual struct bug X-Git-Tag: v2017.05.01.00~11 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=92f554a525fc603232cc80b4603e4d43ec6b50de;p=folly.git Fix virtual struct bug Summary: virtual classes currently don't work in hazard pointers, and get incorrectly reclaimed. Reviewed By: magedm Differential Revision: D4951584 fbshipit-source-id: 8200df6bb8d500af2e89086edf7835d4fb90b6a2 --- diff --git a/folly/experimental/hazptr/hazptr-impl.h b/folly/experimental/hazptr/hazptr-impl.h index 1ed15244..ecf6865d 100644 --- a/folly/experimental/hazptr/hazptr-impl.h +++ b/folly/experimental/hazptr/hazptr-impl.h @@ -108,8 +108,9 @@ inline T* hazptr_owner<T>::get_protected(const A& src) noexcept { template <typename T> inline void hazptr_owner<T>::set(const T* ptr) noexcept { - DEBUG_PRINT(this << " " << ptr); - hazptr_->set(ptr); + auto p = static_cast<hazptr_obj*>(const_cast<T*>(ptr)); + DEBUG_PRINT(this << " " << ptr << " p:" << p); + hazptr_->set(p); } template <typename T> diff --git a/folly/experimental/hazptr/hazptr.h b/folly/experimental/hazptr/hazptr.h index 464dc1f3..d06cefcb 100644 --- a/folly/experimental/hazptr/hazptr.h +++ b/folly/experimental/hazptr/hazptr.h @@ -89,7 +89,7 @@ class hazptr_obj { /** Definition of hazptr_obj_base */ template <typename T, typename Deleter = std::default_delete<T>> -class hazptr_obj_base : private hazptr_obj { +class hazptr_obj_base : public hazptr_obj { public: /* Retire a removed object and pass the responsibility for * reclaiming it to the hazptr library */ diff --git a/folly/experimental/hazptr/test/HazptrTest.cpp b/folly/experimental/hazptr/test/HazptrTest.cpp index bcabbe72..fa4ac1ec 100644 --- a/folly/experimental/hazptr/test/HazptrTest.cpp +++ b/folly/experimental/hazptr/test/HazptrTest.cpp @@ -238,3 +238,21 @@ TEST_F(HazptrTest, WIDECAS) { ret = s.cas(u, v); CHECK(ret); } + +TEST_F(HazptrTest, VirtualTest) { + struct Thing : public hazptr_obj_base<Thing> { + virtual ~Thing() { + DEBUG_PRINT("this: " << this << " &a: " << &a << " a: " << a); + } + int a; + }; + for (int i = 0; i < 100; i++) { + auto bar = new Thing; + bar->a = i; + + hazptr_owner<Thing> hptr; + hptr.set(bar); + bar->retire(); + EXPECT_EQ(bar->a, i); + } +}