/* * Copyright (c) Facebook, Inc. and its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include /// /// Classes related to link counted objects and automatic retirement. /// namespace folly { /** * hazptr_root * * Link to counted objects. When destroyed unlinks the linked object * if any. * * Template parameter T must support a member function unlink(), * inherited from hazptr_obj_base_linked. * * Use example: Bucket heads in ConcurrentHashMap. */ template class Atom> class hazptr_root { Atom link_; public: explicit hazptr_root(T* p = nullptr) noexcept : link_(p) {} ~hazptr_root() { auto p = link_.load(std::memory_order_relaxed); if (p) { p->unlink(); } } const Atom& operator()() const noexcept { return link_; } Atom& operator()() noexcept { return link_; } }; // hazptr_root /** * hazptr_obj_linked * * Base class template for link counted objects. * Supports: * - Protecting descendants of protected objects. * - One-pass reclamation of long immutable chains of objects. * - Automatic reclamation of acyclic structures. * * Two inbound link counts are maintained per object: * - Link count: Represents the number of links from mutable paths. * - Ref count: Represents the number of links from immutable paths. * [Note: The ref count is one less than such links plus one if * the object hasn't gone through matching with hazard pointers * without finding a match. That is, a new object without inbound * links has a ref count of 0 and an about-to-be-reclaimed object * can be viewed to have a ref count of -1.] * * User code can increment the link and ref counts by calling * acquire_link and acquire_ref or their variants that require the * user to guarantee thread safety. There are no public functions to * decrement the counts explicitly. Counts are decremented implicitly * as described in hazptr_obj_base_linked. */ template