ReadMostlyMainPtrDeleter
[folly.git] / folly / experimental / ReadMostlySharedPtr.h
index 1839b435848a12cd63ae69808d0e221f548a7640..f81ce856a6b962dd080887318ccad71b539776f1 100644 (file)
@@ -28,6 +28,8 @@ template <typename T, typename RefCount>
 class ReadMostlyWeakPtr;
 template <typename T, typename RefCount>
 class ReadMostlySharedPtr;
+template <typename RefCount>
+class ReadMostlyMainPtrDeleter;
 
 using DefaultRefCount = TLRefCount;
 
@@ -79,6 +81,7 @@ class ReadMostlySharedPtrCore {
 
  private:
   friend class ReadMostlyMainPtr<T, RefCount>;
+  friend class ReadMostlyMainPtrDeleter<RefCount>;
 
   explicit ReadMostlySharedPtrCore(std::shared_ptr<T> ptr) :
       ptrRaw_(ptr.get()),
@@ -183,6 +186,7 @@ class ReadMostlyMainPtr {
  private:
   friend class ReadMostlyWeakPtr<T, RefCount>;
   friend class ReadMostlySharedPtr<T, RefCount>;
+  friend class ReadMostlyMainPtrDeleter<RefCount>;
 
   detail::ReadMostlySharedPtrCore<T, RefCount>* impl_{nullptr};
 };
@@ -362,4 +366,33 @@ class ReadMostlySharedPtr {
   detail::ReadMostlySharedPtrCore<T, RefCount>* impl_{nullptr};
 };
 
+/**
+ * This can be used to destroy multiple ReadMostlyMainPtrs at once.
+ */
+template <typename RefCount = DefaultRefCount>
+class ReadMostlyMainPtrDeleter {
+ public:
+  ~ReadMostlyMainPtrDeleter() noexcept {
+    RefCount::useGlobal(refCounts_);
+    for (auto& decref : decrefs_) {
+      decref();
+    }
+  }
+
+  template <typename T>
+  void add(ReadMostlyMainPtr<T, RefCount> ptr) noexcept {
+    if (!ptr.impl_) {
+      return;
+    }
+
+    refCounts_.push_back(&ptr.impl_->count_);
+    refCounts_.push_back(&ptr.impl_->weakCount_);
+    decrefs_.push_back([impl = ptr.impl_] { impl->decref(); });
+    ptr.impl_ = nullptr;
+  }
+
+ private:
+  std::vector<RefCount*> refCounts_;
+  std::vector<folly::Function<void()>> decrefs_;
+};
 }