-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
src: move per-process global variables into node::per_process #25302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
So that it's easier to tell whether we are manipulating per-process global states that may need to be treated with care to avoid races. Also added comments about these variables and moved some of them to a more suitable compilation unit: - Move `v8_initialized` to `util.h` since it's only used in `util.cc` and `node.cc` - Rename `process_mutex` to `tty_mutex` and move it into `node_errors.cc` since that's the only place it's used to guard the tty. - Move `per_process_opts_mutex` and `per_process_opts` into `node_options.h` and rename them to `per_process::cli_options[_mutex]` - Rename `node_isolate[_mutex]` to `per_process::main_isolate[_mutex]`
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -139,21 +139,28 @@ using v8::Undefined; | |
| using v8::V8; | ||
| using v8::Value; | ||
|
|
||
| namespace per_process { | ||
| // Tells whether --prof is passed. | ||
| // TODO(joyeecheung): replace this with env->options()->prof_process | ||
| static bool v8_is_profiling = false; | ||
|
|
||
| // Bit flag used to track security reverts (see node_revert.h) | ||
| unsigned int reverted = 0; | ||
| // Isolate on the main thread | ||
| static Mutex main_isolate_mutex; | ||
| static Isolate* main_isolate; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these actually consumed anywhere? It looks like we should remove this entirely…
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think they are used to check that someone don't call
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| // node_revert.h | ||
| // Bit flag used to track security reverts. | ||
| unsigned int reverted_cve = 0; | ||
|
|
||
| // util.h | ||
| // Tells whether the per-process V8::Initialize() is called and | ||
| // if it is safe to call v8::Isolate::GetCurrent(). | ||
| bool v8_initialized = false; | ||
|
|
||
| // node_internals.h | ||
| // process-relative uptime base, initialized at start-up | ||
| double prog_start_time; | ||
|
|
||
| Mutex per_process_opts_mutex; | ||
| std::shared_ptr<PerProcessOptions> per_process_opts { | ||
| new PerProcessOptions() }; | ||
| static Mutex node_isolate_mutex; | ||
| static Isolate* node_isolate; | ||
| } // namespace per_process | ||
|
|
||
| // Ensures that __metadata trace events are only emitted | ||
| // when tracing is enabled. | ||
|
|
@@ -265,14 +272,15 @@ static struct { | |
| #endif // HAVE_INSPECTOR | ||
|
|
||
| void StartTracingAgent() { | ||
| if (per_process_opts->trace_event_categories.empty()) { | ||
| if (per_process::cli_options->trace_event_categories.empty()) { | ||
| tracing_file_writer_ = tracing_agent_->DefaultHandle(); | ||
| } else { | ||
| tracing_file_writer_ = tracing_agent_->AddClient( | ||
| ParseCommaSeparatedSet(per_process_opts->trace_event_categories), | ||
| ParseCommaSeparatedSet( | ||
| per_process::cli_options->trace_event_categories), | ||
| std::unique_ptr<tracing::AsyncTraceWriter>( | ||
| new tracing::NodeTraceWriter( | ||
| per_process_opts->trace_event_file_pattern)), | ||
| per_process::cli_options->trace_event_file_pattern)), | ||
| tracing::Agent::kUseDefaultCategories); | ||
| } | ||
| } | ||
|
|
@@ -496,7 +504,7 @@ const char* signo_string(int signo) { | |
| } | ||
|
|
||
| void* ArrayBufferAllocator::Allocate(size_t size) { | ||
| if (zero_fill_field_ || per_process_opts->zero_fill_all_buffers) | ||
| if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers) | ||
| return UncheckedCalloc(size); | ||
| else | ||
| return UncheckedMalloc(size); | ||
|
|
@@ -1271,12 +1279,12 @@ void ProcessArgv(std::vector<std::string>* args, | |
| { | ||
| // TODO(addaleax): The mutex here should ideally be held during the | ||
| // entire function, but that doesn't play well with the exit() calls below. | ||
| Mutex::ScopedLock lock(per_process_opts_mutex); | ||
| Mutex::ScopedLock lock(per_process::cli_options_mutex); | ||
| options_parser::PerProcessOptionsParser::instance.Parse( | ||
| args, | ||
| exec_args, | ||
| &v8_args, | ||
| per_process_opts.get(), | ||
| per_process::cli_options.get(), | ||
| is_env ? kAllowedInEnvironment : kDisallowedInEnvironment, | ||
| &errors); | ||
| } | ||
|
|
@@ -1288,20 +1296,20 @@ void ProcessArgv(std::vector<std::string>* args, | |
| exit(9); | ||
| } | ||
|
|
||
| if (per_process_opts->print_version) { | ||
| if (per_process::cli_options->print_version) { | ||
| printf("%s\n", NODE_VERSION); | ||
| exit(0); | ||
| } | ||
|
|
||
| if (per_process_opts->print_v8_help) { | ||
| if (per_process::cli_options->print_v8_help) { | ||
| V8::SetFlagsFromString("--help", 6); | ||
| exit(0); | ||
| } | ||
|
|
||
| for (const std::string& cve : per_process_opts->security_reverts) | ||
| for (const std::string& cve : per_process::cli_options->security_reverts) | ||
| Revert(cve.c_str()); | ||
|
|
||
| auto env_opts = per_process_opts->per_isolate->per_env; | ||
| auto env_opts = per_process::cli_options->per_isolate->per_env; | ||
| if (std::find(v8_args.begin(), v8_args.end(), | ||
| "--abort-on-uncaught-exception") != v8_args.end() || | ||
| std::find(v8_args.begin(), v8_args.end(), | ||
|
|
@@ -1314,14 +1322,14 @@ void ProcessArgv(std::vector<std::string>* args, | |
| // behavior but it could also interfere with the user's intentions in ways | ||
| // we fail to anticipate. Dillema. | ||
| if (std::find(v8_args.begin(), v8_args.end(), "--prof") != v8_args.end()) { | ||
| v8_is_profiling = true; | ||
| per_process::v8_is_profiling = true; | ||
| } | ||
|
|
||
| #ifdef __POSIX__ | ||
| // Block SIGPROF signals when sleeping in epoll_wait/kevent/etc. Avoids the | ||
| // performance penalty of frequent EINTR wakeups when the profiler is running. | ||
| // Only do this for v8.log profiling, as it breaks v8::CpuProfiler users. | ||
| if (v8_is_profiling) { | ||
| if (per_process::v8_is_profiling) { | ||
| uv_loop_configure(uv_default_loop(), UV_LOOP_BLOCK_SIGNAL, SIGPROF); | ||
| } | ||
| #endif | ||
|
|
@@ -1350,7 +1358,7 @@ void ProcessArgv(std::vector<std::string>* args, | |
| void Init(std::vector<std::string>* argv, | ||
| std::vector<std::string>* exec_argv) { | ||
| // Initialize prog_start_time to get relative uptime. | ||
| prog_start_time = static_cast<double>(uv_now(uv_default_loop())); | ||
| per_process::prog_start_time = static_cast<double>(uv_now(uv_default_loop())); | ||
|
|
||
| // Register built-in modules | ||
| binding::RegisterBuiltinModules(); | ||
|
|
@@ -1366,7 +1374,7 @@ void Init(std::vector<std::string>* argv, | |
| #endif | ||
|
|
||
| std::shared_ptr<EnvironmentOptions> default_env_options = | ||
| per_process_opts->per_isolate->per_env; | ||
| per_process::cli_options->per_isolate->per_env; | ||
| { | ||
| std::string text; | ||
| default_env_options->pending_deprecation = | ||
|
|
@@ -1395,7 +1403,7 @@ void Init(std::vector<std::string>* argv, | |
| } | ||
|
|
||
| #if HAVE_OPENSSL | ||
| std::string* openssl_config = &per_process_opts->openssl_config; | ||
| std::string* openssl_config = &per_process::cli_options->openssl_config; | ||
| if (openssl_config->empty()) { | ||
| credentials::SafeGetenv("OPENSSL_CONF", openssl_config); | ||
| } | ||
|
|
@@ -1429,16 +1437,17 @@ void Init(std::vector<std::string>* argv, | |
| ProcessArgv(argv, exec_argv, false); | ||
|
|
||
| // Set the process.title immediately after processing argv if --title is set. | ||
| if (!per_process_opts->title.empty()) | ||
| uv_set_process_title(per_process_opts->title.c_str()); | ||
| if (!per_process::cli_options->title.empty()) | ||
| uv_set_process_title(per_process::cli_options->title.c_str()); | ||
|
|
||
| #if defined(NODE_HAVE_I18N_SUPPORT) | ||
| // If the parameter isn't given, use the env variable. | ||
| if (per_process_opts->icu_data_dir.empty()) | ||
| credentials::SafeGetenv("NODE_ICU_DATA", &per_process_opts->icu_data_dir); | ||
| if (per_process::cli_options->icu_data_dir.empty()) | ||
| credentials::SafeGetenv("NODE_ICU_DATA", | ||
| &per_process::cli_options->icu_data_dir); | ||
| // Initialize ICU. | ||
| // If icu_data_dir is empty here, it will load the 'minimal' data. | ||
| if (!i18n::InitializeICUDirectory(per_process_opts->icu_data_dir)) { | ||
| if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir)) { | ||
| fprintf(stderr, | ||
| "%s: could not initialize ICU " | ||
| "(check NODE_ICU_DATA or --icu-data-dir parameters)\n", | ||
|
|
@@ -1599,7 +1608,7 @@ Environment* CreateEnvironment(IsolateData* isolate_data, | |
| std::vector<std::string> args(argv, argv + argc); | ||
| std::vector<std::string> exec_args(exec_argv, exec_argv + exec_argc); | ||
| Environment* env = new Environment(isolate_data, context); | ||
| env->Start(args, exec_args, v8_is_profiling); | ||
| env->Start(args, exec_args, per_process::v8_is_profiling); | ||
| return env; | ||
| } | ||
|
|
||
|
|
@@ -1673,7 +1682,7 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data, | |
| Local<Context> context = NewContext(isolate); | ||
| Context::Scope context_scope(context); | ||
| Environment env(isolate_data, context); | ||
| env.Start(args, exec_args, v8_is_profiling); | ||
| env.Start(args, exec_args, per_process::v8_is_profiling); | ||
|
|
||
| const char* path = args.size() > 1 ? args[1].c_str() : nullptr; | ||
| StartInspector(&env, path); | ||
|
|
@@ -1780,9 +1789,9 @@ inline int Start(uv_loop_t* event_loop, | |
| return 12; // Signal internal error. | ||
|
|
||
| { | ||
| Mutex::ScopedLock scoped_lock(node_isolate_mutex); | ||
| CHECK_NULL(node_isolate); | ||
| node_isolate = isolate; | ||
| Mutex::ScopedLock scoped_lock(per_process::main_isolate_mutex); | ||
| CHECK_NULL(per_process::main_isolate); | ||
| per_process::main_isolate = isolate; | ||
| } | ||
|
|
||
| int exit_code; | ||
|
|
@@ -1807,9 +1816,9 @@ inline int Start(uv_loop_t* event_loop, | |
| } | ||
|
|
||
| { | ||
| Mutex::ScopedLock scoped_lock(node_isolate_mutex); | ||
| CHECK_EQ(node_isolate, isolate); | ||
| node_isolate = nullptr; | ||
| Mutex::ScopedLock scoped_lock(per_process::main_isolate_mutex); | ||
| CHECK_EQ(per_process::main_isolate, isolate); | ||
| per_process::main_isolate = nullptr; | ||
| } | ||
|
|
||
| isolate->Dispose(); | ||
|
|
@@ -1857,14 +1866,14 @@ int Start(int argc, char** argv) { | |
| V8::SetEntropySource(crypto::EntropySource); | ||
| #endif // HAVE_OPENSSL | ||
|
|
||
| InitializeV8Platform(per_process_opts->v8_thread_pool_size); | ||
| InitializeV8Platform(per_process::cli_options->v8_thread_pool_size); | ||
| V8::Initialize(); | ||
| performance::performance_v8_start = PERFORMANCE_NOW(); | ||
| v8_initialized = true; | ||
| per_process::v8_initialized = true; | ||
| const int exit_code = | ||
| Start(uv_default_loop(), args, exec_args); | ||
| v8_platform.StopTracingAgent(); | ||
| v8_initialized = false; | ||
| per_process::v8_initialized = false; | ||
| V8::Dispose(); | ||
|
|
||
| // uv_run cannot be called from the time before the beforeExit callback | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,9 +59,9 @@ namespace node { | |
| namespace { | ||
|
|
||
| inline void* BufferMalloc(size_t length) { | ||
| return per_process_opts->zero_fill_all_buffers ? | ||
| node::UncheckedCalloc(length) : | ||
| node::UncheckedMalloc(length); | ||
| return per_process::cli_options->zero_fill_all_buffers | ||
| ? node::UncheckedCalloc(length) | ||
| : node::UncheckedMalloc(length); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| } | ||
|
|
||
| } // namespace | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if that would do any good.
--profis a global flag.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bnoordhuis Good catch...we should probably move that to
per_process::cli_options.prof_process