Skip to content

Commit 4ae64b2

Browse files
petkaantonovchrisdickinson
authored andcommitted
src: extract node env init out of process init
PR-URL: #980 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent 7b554b1 commit 4ae64b2

File tree

2 files changed

+159
-53
lines changed

2 files changed

+159
-53
lines changed

src/node.cc

+82-53
Original file line numberDiff line numberDiff line change
@@ -3499,7 +3499,7 @@ void Init(int* argc,
34993499
uv_disable_stdio_inheritance();
35003500

35013501
// init async debug messages dispatching
3502-
// FIXME(bnoordhuis) Should be per-isolate or per-context, not global.
3502+
// Main thread uses uv_default_loop
35033503
uv_async_init(uv_default_loop(),
35043504
&dispatch_debug_messages_async,
35053505
DispatchDebugMessagesAsyncCallback);
@@ -3663,6 +3663,18 @@ Environment* CreateEnvironment(Isolate* isolate,
36633663
return env;
36643664
}
36653665

3666+
static Environment* CreateEnvironment(Isolate* isolate,
3667+
Handle<Context> context,
3668+
NodeInstanceData* instance_data) {
3669+
return CreateEnvironment(isolate,
3670+
instance_data->event_loop(),
3671+
context,
3672+
instance_data->argc(),
3673+
instance_data->argv(),
3674+
instance_data->exec_argc(),
3675+
instance_data->exec_argv());
3676+
}
3677+
36663678

36673679
static void HandleCloseCb(uv_handle_t* handle) {
36683680
Environment* env = reinterpret_cast<Environment*>(handle->data);
@@ -3746,62 +3758,32 @@ Environment* CreateEnvironment(Isolate* isolate,
37463758
}
37473759

37483760

3749-
int Start(int argc, char** argv) {
3750-
PlatformInit();
3751-
3752-
const char* replaceInvalid = secure_getenv("NODE_INVALID_UTF8");
3753-
3754-
if (replaceInvalid == nullptr)
3755-
WRITE_UTF8_FLAGS |= String::REPLACE_INVALID_UTF8;
3756-
3757-
CHECK_GT(argc, 0);
3758-
3759-
// Hack around with the argv pointer. Used for process.title = "blah".
3760-
argv = uv_setup_args(argc, argv);
3761-
3762-
// This needs to run *before* V8::Initialize(). The const_cast is not
3763-
// optional, in case you're wondering.
3764-
int exec_argc;
3765-
const char** exec_argv;
3766-
Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
3767-
3768-
#if HAVE_OPENSSL
3769-
// V8 on Windows doesn't have a good source of entropy. Seed it from
3770-
// OpenSSL's pool.
3771-
V8::SetEntropySource(crypto::EntropySource);
3772-
#endif
3773-
3774-
V8::InitializePlatform(new Platform(4));
3775-
3776-
int code;
3777-
V8::Initialize();
3778-
3779-
// Fetch a reference to the main isolate, so we have a reference to it
3761+
// Entry point for new node instances, also called directly for the main
3762+
// node instance.
3763+
static void StartNodeInstance(void* arg) {
3764+
NodeInstanceData* instance_data = static_cast<NodeInstanceData*>(arg);
3765+
Isolate* isolate = Isolate::New();
3766+
// Fetch a reference to the main isolate, so we have a reference to it
37803767
// even when we need it to access it from another (debugger) thread.
3781-
node_isolate = Isolate::New();
3768+
if (instance_data->is_main())
3769+
node_isolate = isolate;
37823770
{
3783-
Locker locker(node_isolate);
3784-
Isolate::Scope isolate_scope(node_isolate);
3785-
HandleScope handle_scope(node_isolate);
3786-
Local<Context> context = Context::New(node_isolate);
3787-
Environment* env = CreateEnvironment(
3788-
node_isolate,
3789-
uv_default_loop(),
3790-
context,
3791-
argc,
3792-
argv,
3793-
exec_argc,
3794-
exec_argv);
3771+
Locker locker(isolate);
3772+
Isolate::Scope isolate_scope(isolate);
3773+
HandleScope handle_scope(isolate);
3774+
Local<Context> context = Context::New(isolate);
3775+
Environment* env = CreateEnvironment(isolate, context, instance_data);
37953776
Context::Scope context_scope(context);
3796-
env->set_using_abort_on_uncaught_exc(abort_on_uncaught_exception);
3777+
if (instance_data->is_main())
3778+
env->set_using_abort_on_uncaught_exc(abort_on_uncaught_exception);
37973779
// Start debug agent when argv has --debug
3798-
if (use_debug_agent)
3780+
if (instance_data->use_debug_agent())
37993781
StartDebug(env, debug_wait_connect);
38003782

38013783
LoadEnvironment(env);
38023784

38033785
// Enable debugger
3804-
if (use_debug_agent)
3786+
if (instance_data->use_debug_agent())
38053787
EnableDebug(env);
38063788

38073789
bool more;
@@ -3817,22 +3799,69 @@ int Start(int argc, char** argv) {
38173799
more = true;
38183800
}
38193801
} while (more == true);
3820-
code = EmitExit(env);
3802+
3803+
int exit_code = EmitExit(env);
3804+
if (instance_data->is_main())
3805+
instance_data->set_exit_code(exit_code);
38213806
RunAtExit(env);
38223807

38233808
env->Dispose();
38243809
env = nullptr;
38253810
}
38263811

3827-
CHECK_NE(node_isolate, nullptr);
3828-
node_isolate->Dispose();
3829-
node_isolate = nullptr;
3812+
CHECK_NE(isolate, nullptr);
3813+
isolate->Dispose();
3814+
isolate = nullptr;
3815+
if (instance_data->is_main())
3816+
node_isolate = nullptr;
3817+
}
3818+
3819+
int Start(int argc, char** argv) {
3820+
PlatformInit();
3821+
3822+
const char* replace_invalid = secure_getenv("NODE_INVALID_UTF8");
3823+
3824+
if (replace_invalid == nullptr)
3825+
WRITE_UTF8_FLAGS |= String::REPLACE_INVALID_UTF8;
3826+
3827+
CHECK_GT(argc, 0);
3828+
3829+
// Hack around with the argv pointer. Used for process.title = "blah".
3830+
argv = uv_setup_args(argc, argv);
3831+
3832+
// This needs to run *before* V8::Initialize(). The const_cast is not
3833+
// optional, in case you're wondering.
3834+
int exec_argc;
3835+
const char** exec_argv;
3836+
Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
3837+
3838+
#if HAVE_OPENSSL
3839+
// V8 on Windows doesn't have a good source of entropy. Seed it from
3840+
// OpenSSL's pool.
3841+
V8::SetEntropySource(crypto::EntropySource);
3842+
#endif
3843+
3844+
V8::InitializePlatform(new Platform(4));
3845+
V8::Initialize();
3846+
3847+
int exit_code = 1;
3848+
{
3849+
NodeInstanceData instance_data(NodeInstanceType::MAIN,
3850+
uv_default_loop(),
3851+
argc,
3852+
const_cast<const char**>(argv),
3853+
exec_argc,
3854+
exec_argv,
3855+
use_debug_agent);
3856+
StartNodeInstance(&instance_data);
3857+
exit_code = instance_data.exit_code();
3858+
}
38303859
V8::Dispose();
38313860

38323861
delete[] exec_argv;
38333862
exec_argv = nullptr;
38343863

3835-
return code;
3864+
return exit_code;
38363865
}
38373866

38383867

src/node_internals.h

+77
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,83 @@ inline void NODE_SET_EXTERNAL(v8::Handle<v8::ObjectTemplate> target,
210210
v8::DontDelete));
211211
}
212212

