From 322e9b6ed1253c38bf2b6b86282c978dd7113580 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Sun, 14 Apr 2019 17:46:52 +0800 Subject: [PATCH] src: split per-process initialization and teardown routines This patch makes it possible to instantiate NodeMainInstance in a separate target and use it to e.g. create snapshot. --- src/node.cc | 46 ++++++++++++++++++++++++++++++-------------- src/node_internals.h | 9 +++++++++ 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/node.cc b/src/node.cc index 53a9ae397bf20b..a44d045948c4bd 100644 --- a/src/node.cc +++ b/src/node.cc @@ -752,7 +752,7 @@ void Init(int* argc, argv[i] = strdup(argv_[i].c_str()); } -int Start(int argc, char** argv) { +InitializationResult InitializeOncePerProcess(int argc, char** argv) { atexit([] () { uv_tty_reset_mode(); }); PlatformInit(); per_process::node_start_time = uv_hrtime(); @@ -770,20 +770,27 @@ int Start(int argc, char** argv) { // Hack around with the argv pointer. Used for process.title = "blah". argv = uv_setup_args(argc, argv); - std::vector args(argv, argv + argc); - std::vector exec_args; + InitializationResult result; + result.args = std::vector(argv, argv + argc); std::vector errors; + // This needs to run *before* V8::Initialize(). { - const int exit_code = InitializeNodeWithArgs(&args, &exec_args, &errors); + result.exit_code = + InitializeNodeWithArgs(&(result.args), &(result.exec_args), &errors); for (const std::string& error : errors) - fprintf(stderr, "%s: %s\n", args.at(0).c_str(), error.c_str()); - if (exit_code != 0) return exit_code; + fprintf(stderr, "%s: %s\n", result.args.at(0).c_str(), error.c_str()); + if (result.exit_code != 0) { + result.early_return = true; + return result; + } } if (per_process::cli_options->print_version) { printf("%s\n", NODE_VERSION); - return 0; + result.exit_code = 0; + result.early_return = true; + return result; } if (per_process::cli_options->print_v8_help) { @@ -811,13 +818,10 @@ int Start(int argc, char** argv) { V8::Initialize(); performance::performance_v8_start = PERFORMANCE_NOW(); per_process::v8_initialized = true; + return result; +} - int exit_code = 0; - { - NodeMainInstance main_instance(uv_default_loop(), args, exec_args); - exit_code = main_instance.Run(); - } - +void TearDownOncePerProcess() { per_process::v8_initialized = false; V8::Dispose(); @@ -828,8 +832,22 @@ int Start(int argc, char** argv) { // Since uv_run cannot be called, uv_async handles held by the platform // will never be fully cleaned up. per_process::v8_platform.Dispose(); +} + +int Start(int argc, char** argv) { + InitializationResult result = InitializeOncePerProcess(argc, argv); + if (result.early_return) { + return result.exit_code; + } + + { + NodeMainInstance main_instance( + uv_default_loop(), result.args, result.exec_args); + result.exit_code = main_instance.Run(); + } - return exit_code; + TearDownOncePerProcess(); + return result.exit_code; } int Stop(Environment* env) { diff --git a/src/node_internals.h b/src/node_internals.h index 53f7d3cdbad237..ef6195ef3b9570 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -311,6 +311,15 @@ v8::MaybeLocal ExecuteBootstrapper( std::vector>* arguments); void MarkBootstrapComplete(const v8::FunctionCallbackInfo& args); +struct InitializationResult { + int exit_code = 0; + std::vector args; + std::vector exec_args; + bool early_return = false; +}; +InitializationResult InitializeOncePerProcess(int argc, char** argv); +void TearDownOncePerProcess(); + #if HAVE_INSPECTOR namespace profiler { void StartCoverageCollection(Environment* env);