Files
node/src/cleanup_queue.h
T
legendecas 0b5b5edd86 src: consolidate environment cleanup queue
Each Realm tracks its own cleanup hooks and drains the hooks when it is
going to be destroyed.

Moves the implementations of the cleanup queue to its own class so that
it can be used in `node::Realm` too.

PR-URL: https://github.com/nodejs/node/pull/44379
Refs: https://github.com/nodejs/node/pull/44348
Refs: https://github.com/nodejs/node/issues/42528
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2022-09-08 00:06:47 +08:00

84 lines
2.1 KiB
C++

#ifndef SRC_CLEANUP_QUEUE_H_
#define SRC_CLEANUP_QUEUE_H_
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#include <cstddef>
#include <cstdint>
#include <unordered_set>
#include "memory_tracker.h"
namespace node {
class BaseObject;
class CleanupQueue : public MemoryRetainer {
public:
typedef void (*Callback)(void*);
CleanupQueue() {}
// Not copyable.
CleanupQueue(const CleanupQueue&) = delete;
SET_MEMORY_INFO_NAME(CleanupQueue)
inline void MemoryInfo(node::MemoryTracker* tracker) const override;
inline size_t SelfSize() const override;
inline bool empty() const;
inline void Add(Callback cb, void* arg);
inline void Remove(Callback cb, void* arg);
void Drain();
template <typename T>
inline void ForEachBaseObject(T&& iterator) const;
private:
class CleanupHookCallback {
public:
CleanupHookCallback(Callback fn,
void* arg,
uint64_t insertion_order_counter)
: fn_(fn),
arg_(arg),
insertion_order_counter_(insertion_order_counter) {}
// Only hashes `arg_`, since that is usually enough to identify the hook.
struct Hash {
size_t operator()(const CleanupHookCallback& cb) const;
};
// Compares by `fn_` and `arg_` being equal.
struct Equal {
bool operator()(const CleanupHookCallback& a,
const CleanupHookCallback& b) const;
};
private:
friend class CleanupQueue;
Callback fn_;
void* arg_;
// We keep track of the insertion order for these objects, so that we can
// call the callbacks in reverse order when we are cleaning up.
uint64_t insertion_order_counter_;
};
inline BaseObject* GetBaseObject(const CleanupHookCallback& callback) const;
// Use an unordered_set, so that we have efficient insertion and removal.
std::unordered_set<CleanupHookCallback,
CleanupHookCallback::Hash,
CleanupHookCallback::Equal>
cleanup_hooks_;
uint64_t cleanup_hook_counter_ = 0;
};
} // namespace node
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#endif // SRC_CLEANUP_QUEUE_H_