Skip to content

Commit

Permalink
node: extract node env initialization out of process initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
petkaantonov committed Mar 3, 2015
1 parent 2b47fd2 commit dfe0b40
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 53 deletions.
135 changes: 82 additions & 53 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3499,7 +3499,7 @@ void Init(int* argc,
uv_disable_stdio_inheritance();

// init async debug messages dispatching
// FIXME(bnoordhuis) Should be per-isolate or per-context, not global.
// Main thread uses uv_default_loop
uv_async_init(uv_default_loop(),
&dispatch_debug_messages_async,
DispatchDebugMessagesAsyncCallback);
Expand Down Expand Up @@ -3663,6 +3663,18 @@ Environment* CreateEnvironment(Isolate* isolate,
return env;
}

static Environment* CreateEnvironment(Isolate* isolate,
Handle<Context> context,
NodeInstanceData* instance_data) {
return CreateEnvironment(isolate,
instance_data->event_loop(),
context,
instance_data->argc(),
instance_data->argv(),
instance_data->exec_argc(),
instance_data->exec_argv());
}


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


int Start(int argc, char** argv) {
PlatformInit();

const char* replaceInvalid = secure_getenv("NODE_INVALID_UTF8");

if (replaceInvalid == nullptr)
WRITE_UTF8_FLAGS |= String::REPLACE_INVALID_UTF8;

CHECK_GT(argc, 0);

// Hack around with the argv pointer. Used for process.title = "blah".
argv = uv_setup_args(argc, argv);

// This needs to run *before* V8::Initialize(). The const_cast is not
// optional, in case you're wondering.
int exec_argc;
const char** exec_argv;
Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);

#if HAVE_OPENSSL
// V8 on Windows doesn't have a good source of entropy. Seed it from
// OpenSSL's pool.
V8::SetEntropySource(crypto::EntropySource);
#endif

V8::InitializePlatform(new Platform(4));

int code;
V8::Initialize();

// Fetch a reference to the main isolate, so we have a reference to it
// Entry point for new node instances, also called directly for the main
// node instance.
static void StartNodeInstance(void* arg) {
NodeInstanceData* instance_data = static_cast<NodeInstanceData*>(arg);
Isolate* isolate = Isolate::New();
// Fetch a reference to the main isolate, so we have a reference to it
// even when we need it to access it from another (debugger) thread.
node_isolate = Isolate::New();
if (instance_data->is_main())
node_isolate = isolate;
{
Locker locker(node_isolate);
Isolate::Scope isolate_scope(node_isolate);
HandleScope handle_scope(node_isolate);
Local<Context> context = Context::New(node_isolate);
Environment* env = CreateEnvironment(
node_isolate,
uv_default_loop(),
context,
argc,
argv,
exec_argc,
exec_argv);
Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
Local<Context> context = Context::New(isolate);
Environment* env = CreateEnvironment(isolate, context, instance_data);
Context::Scope context_scope(context);
env->set_using_abort_on_uncaught_exc(abort_on_uncaught_exception);
if (instance_data->is_main())
env->set_using_abort_on_uncaught_exc(abort_on_uncaught_exception);
// Start debug agent when argv has --debug
if (use_debug_agent)
if (instance_data->use_debug_agent())
StartDebug(env, debug_wait_connect);

LoadEnvironment(env);

// Enable debugger
if (use_debug_agent)
if (instance_data->use_debug_agent())
EnableDebug(env);

bool more;
Expand All @@ -3817,22 +3799,69 @@ int Start(int argc, char** argv) {
more = true;
}
} while (more == true);
code = EmitExit(env);

int exit_code = EmitExit(env);
if (instance_data->is_main())
instance_data->set_exit_code(exit_code);
RunAtExit(env);

env->Dispose();
env = nullptr;
}

CHECK_NE(node_isolate, nullptr);
node_isolate->Dispose();
node_isolate = nullptr;
CHECK_NE(isolate, nullptr);
isolate->Dispose();
isolate = nullptr;
if (instance_data->is_main())
node_isolate = nullptr;
}

int Start(int argc, char** argv) {
PlatformInit();

const char* replace_invalid = secure_getenv("NODE_INVALID_UTF8");

if (replace_invalid == nullptr)
WRITE_UTF8_FLAGS |= String::REPLACE_INVALID_UTF8;

CHECK_GT(argc, 0);

// Hack around with the argv pointer. Used for process.title = "blah".
argv = uv_setup_args(argc, argv);

// This needs to run *before* V8::Initialize(). The const_cast is not
// optional, in case you're wondering.
int exec_argc;
const char** exec_argv;
Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);

#if HAVE_OPENSSL
// V8 on Windows doesn't have a good source of entropy. Seed it from
// OpenSSL's pool.
V8::SetEntropySource(crypto::EntropySource);
#endif

V8::InitializePlatform(new Platform(4));
V8::Initialize();

int exit_code = 1;
{
NodeInstanceData instance_data(NodeInstanceType::MAIN,
uv_default_loop(),
argc,
const_cast<const char**>(argv),
exec_argc,
exec_argv,
use_debug_agent);
StartNodeInstance(&instance_data);
exit_code = instance_data.exit_code();
}
V8::Dispose();

delete[] exec_argv;
exec_argv = nullptr;

return code;
return exit_code;
}


Expand Down
77 changes: 77 additions & 0 deletions src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,83 @@ inline void NODE_SET_EXTERNAL(v8::Handle<v8::ObjectTemplate> target,
v8::DontDelete));
}

enum NodeInstanceType { MAIN, WORKER };

class NodeInstanceData {
public:
NodeInstanceData(NodeInstanceType node_instance_type,
uv_loop_t* event_loop,
int argc,
const char** argv,
int exec_argc,
const char** exec_argv,
bool use_debug_agent_flag)
: node_instance_type_(node_instance_type),
exit_code_(1),
event_loop_(event_loop),
argc_(argc),
argv_(argv),
exec_argc_(exec_argc),
exec_argv_(exec_argv),
use_debug_agent_flag_(use_debug_agent_flag) {
CHECK_NE(event_loop_, nullptr);
}

uv_loop_t* event_loop() const {
return event_loop_;
}

int exit_code() {
CHECK(is_main());
return exit_code_;
}

void set_exit_code(int exit_code) {
CHECK(is_main());
exit_code_ = exit_code;
}

bool is_main() {
return node_instance_type_ == MAIN;
}

bool is_worker() {
return node_instance_type_ == WORKER;
}

int argc() {
return argc_;
}

const char** argv() {
return argv_;
}

int exec_argc() {
return exec_argc_;
}

const char** exec_argv() {
return exec_argv_;
}

bool use_debug_agent() {
return is_main() && use_debug_agent_flag_;
}

private:
const NodeInstanceType node_instance_type_;
int exit_code_;
uv_loop_t* const event_loop_;
const int argc_;
const char** argv_;
const int exec_argc_;
const char** exec_argv_;
const bool use_debug_agent_flag_;

DISALLOW_COPY_AND_ASSIGN(NodeInstanceData);
};

} // namespace node

#endif // SRC_NODE_INTERNALS_H_

0 comments on commit dfe0b40

Please sign in to comment.