fork of https://github.com/rust-rocksdb/rust-rocksdb for nextgraph
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
4.3 KiB
129 lines
4.3 KiB
1 year ago
|
// 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
|