summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/include/rocksdb/cleanable.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/rocksdb/include/rocksdb/cleanable.h128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/rocksdb/include/rocksdb/cleanable.h b/src/rocksdb/include/rocksdb/cleanable.h
new file mode 100644
index 000000000..afc736673
--- /dev/null
+++ b/src/rocksdb/include/rocksdb/cleanable.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file. See the AUTHORS file for names of contributors.
+
+#pragma once
+
+#include "rocksdb/rocksdb_namespace.h"
+
+namespace ROCKSDB_NAMESPACE {
+
+class Cleanable {
+ public:
+ Cleanable();
+ // No copy constructor and copy assignment allowed.
+ Cleanable(Cleanable&) = delete;
+ Cleanable& operator=(Cleanable&) = delete;
+
+ // Executes all the registered cleanups
+ ~Cleanable();
+
+ // Move constructor and move assignment is allowed.
+ Cleanable(Cleanable&&) noexcept;
+ Cleanable& operator=(Cleanable&&) noexcept;
+
+ // Clients are allowed to register function/arg1/arg2 triples that
+ // will be invoked when this iterator is destroyed.
+ //
+ // Note that unlike all of the preceding methods, this method is
+ // not abstract and therefore clients should not override it.
+ using CleanupFunction = void (*)(void* arg1, void* arg2);
+
+ // Add another Cleanup to the list
+ void RegisterCleanup(CleanupFunction function, void* arg1, void* arg2);
+
+ // Move the cleanups owned by this Cleanable to another Cleanable, adding to
+ // any existing cleanups it has
+ void DelegateCleanupsTo(Cleanable* other);
+
+ // DoCleanup and also resets the pointers for reuse
+ inline void Reset() {
+ DoCleanup();
+ cleanup_.function = nullptr;
+ cleanup_.next = nullptr;
+ }
+
+ inline bool HasCleanups() { return cleanup_.function != nullptr; }
+
+ protected:
+ struct Cleanup {
+ CleanupFunction function;
+ void* arg1;
+ void* arg2;
+ Cleanup* next;
+ };
+ Cleanup cleanup_;
+ // It also becomes the owner of c
+ void RegisterCleanup(Cleanup* c);
+
+ private:
+ // Performs all the cleanups. It does not reset the pointers. Making it
+ // private
+ // to prevent misuse
+ inline void DoCleanup() {
+ if (cleanup_.function != nullptr) {
+ (*cleanup_.function)(cleanup_.arg1, cleanup_.arg2);
+ for (Cleanup* c = cleanup_.next; c != nullptr;) {
+ (*c->function)(c->arg1, c->arg2);
+ Cleanup* next = c->next;
+ delete c;
+ c = next;
+ }
+ }
+ }
+};
+
+// A copyable, reference-counted pointer to a simple Cleanable that only
+// performs registered cleanups after all copies are destroy. This is like
+// shared_ptr<Cleanable> but works more efficiently with wrapping the pointer
+// in an outer Cleanable (see RegisterCopyWith() and MoveAsCleanupTo()).
+// WARNING: if you create a reference cycle, for example:
+// SharedCleanablePtr scp;
+// scp.Allocate();
+// scp.RegisterCopyWith(&*scp);
+// It will prevent cleanups from ever happening!
+class SharedCleanablePtr {
+ public:
+ // Empy/null pointer
+ SharedCleanablePtr() {}
+ // Copy and move constructors and assignment
+ SharedCleanablePtr(const SharedCleanablePtr& from);
+ SharedCleanablePtr(SharedCleanablePtr&& from) noexcept;
+ SharedCleanablePtr& operator=(const SharedCleanablePtr& from);
+ SharedCleanablePtr& operator=(SharedCleanablePtr&& from) noexcept;
+ // Destructor (decrement refcount if non-null)
+ ~SharedCleanablePtr();
+ // Create a new simple Cleanable and make this assign this pointer to it.
+ // (Reset()s first if necessary.)
+ void Allocate();
+ // Reset to empty/null (decrement refcount if previously non-null)
+ void Reset();
+ // Dereference to pointed-to Cleanable
+ Cleanable& operator*();
+ Cleanable* operator->();
+ // Get as raw pointer to Cleanable
+ Cleanable* get();
+
+ // Creates a (virtual) copy of this SharedCleanablePtr and registers its
+ // destruction with target, so that the cleanups registered with the
+ // Cleanable pointed to by this can only happen after the cleanups in the
+ // target Cleanable are run.
+ // No-op if this is empty (nullptr).
+ void RegisterCopyWith(Cleanable* target);
+
+ // Moves (virtually) this shared pointer to a new cleanup in the target.
+ // This is essentilly a move semantics version of RegisterCopyWith(), for
+ // performance optimization. No-op if this is empty (nullptr).
+ void MoveAsCleanupTo(Cleanable* target);
+
+ private:
+ struct Impl;
+ Impl* ptr_ = nullptr;
+};
+
+} // namespace ROCKSDB_NAMESPACE