X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Fexperimental%2Fhazptr%2Fhazptr.h;h=48e8392ae48676fccd311e667e41e0f986ca2117;hb=7046d43c7e3c18ebc28c62141b8e1eefabce5323;hp=f1776e4b8e4c8fd4e9abf4a8edcc1a32d9360b94;hpb=bf4d53709b769785cb1f8afeca5547dd18439acf;p=folly.git diff --git a/folly/experimental/hazptr/hazptr.h b/folly/experimental/hazptr/hazptr.h index f1776e4b..48e8392a 100644 --- a/folly/experimental/hazptr/hazptr.h +++ b/folly/experimental/hazptr/hazptr.h @@ -34,6 +34,12 @@ class hazptr_obj; template class hazptr_obj_base; +/** hazptr_obj_base_refcounted: + * Base template for reference counted objects protected by hazard pointers. + */ +template +class hazptr_obj_base_refcounted; + /** hazptr_local: Optimized template for bulk construction and destruction of * hazard pointers */ template @@ -56,10 +62,16 @@ class hazptr_domain { hazptr_domain& operator=(const hazptr_domain&) = delete; hazptr_domain& operator=(hazptr_domain&&) = delete; + /** Free-function retire. May allocate memory */ + template > + void retire(T* obj, D reclaim = {}); + private: friend class hazptr_holder; template friend class hazptr_obj_base; + template + friend class hazptr_obj_base_refcounted; friend struct hazptr_priv; memory_resource* mr_; @@ -82,15 +94,22 @@ hazptr_domain& default_hazptr_domain(); extern hazptr_domain default_domain_; +/** Free-function retire, that operates on the default domain */ +template > +void hazptr_retire(T* obj, D reclaim = {}); + /** Definition of hazptr_obj */ class hazptr_obj { friend class hazptr_domain; template friend class hazptr_obj_base; + template + friend class hazptr_obj_base_refcounted; friend struct hazptr_priv; void (*reclaim_)(hazptr_obj*); hazptr_obj* next_; + const void* getObjPtr() const; }; @@ -106,6 +125,33 @@ class hazptr_obj_base : public hazptr_obj { D deleter_; }; +/** Definition of hazptr_recounted_obj_base */ +template > +class hazptr_obj_base_refcounted : public hazptr_obj { + public: + /* Retire a removed object and pass the responsibility for + * reclaiming it to the hazptr library */ + void retire(hazptr_domain& domain = default_hazptr_domain(), D reclaim = {}); + + /* aquire_ref() increments the reference count + * + * acquire_ref_safe() is the same as acquire_ref() except that in + * addition the caller guarantees that the call is made in a + * thread-safe context, e.g., the object is not yet shared. This is + * just an optimization to save an atomic operation. + * + * release_ref() decrements the reference count and returns true if + * the object is safe to reclaim. + */ + void acquire_ref(); + void acquire_ref_safe(); + bool release_ref(); + + private: + std::atomic refcount_{0}; + D deleter_; +}; + /** hazptr_holder: Class for automatic acquisition and release of * hazard pointers, and interface for hazard pointer operations. */ class hazptr_holder {