diff options
author | Anna Henningsen <anna@addaleax.net> | 2020-12-01 21:15:27 +0100 |
---|---|---|
committer | Node.js GitHub Bot <github-bot@iojs.org> | 2020-12-06 01:01:32 +0000 |
commit | 09056633995bd9593efbb244b0d8897678c6c552 (patch) | |
tree | ff7d98b684c737835643a0f7648c92a9e7752431 /test/cctest | |
parent | e929d1f2c8f7d422067983481d7a68dd70a38e5f (diff) | |
download | node-new-09056633995bd9593efbb244b0d8897678c6c552.tar.gz |
vm: add `SafeForTerminationScope`s for SIGINT interruptions
Some embedders, like Electron, choose to start Node.js with
`only_terminate_in_safe_scope` set to `true`. In those cases, parts
of the API that expect execution termination to happen need to
be marked as able to receive those events. In our case, this is
the Ctrl+C support of the `vm` module (and Workers, but since
we’re in control of creating the `Isolate` for them, that’s a
non-concern there).
Add those scopes and add a regression test.
PR-URL: https://github.com/nodejs/node/pull/36344
Reviewed-By: Shelley Vohr <codebytere@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Gus Caplan <me@gus.host>
Diffstat (limited to 'test/cctest')
-rw-r--r-- | test/cctest/test_environment.cc | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc index a6b27e9871..dcd59a22d3 100644 --- a/test/cctest/test_environment.cc +++ b/test/cctest/test_environment.cc @@ -549,3 +549,62 @@ TEST_F(EnvironmentTest, SetImmediateMicrotasks) { EXPECT_EQ(called, 1); } + +#ifndef _WIN32 // No SIGINT on Windows. +TEST_F(NodeZeroIsolateTestFixture, CtrlCWithOnlySafeTerminationTest) { + // We need to go through the whole setup dance here because we want to + // set only_terminate_in_safe_scope. + // Allocate and initialize Isolate. + v8::Isolate::CreateParams create_params; + create_params.array_buffer_allocator = allocator.get(); + create_params.only_terminate_in_safe_scope = true; + v8::Isolate* isolate = v8::Isolate::Allocate(); + CHECK_NOT_NULL(isolate); + platform->RegisterIsolate(isolate, ¤t_loop); + v8::Isolate::Initialize(isolate, create_params); + + // Try creating Context + IsolateData + Environment. + { + v8::Isolate::Scope isolate_scope(isolate); + v8::HandleScope handle_scope(isolate); + + auto context = node::NewContext(isolate); + CHECK(!context.IsEmpty()); + v8::Context::Scope context_scope(context); + + std::unique_ptr<node::IsolateData, decltype(&node::FreeIsolateData)> + isolate_data{node::CreateIsolateData(isolate, + ¤t_loop, + platform.get()), + node::FreeIsolateData}; + CHECK(isolate_data); + + std::unique_ptr<node::Environment, decltype(&node::FreeEnvironment)> + environment{node::CreateEnvironment(isolate_data.get(), + context, + {}, + {}), + node::FreeEnvironment}; + CHECK(environment); + + v8::Local<v8::Value> main_ret = + node::LoadEnvironment(environment.get(), + "'use strict';\n" + "const { runInThisContext } = require('vm');\n" + "try {\n" + " runInThisContext(" + " `process.kill(process.pid, 'SIGINT'); while(true){}`, " + " { breakOnSigint: true });\n" + " return 'unreachable';\n" + "} catch (err) {\n" + " return err.code;\n" + "}").ToLocalChecked(); + node::Utf8Value main_ret_str(isolate, main_ret); + EXPECT_EQ(std::string(*main_ret_str), "ERR_SCRIPT_EXECUTION_INTERRUPTED"); + } + + // Cleanup. + platform->UnregisterIsolate(isolate); + isolate->Dispose(); +} +#endif // _WIN32 |