| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 4c869c8 commit a33cc22
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -232,7 +232,9 @@ inline T* Unwrap(v8::Local<v8::Value> obj) { | |||
| 232 | 232 | // circumstances such as the GC or Environment cleanup. | |
| 233 | 233 | // If weak, destruction behaviour is not affected, but the pointer will be | |
| 234 | 234 | // reset to nullptr once the BaseObject is destroyed. | |
| 235 | - // The API matches std::shared_ptr closely. | ||
| 235 | + // The API matches std::shared_ptr closely. However, this class is not thread | ||
| 236 | + // safe, that is, we can't have different BaseObjectPtrImpl instances in | ||
| 237 | + // different threads refering to the same BaseObject instance. | ||
| 236 | 238 | template <typename T, bool kIsWeak> | |
| 237 | 239 | class BaseObjectPtrImpl final { | |
| 238 | 240 | public: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -771,28 +771,49 @@ void Worker::TakeHeapSnapshot(const FunctionCallbackInfo<Value>& args) { | |||
| 771 | 771 | ->NewInstance(env->context()).ToLocal(&wrap)) { | |
| 772 | 772 | return; | |
| 773 | 773 | } | |
| 774 | - BaseObjectPtr<WorkerHeapSnapshotTaker> taker = | ||
| 775 | - MakeDetachedBaseObject<WorkerHeapSnapshotTaker>(env, wrap); | ||
| 774 | + | ||
| 775 | + // The created WorkerHeapSnapshotTaker is an object owned by main | ||
| 776 | + // thread's Isolate, it can not be accessed by worker thread | ||
| 777 | + std::unique_ptr<BaseObjectPtr<WorkerHeapSnapshotTaker>> taker = | ||
| 778 | + std::make_unique<BaseObjectPtr<WorkerHeapSnapshotTaker>>( | ||
| 779 | + MakeDetachedBaseObject<WorkerHeapSnapshotTaker>(env, wrap)); | ||
| 776 | 780 | ||
| 777 | 781 | // Interrupt the worker thread and take a snapshot, then schedule a call | |
| 778 | 782 | // on the parent thread that turns that snapshot into a readable stream. | |
| 779 | - bool scheduled = w->RequestInterrupt([taker, env](Environment* worker_env) { | ||
| 780 | - heap::HeapSnapshotPointer snapshot { | ||
| 781 | - worker_env->isolate()->GetHeapProfiler()->TakeHeapSnapshot() }; | ||
| 783 | + bool scheduled = w->RequestInterrupt([taker = std::move(taker), | ||
| 784 | + env](Environment* worker_env) mutable { | ||
| 785 | + heap::HeapSnapshotPointer snapshot{ | ||
| 786 | + worker_env->isolate()->GetHeapProfiler()->TakeHeapSnapshot()}; | ||
| 782 | 787 | CHECK(snapshot); | |
| 788 | + | ||
| 789 | + // Here, the worker thread temporarily owns the WorkerHeapSnapshotTaker | ||
| 790 | + // object. | ||
| 791 | + | ||
| 783 | 792 | env->SetImmediateThreadsafe( | |
| 784 | - [taker, snapshot = std::move(snapshot)](Environment* env) mutable { | ||
| 793 | + [taker = std::move(taker), | ||
| 794 | + snapshot = std::move(snapshot)](Environment* env) mutable { | ||
| 785 | 795 | HandleScope handle_scope(env->isolate()); | |
| 786 | 796 | Context::Scope context_scope(env->context()); | |
| 787 | 797 | ||
| 788 | - AsyncHooks::DefaultTriggerAsyncIdScope trigger_id_scope(taker.get()); | ||
| 789 | - BaseObjectPtr<AsyncWrap> stream = heap::CreateHeapSnapshotStream( | ||
| 790 | - env, std::move(snapshot)); | ||
| 791 | - Local<Value> args[] = { stream->object() }; | ||
| 792 | - taker->MakeCallback(env->ondone_string(), arraysize(args), args); | ||
| 793 | - }, CallbackFlags::kUnrefed); | ||
| 798 | + AsyncHooks::DefaultTriggerAsyncIdScope trigger_id_scope(taker->get()); | ||
| 799 | + BaseObjectPtr<AsyncWrap> stream = | ||
| 800 | + heap::CreateHeapSnapshotStream(env, std::move(snapshot)); | ||
| 801 | + Local<Value> args[] = {stream->object()}; | ||
| 802 | + taker->get()->MakeCallback( | ||
| 803 | + env->ondone_string(), arraysize(args), args); | ||
| 804 | + // implicitly delete `taker` | ||
| 805 | + }, | ||
| 806 | + CallbackFlags::kUnrefed); | ||
| 807 | + | ||
| 808 | + // Now, the lambda is delivered to the main thread, as a result, the | ||
| 809 | + // WorkerHeapSnapshotTaker object is delivered to the main thread, too. | ||
| 794 | 810 | }); | |
| 795 | - args.GetReturnValue().Set(scheduled ? taker->object() : Local<Object>()); | ||
| 811 | + | ||
| 812 | + if (scheduled) { | ||
| 813 | + args.GetReturnValue().Set(wrap); | ||
| 814 | + } else { | ||
| 815 | + args.GetReturnValue().Set(Local<Object>()); | ||
| 816 | + } | ||
| 796 | 817 | } | |
| 797 | 818 | ||
| 798 | 819 | void Worker::LoopIdleTime(const FunctionCallbackInfo<Value>& args) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments