| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f3563d3 commit e404841
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -493,8 +493,8 @@ static void EnablePromiseHook(const FunctionCallbackInfo<Value>& args) { | |||
| 493 | 493 | ||
| 494 | 494 | static void SetPromiseHooks(const FunctionCallbackInfo<Value>& args) { | |
| 495 | 495 | Environment* env = Environment::GetCurrent(args); | |
| 496 | - Local<Context> ctx = env->context(); | ||
| 497 | - ctx->SetPromiseHooks( | ||
| 496 | + | ||
| 497 | + env->async_hooks()->SetJSPromiseHooks( | ||
| 498 | 498 | args[0]->IsFunction() ? args[0].As<Function>() : Local<Function>(), | |
| 499 | 499 | args[1]->IsFunction() ? args[1].As<Function>() : Local<Function>(), | |
| 500 | 500 | args[2]->IsFunction() ? args[2].As<Function>() : Local<Function>(), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -118,6 +118,20 @@ v8::Local<v8::Object> AsyncHooks::native_execution_async_resource(size_t i) { | |||
| 118 | 118 | return PersistentToLocal::Strong(native_execution_async_resources_[i]); | |
| 119 | 119 | } | |
| 120 | 120 | ||
| 121 | + inline void AsyncHooks::SetJSPromiseHooks(v8::Local<v8::Function> init, | ||
| 122 | + v8::Local<v8::Function> before, | ||
| 123 | + v8::Local<v8::Function> after, | ||
| 124 | + v8::Local<v8::Function> resolve) { | ||
| 125 | + js_promise_hooks_[0].Reset(env()->isolate(), init); | ||
| 126 | + js_promise_hooks_[1].Reset(env()->isolate(), before); | ||
| 127 | + js_promise_hooks_[2].Reset(env()->isolate(), after); | ||
| 128 | + js_promise_hooks_[3].Reset(env()->isolate(), resolve); | ||
| 129 | + for (auto it = contexts_.begin(); it != contexts_.end(); it++) { | ||
| 130 | + PersistentToLocal::Weak(env()->isolate(), *it) | ||
| 131 | + ->SetPromiseHooks(init, before, after, resolve); | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + | ||
| 121 | 135 | inline v8::Local<v8::String> AsyncHooks::provider_string(int idx) { | |
| 122 | 136 | return env()->isolate_data()->async_wrap_provider(idx); | |
| 123 | 137 | } | |
@@ -240,6 +254,41 @@ void AsyncHooks::clear_async_id_stack() { | |||
| 240 | 254 | fields_[kStackLength] = 0; | |
| 241 | 255 | } | |
| 242 | 256 | ||
| 257 | + inline void AsyncHooks::AddContext(v8::Local<v8::Context> ctx) { | ||
| 258 | + ctx->SetPromiseHooks( | ||
| 259 | + js_promise_hooks_[0].IsEmpty() ? | ||
| 260 | + v8::Local<v8::Function>() : | ||
| 261 | + PersistentToLocal::Strong(js_promise_hooks_[0]), | ||
| 262 | + js_promise_hooks_[1].IsEmpty() ? | ||
| 263 | + v8::Local<v8::Function>() : | ||
| 264 | + PersistentToLocal::Strong(js_promise_hooks_[1]), | ||
| 265 | + js_promise_hooks_[2].IsEmpty() ? | ||
| 266 | + v8::Local<v8::Function>() : | ||
| 267 | + PersistentToLocal::Strong(js_promise_hooks_[2]), | ||
| 268 | + js_promise_hooks_[3].IsEmpty() ? | ||
| 269 | + v8::Local<v8::Function>() : | ||
| 270 | + PersistentToLocal::Strong(js_promise_hooks_[3])); | ||
| 271 | + | ||
| 272 | + size_t id = contexts_.size(); | ||
| 273 | + contexts_.resize(id + 1); | ||
| 274 | + contexts_[id].Reset(env()->isolate(), ctx); | ||
| 275 | + contexts_[id].SetWeak(); | ||
| 276 | + } | ||
| 277 | + | ||
| 278 | + inline void AsyncHooks::RemoveContext(v8::Local<v8::Context> ctx) { | ||
| 279 | + v8::Isolate* isolate = env()->isolate(); | ||
| 280 | + v8::HandleScope handle_scope(isolate); | ||
| 281 | + for (auto it = contexts_.begin(); it != contexts_.end(); it++) { | ||
| 282 | + v8::Local<v8::Context> saved_context = | ||
| 283 | + PersistentToLocal::Weak(env()->isolate(), *it); | ||
| 284 | + if (saved_context == ctx) { | ||
| 285 | + it->Reset(); | ||
| 286 | + contexts_.erase(it); | ||
| 287 | + break; | ||
| 288 | + } | ||
| 289 | + } | ||
| 290 | + } | ||
| 291 | + | ||
| 243 | 292 | // The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in | |
| 244 | 293 | // async_wrap-inl.h to avoid a circular dependency. | |
| 245 | 294 | ||
@@ -333,6 +382,8 @@ inline void Environment::AssignToContext(v8::Local<v8::Context> context, | |||
| 333 | 382 | #if HAVE_INSPECTOR | |
| 334 | 383 | inspector_agent()->ContextCreated(context, info); | |
| 335 | 384 | #endif // HAVE_INSPECTOR | |
| 385 | + | ||
| 386 | + this->async_hooks()->AddContext(context); | ||
| 336 | 387 | } | |
| 337 | 388 | ||
| 338 | 389 | inline Environment* Environment::GetCurrent(v8::Isolate* isolate) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -997,6 +997,7 @@ void AsyncHooks::MemoryInfo(MemoryTracker* tracker) const { | |||
| 997 | 997 | tracker->TrackField("async_ids_stack", async_ids_stack_); | |
| 998 | 998 | tracker->TrackField("fields", fields_); | |
| 999 | 999 | tracker->TrackField("async_id_fields", async_id_fields_); | |
| 1000 | + tracker->TrackField("js_promise_hooks", js_promise_hooks_); | ||
| 1000 | 1001 | } | |
| 1001 | 1002 | ||
| 1002 | 1003 | void AsyncHooks::grow_async_ids_stack() { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -648,6 +648,11 @@ class AsyncHooks : public MemoryRetainer { | |||
| 648 | 648 | // The `js_execution_async_resources` array contains the value in that case. | |
| 649 | 649 | inline v8::Local<v8::Object> native_execution_async_resource(size_t index); | |
| 650 | 650 | ||
| 651 | + inline void SetJSPromiseHooks(v8::Local<v8::Function> init, | ||
| 652 | + v8::Local<v8::Function> before, | ||
| 653 | + v8::Local<v8::Function> after, | ||
| 654 | + v8::Local<v8::Function> resolve); | ||
| 655 | + | ||
| 651 | 656 | inline v8::Local<v8::String> provider_string(int idx); | |
| 652 | 657 | ||
| 653 | 658 | inline void no_force_checks(); | |
@@ -658,6 +663,9 @@ class AsyncHooks : public MemoryRetainer { | |||
| 658 | 663 | inline bool pop_async_context(double async_id); | |
| 659 | 664 | inline void clear_async_id_stack(); // Used in fatal exceptions. | |
| 660 | 665 | ||
| 666 | + inline void AddContext(v8::Local<v8::Context> ctx); | ||
| 667 | + inline void RemoveContext(v8::Local<v8::Context> ctx); | ||
| 668 | + | ||
| 661 | 669 | AsyncHooks(const AsyncHooks&) = delete; | |
| 662 | 670 | AsyncHooks& operator=(const AsyncHooks&) = delete; | |
| 663 | 671 | AsyncHooks(AsyncHooks&&) = delete; | |
@@ -701,6 +709,10 @@ class AsyncHooks : public MemoryRetainer { | |||
| 701 | 709 | ||
| 702 | 710 | v8::Global<v8::Array> js_execution_async_resources_; | |
| 703 | 711 | std::vector<v8::Global<v8::Object>> native_execution_async_resources_; | |
| 712 | + | ||
| 713 | + std::vector<v8::Global<v8::Context>> contexts_; | ||
| 714 | + | ||
| 715 | + std::array<v8::Global<v8::Function>, 4> js_promise_hooks_; | ||
| 704 | 716 | }; | |
| 705 | 717 | ||
| 706 | 718 | class ImmediateInfo : public MemoryRetainer { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -127,6 +127,11 @@ ContextifyContext::ContextifyContext( | |||
| 127 | 127 | ||
| 128 | 128 | ContextifyContext::~ContextifyContext() { | |
| 129 | 129 | env()->RemoveCleanupHook(CleanupHook, this); | |
| 130 | + Isolate* isolate = env()->isolate(); | ||
| 131 | + HandleScope scope(isolate); | ||
| 132 | + | ||
| 133 | + env()->async_hooks() | ||
| 134 | + ->RemoveContext(PersistentToLocal::Weak(isolate, context_)); | ||
| 130 | 135 | } | |
| 131 | 136 | ||
| 132 | 137 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,35 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const vm = require('vm'); | ||
| 6 | + const { AsyncLocalStorage } = require('async_hooks'); | ||
| 7 | + | ||
| 8 | + // Regression test for https://github.com/nodejs/node/issues/38781 | ||
| 9 | + | ||
| 10 | + const context = vm.createContext({ | ||
| 11 | + AsyncLocalStorage, | ||
| 12 | + assert | ||
| 13 | + }); | ||
| 14 | + | ||
| 15 | + vm.runInContext(` | ||
| 16 | + const storage = new AsyncLocalStorage() | ||
| 17 | + async function test() { | ||
| 18 | + return storage.run({ test: 'vm' }, async () => { | ||
| 19 | + assert.strictEqual(storage.getStore().test, 'vm'); | ||
| 20 | + await 42; | ||
| 21 | + assert.strictEqual(storage.getStore().test, 'vm'); | ||
| 22 | + }); | ||
| 23 | + } | ||
| 24 | + test() | ||
| 25 | + `, context); | ||
| 26 | + | ||
| 27 | + const storage = new AsyncLocalStorage(); | ||
| 28 | + async function test() { | ||
| 29 | + return storage.run({ test: 'main context' }, async () => { | ||
| 30 | + assert.strictEqual(storage.getStore().test, 'main context'); | ||
| 31 | + await 42; | ||
| 32 | + assert.strictEqual(storage.getStore().test, 'main context'); | ||
| 33 | + }); | ||
| 34 | + } | ||
| 35 | + test(); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments