22
33#include " base_object-inl.h"
44#include " env-inl.h"
5+ #include " node_debug.h"
56#include " node_errors.h"
67#include " node_external_reference.h"
78#include " node_internals.h"
@@ -237,8 +238,8 @@ void LockManager::ProcessQueue(Environment* env) {
237238 * 1- Build first_seen_for_resource: the oldest pending request
238239 * for every resource name we encounter
239240 * 2- Decide what to do with each entry:
240- * – If it belongs to another Environment, remember that env so we
241- * can wake it later
241+ * – If it belongs to another Environment, remember that env only if
242+ * the request can make progress
242243 * – For our Environment, pick one of:
243244 * * grantable_request – can be granted now
244245 * * if_available_request – user asked for ifAvailable and the
@@ -255,11 +256,6 @@ void LockManager::ProcessQueue(Environment* env) {
255256 ++queue_iter) {
256257 LockRequest* request = queue_iter->get ();
257258
258- // Collect unique environments to wake up later
259- if (request->env () != env) {
260- other_envs_to_wake.insert (request->env ());
261- }
262-
263259 // During a single pass, the first time we see a resource name is the
264260 // earliest pending request
265261 auto & first_for_resource = first_seen_for_resource[request->name ()];
@@ -283,12 +279,21 @@ void LockManager::ProcessQueue(Environment* env) {
283279 // If both are shared, they're compatible and can proceed
284280 }
285281
286- // Only process requests from the current environment
282+ bool is_grantable =
283+ !should_wait_for_earlier_requests && IsGrantable (request);
284+
285+ // Requests must be processed on their Environment's event loop. Wake
286+ // another Environment only when it has a request that can make
287+ // progress; otherwise blocked Environments would continuously wake
288+ // each other.
287289 if (request->env () != env) {
290+ if (is_grantable || request->if_available ()) {
291+ other_envs_to_wake.insert (request->env ());
292+ }
288293 continue ;
289294 }
290295
291- if (should_wait_for_earlier_requests || ! IsGrantable (request) ) {
296+ if (!is_grantable ) {
292297 if (request->if_available ()) {
293298 // ifAvailable request when resource not available: grant with null
294299 if_available_request = std::move (*queue_iter);
@@ -754,6 +759,8 @@ void LockManager::ReleaseLock(Lock* lock) {
754759void LockManager::WakeEnvironment (Environment* target_env) {
755760 if (target_env == nullptr || target_env->is_stopping ()) return ;
756761
762+ COUNT_GENERIC_USAGE (" LockManager.WakeEnvironment" );
763+
757764 // Schedule ProcessQueue in the target Environment on its event loop.
758765 target_env->SetImmediateThreadsafe ([](Environment* env_to_wake) {
759766 if (env_to_wake != nullptr && !env_to_wake->is_stopping ()) {
0 commit comments