v8::Locker 退出 Isolate 中的当前 Context
v8::Locker exits current Context in Isolate
我正在尝试将 V8 嵌入到多线程应用程序中。我的计划是在当前需要执行 JS 代码的任何线程中内联执行 V8 代码。
因此,在我的执行上下文中,我正在获取 v8::Locker
并在 random 线程中输入 Isolate。我注意到在获取 v8::Locker
时,隔离 丢失 它是 CurrentContext。
在下面的代码片段中,我将其归结为问题的本质。如果我 Enter
在 v8::Locker 下的上下文,退出那个锁柜并进入一个新的锁柜,则 Isolate 将失去其上下文。请注意,我从未明确 Exit
上下文。
这是正确的用法吗?我错过了什么吗?
在下面的代码片段中,您可以看到问题的单线程虚拟示例。
断言 1 和 2 通过并断言 3 失败。
v8::V8::InitializeICU(V8_ICU_FILE);
v8::V8::InitializeExternalStartupData(V8_SNAPSHOT_BIN_FILE);
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
// Create a new Isolate and make it the current one.
v8::Isolate::CreateParams create_params;
auto allocator = std::unique_ptr<v8::ArrayBuffer::Allocator>(v8::ArrayBuffer::Allocator::NewDefaultAllocator());
create_params.array_buffer_allocator = allocator.get();
v8::Isolate* isolate = v8::Isolate::New(create_params);
v8::HandleScope handle_scope(isolate);
// Create a new context.
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
global->Set(isolate, "log", v8::FunctionTemplate::New(isolate, logCallback));
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);
// Enter the context for compiling and running the hello world script.
{
v8::Locker locker(isolate);
v8::Isolate::Scope scope(isolate);
context->Enter(); // Explicitly Enter the context (Which makes it the CurrentContext)
assert(!isolate->GetCurrentContext().IsEmpty()); // 1 - Succeeds
isolate->Exit();
isolate->Enter();
assert(!isolate->GetCurrentContext().IsEmpty()); // 2 - Succeeds
}
{
v8::Locker locker(isolate);
v8::Isolate::Scope scope(isolate);
assert(!isolate->GetCurrentContext().IsEmpty()); // 3 - Assertion Fails
}
// Create a string containing the JavaScript source code.
isolate->Dispose();
v8::V8::Dispose();
v8::V8::ShutdownPlatform();
v8::Locker
析构函数假定当前线程已完成其正在执行的所有操作并随后进行清理;特别是这意味着它取消了当前上下文。在下一个线程上创建下一个储物柜后,您必须(重新)输入正确的上下文。 v8::Context::Scope
让这变得很方便。
我正在尝试将 V8 嵌入到多线程应用程序中。我的计划是在当前需要执行 JS 代码的任何线程中内联执行 V8 代码。
因此,在我的执行上下文中,我正在获取 v8::Locker
并在 random 线程中输入 Isolate。我注意到在获取 v8::Locker
时,隔离 丢失 它是 CurrentContext。
在下面的代码片段中,我将其归结为问题的本质。如果我 Enter
在 v8::Locker 下的上下文,退出那个锁柜并进入一个新的锁柜,则 Isolate 将失去其上下文。请注意,我从未明确 Exit
上下文。
这是正确的用法吗?我错过了什么吗?
在下面的代码片段中,您可以看到问题的单线程虚拟示例。 断言 1 和 2 通过并断言 3 失败。
v8::V8::InitializeICU(V8_ICU_FILE);
v8::V8::InitializeExternalStartupData(V8_SNAPSHOT_BIN_FILE);
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
// Create a new Isolate and make it the current one.
v8::Isolate::CreateParams create_params;
auto allocator = std::unique_ptr<v8::ArrayBuffer::Allocator>(v8::ArrayBuffer::Allocator::NewDefaultAllocator());
create_params.array_buffer_allocator = allocator.get();
v8::Isolate* isolate = v8::Isolate::New(create_params);
v8::HandleScope handle_scope(isolate);
// Create a new context.
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
global->Set(isolate, "log", v8::FunctionTemplate::New(isolate, logCallback));
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);
// Enter the context for compiling and running the hello world script.
{
v8::Locker locker(isolate);
v8::Isolate::Scope scope(isolate);
context->Enter(); // Explicitly Enter the context (Which makes it the CurrentContext)
assert(!isolate->GetCurrentContext().IsEmpty()); // 1 - Succeeds
isolate->Exit();
isolate->Enter();
assert(!isolate->GetCurrentContext().IsEmpty()); // 2 - Succeeds
}
{
v8::Locker locker(isolate);
v8::Isolate::Scope scope(isolate);
assert(!isolate->GetCurrentContext().IsEmpty()); // 3 - Assertion Fails
}
// Create a string containing the JavaScript source code.
isolate->Dispose();
v8::V8::Dispose();
v8::V8::ShutdownPlatform();
v8::Locker
析构函数假定当前线程已完成其正在执行的所有操作并随后进行清理;特别是这意味着它取消了当前上下文。在下一个线程上创建下一个储物柜后,您必须(重新)输入正确的上下文。 v8::Context::Scope
让这变得很方便。