Commit 0e60f61d authored by Maged Michael's avatar Maged Michael Committed by Facebook Github Bot

hazptr: add checks for double retire in non-debug modes

Summary: Add steps to hazptr_obj construction and retirement to catch misuse bugs such as double retire.

Reviewed By: yfeldblum

Differential Revision: D6851965

fbshipit-source-id: 026e578b595792e3118b6b4b9a22c8c1dce6acba
parent 26276668
...@@ -221,6 +221,7 @@ inline constexpr hazptr_domain::hazptr_domain(memory_resource* mr) noexcept ...@@ -221,6 +221,7 @@ inline constexpr hazptr_domain::hazptr_domain(memory_resource* mr) noexcept
template <typename T, typename D> template <typename T, typename D>
inline void hazptr_obj_base<T, D>::retire(hazptr_domain& domain, D deleter) { inline void hazptr_obj_base<T, D>::retire(hazptr_domain& domain, D deleter) {
DEBUG_PRINT(this << " " << &domain); DEBUG_PRINT(this << " " << &domain);
retireCheck();
deleter_ = std::move(deleter); deleter_ = std::move(deleter);
reclaim_ = [](hazptr_obj* p) { reclaim_ = [](hazptr_obj* p) {
auto hobp = static_cast<hazptr_obj_base*>(p); auto hobp = static_cast<hazptr_obj_base*>(p);
...@@ -288,8 +289,8 @@ inline bool hazptr_obj_base_refcounted<T, D>::release_ref() { ...@@ -288,8 +289,8 @@ inline bool hazptr_obj_base_refcounted<T, D>::release_ref() {
template <typename T, typename D> template <typename T, typename D>
inline void hazptr_obj_base_refcounted<T, D>::preRetire(D deleter) { inline void hazptr_obj_base_refcounted<T, D>::preRetire(D deleter) {
DCHECK(next_ == nullptr);
deleter_ = std::move(deleter); deleter_ = std::move(deleter);
retireCheck();
reclaim_ = [](hazptr_obj* p) { reclaim_ = [](hazptr_obj* p) {
auto hrobp = static_cast<hazptr_obj_base_refcounted*>(p); auto hrobp = static_cast<hazptr_obj_base_refcounted*>(p);
if (hrobp->release_ref()) { if (hrobp->release_ref()) {
......
...@@ -113,7 +113,25 @@ class hazptr_obj { ...@@ -113,7 +113,25 @@ class hazptr_obj {
friend struct hazptr_priv; friend struct hazptr_priv;
void (*reclaim_)(hazptr_obj*); void (*reclaim_)(hazptr_obj*);
hazptr_obj* next_{nullptr}; // nullptr for debugging hazptr_obj* next_;
public:
hazptr_obj() {
// Only for catching misuse bugs like double retire
next_ = this;
}
private:
void retireCheck() {
// Only for catching misuse bugs like double retire
if (next_ != this) {
retireCheckFail();
}
}
FOLLY_NOINLINE void retireCheckFail() {
CHECK_EQ(next_, this);
}
const void* getObjPtr() const; const void* getObjPtr() const;
}; };
......
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