/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
v26.2.0
src/node_locks.h
184 строки
5 KB
James M Snell
src: make additional cleanups in node locks impl
11 окт 2025, 18:11
11 окт 2025, 18:11
a1244f0
Код
Авторство
О чём код?
#ifndef SRC_NODE_LOCKS_H_ #define SRC_NODE_LOCKS_H_ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #include <deque> #include <string> #include <unordered_map> #include <unordered_set> #include "base_object.h" #include "env.h" #include "node_mutex.h" #include "v8.h" namespace node::worker::locks { class Lock final : public MemoryRetainer { public: enum class Mode { Shared, Exclusive }; Lock(Environment* env, const std::u16string& name, Mode mode, const std::string& client_id, v8::Local<v8::Promise::Resolver> waiting, v8::Local<v8::Promise::Resolver> released); ~Lock() = default; Lock(const Lock&) = delete; Lock& operator=(const Lock&) = delete; // Resource name for this lock as DOMString const std::u16string& name() const { return name_; } // Lock mode (shared or exclusive). Mode mode() const { return mode_; } // Client identifier string. const std::string& client_id() const { return client_id_; } // Environment that owns this lock. Environment* env() const { return env_; } // Returns true if this lock was stolen by another request. bool is_stolen() const { return stolen_; } // Marks this lock as stolen. void mark_stolen() { stolen_ = true; } // Promise that resolves when the user callback completes. v8::Local<v8::Promise::Resolver> waiting_promise() { return waiting_promise_.Get(env_->isolate()); } // Promise that resolves when the lock is finally released. v8::Local<v8::Promise::Resolver> released_promise() { return released_promise_.Get(env_->isolate()); } void MemoryInfo(node::MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(Lock) SET_SELF_SIZE(Lock) private: Environment* env_; std::u16string name_; Mode mode_; std::string client_id_; bool stolen_ = false; v8::Global<v8::Promise::Resolver> waiting_promise_; v8::Global<v8::Promise::Resolver> released_promise_; }; class LockHolder final : public BaseObject { public: LockHolder(Environment* env, v8::Local<v8::Object> obj, std::shared_ptr<Lock> lock) : BaseObject(env, obj), lock_(std::move(lock)) { MakeWeak(); } ~LockHolder() = default; LockHolder(const LockHolder&) = delete; LockHolder& operator=(const LockHolder&) = delete; std::shared_ptr<Lock> lock() const { return lock_; } void MemoryInfo(node::MemoryTracker* tracker) const override; SET_MEMORY_INFO_NAME(LockHolder) SET_SELF_SIZE(LockHolder) static BaseObjectPtr<LockHolder> Create(Environment* env, std::shared_ptr<Lock> lock); private: static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( Environment* env); std::shared_ptr<Lock> lock_; }; class LockRequest final { public: LockRequest(Environment* env, v8::Local<v8::Promise::Resolver> waiting, v8::Local<v8::Promise::Resolver> released, v8::Local<v8::Function> callback, const std::u16string& name, Lock::Mode mode, std::string client_id, bool steal, bool if_available); ~LockRequest() = default; LockRequest(const LockRequest&) = delete; LockRequest& operator=(const LockRequest&) = delete; const std::u16string& name() const { return name_; } Lock::Mode mode() const { return mode_; } const std::string& client_id() const { return client_id_; } bool steal() const { return steal_; } // Returns true if this is an ifAvailable request. bool if_available() const { return if_available_; } Environment* env() const { return env_; } v8::Local<v8::Promise::Resolver> waiting_promise() { return waiting_promise_.Get(env_->isolate()); } v8::Local<v8::Promise::Resolver> released_promise() { return released_promise_.Get(env_->isolate()); } v8::Local<v8::Function> callback() { return callback_.Get(env_->isolate()); } private: Environment* env_; std::u16string name_; Lock::Mode mode_; std::string client_id_; bool steal_; bool if_available_; v8::Global<v8::Promise::Resolver> waiting_promise_; v8::Global<v8::Promise::Resolver> released_promise_; v8::Global<v8::Function> callback_; }; class LockManager final { public: static void Request(const v8::FunctionCallbackInfo<v8::Value>& args); static void Query(const v8::FunctionCallbackInfo<v8::Value>& args); void ProcessQueue(Environment* env); void CleanupEnvironment(Environment* env); static void OnEnvironmentCleanup(void* arg); static LockManager* GetCurrent() { return ¤t_; } void ReleaseLockAndProcessQueue(Environment* env, std::shared_ptr<Lock> lock, v8::Local<v8::Value> result, bool was_rejected = false); private: LockManager() = default; ~LockManager() = default; LockManager(const LockManager&) = delete; LockManager& operator=(const LockManager&) = delete; bool IsGrantable(const LockRequest* req) const; void CleanupStolenLocks(Environment* env); void ReleaseLock(Lock* lock); void WakeEnvironment(Environment* env); static LockManager current_; mutable Mutex mutex_; // All entries for a given Environment* are purged in CleanupEnvironment(). std::unordered_map<std::u16string, std::deque<std::shared_ptr<Lock>>> held_locks_; std::deque<std::unique_ptr<LockRequest>> pending_queue_; std::unordered_set<Environment*> registered_envs_; }; } // namespace node::worker::locks #endif // NODE_WANT_INTERNALS #endif // SRC_NODE_LOCKS_H_