213+
enum NodeInstanceType { MAIN, WORKER };
214+
215+
class NodeInstanceData {
216+
public:
217+
NodeInstanceData(NodeInstanceType node_instance_type,
218+
uv_loop_t* event_loop,
219+
int argc,
220+
const char** argv,
221+
int exec_argc,
222+
const char** exec_argv,
223+
bool use_debug_agent_flag)
224+
: node_instance_type_(node_instance_type),
225+
exit_code_(1),
226+
event_loop_(event_loop),
227+
argc_(argc),
228+
argv_(argv),
229+
exec_argc_(exec_argc),
230+
exec_argv_(exec_argv),
231+
use_debug_agent_flag_(use_debug_agent_flag) {
232+
CHECK_NE(event_loop_, nullptr);
233+
}
234+
235+
uv_loop_t* event_loop() const {
236+
return event_loop_;
237+
}
238+
239+
int exit_code() {
240+
CHECK(is_main());
241+
return exit_code_;
242+
}
243+
244+
void set_exit_code(int exit_code) {
245+
CHECK(is_main());
246+
exit_code_ = exit_code;
247+
}
248+
249+
bool is_main() {
250+
return node_instance_type_ == MAIN;
251+
}
252+
253+
bool is_worker() {
254+
return node_instance_type_ == WORKER;
255+
}
256+
257+
int argc() {
258+
return argc_;
259+
}
260+
261+
const char** argv() {
262+
return argv_;
263+
}
264+
265+
int exec_argc() {
266+
return exec_argc_;
267+
}
268+
269+
const char** exec_argv() {
270+
return exec_argv_;
271+
}
272+
273+
bool use_debug_agent() {
274+
return is_main() && use_debug_agent_flag_;
275+
}
276+
277+
private:
278+
const NodeInstanceType node_instance_type_;
279+
int exit_code_;
280+
uv_loop_t* const event_loop_;
281+
const int argc_;
282+
const char** argv_;
283+
const int exec_argc_;
284+
const char** exec_argv_;
285+
const bool use_debug_agent_flag_;
286+
287+
DISALLOW_COPY_AND_ASSIGN(NodeInstanceData);
288+
};
289+
213290
} // namespace node
214291

215292
#endif // SRC_NODE_INTERNALS_H_

0 commit comments

Comments
 (0)