Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Separate per-process and per-thread init logic.
Browse files Browse the repository at this point in the history
  • Loading branch information
bnoordhuis committed Dec 9, 2011
1 parent efdf274 commit 19640de
Showing 1 changed file with 44 additions and 42 deletions.
86 changes: 44 additions & 42 deletions src/node.cc
Expand Up @@ -2334,6 +2334,7 @@ static void EnableDebug(bool wait_connect) {


#ifdef __POSIX__
// FIXME this is positively unsafe with isolates/threads
static void EnableDebugSignalHandler(int signal) {
// Break once process will return execution to v8
v8::Debug::DebugBreak(node_isolate);
Expand Down Expand Up @@ -2530,7 +2531,7 @@ static Handle<Value> DebugProcess(const Arguments& args) {
#endif // _WIN32


char** Init(int argc, char *argv[]) {
char** ProcessInit(int argc, char *argv[]) {
// Hack aroung with the argv pointer. Used for process.title = "blah".
argv = node::Platform::SetupArgs(argc, argv);

Expand Down Expand Up @@ -2570,37 +2571,55 @@ char** Init(int argc, char *argv[]) {
#ifdef __POSIX__
// Ignore SIGPIPE
RegisterSignalHandler(SIGPIPE, SIG_IGN);
// TODO decide whether to handle these signals per-process or per-thread
RegisterSignalHandler(SIGINT, SignalExit);
RegisterSignalHandler(SIGTERM, SignalExit);
#endif // __POSIX__

// Don't use NODE_LOOP(), the node::Isolate() has not yet been initialized.
uv_loop_t* const loop = uv_default_loop();
return argv;
}


void EmitExit(v8::Handle<v8::Object> process_l) {
// process.emit('exit')
Local<Value> emit_v = process_l->Get(String::New("emit"));
assert(emit_v->IsFunction());
Local<Function> emit = Local<Function>::Cast(emit_v);
Local<Value> args[] = { String::New("exit") };
TryCatch try_catch;
emit->Call(process_l, 1, args);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
}


uv_prepare_init(uv_default_loop(), &prepare_tick_watcher);
void StartThread(Isolate* isolate, int argc, char** argv) {
uv_loop_t* loop = isolate->GetLoop();

uv_prepare_init(loop, &prepare_tick_watcher);
uv_prepare_start(&prepare_tick_watcher, PrepareTick);
uv_unref(loop);

uv_check_init(uv_default_loop(), &check_tick_watcher);
uv_check_init(loop, &check_tick_watcher);
uv_check_start(&check_tick_watcher, node::CheckTick);
uv_unref(loop);

uv_idle_init(uv_default_loop(), &tick_spinner);
uv_idle_init(loop, &tick_spinner);
uv_unref(loop);

uv_check_init(uv_default_loop(), &gc_check);
uv_check_init(loop, &gc_check);
uv_check_start(&gc_check, node::Check);
uv_unref(loop);

uv_idle_init(uv_default_loop(), &gc_idle);
uv_idle_init(loop, &gc_idle);
uv_unref(loop);

uv_timer_init(uv_default_loop(), &gc_timer);
uv_timer_init(loop, &gc_timer);
uv_unref(loop);

V8::SetFatalErrorHandler(node::OnFatalError);


// Set the callback DebugMessageDispatch which is called from the debug
// thread.
Debug::SetDebugMessageDispatchHandler(node::DebugMessageDispatch);
Expand Down Expand Up @@ -2628,27 +2647,27 @@ char** Init(int argc, char *argv[]) {
#endif // __POSIX__
}

return argv;
}
Handle<Object> process_l = SetupProcessObject(argc, argv);
v8_typed_array::AttachBindings(v8::Context::GetCurrent()->Global());

// Create all the objects, load modules, do everything.
// so your next reading stop should be node::Load()!
Load(process_l);

void EmitExit(v8::Handle<v8::Object> process_l) {
// process.emit('exit')
Local<Value> emit_v = process_l->Get(String::New("emit"));
assert(emit_v->IsFunction());
Local<Function> emit = Local<Function>::Cast(emit_v);
Local<Value> args[] = { String::New("exit") };
TryCatch try_catch;
emit->Call(process_l, 1, args);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
// All our arguments are loaded. We've evaluated all of the scripts. We
// might even have created TCP servers. Now we enter the main eventloop. If
// there are no watchers on the loop (except for the ones that were
// uv_unref'd) then this function exits. As long as there are active
// watchers, it blocks.
uv_run(loop);

EmitExit(process_l);
}


int Start(int argc, char *argv[]) {
// This needs to run *before* V8::Initialize()
argv = Init(argc, argv);
argv = ProcessInit(argc, argv);

v8::V8::Initialize();
v8::HandleScope handle_scope;
Expand All @@ -2659,24 +2678,7 @@ int Start(int argc, char *argv[]) {

// Create the main node::Isolate object
Isolate* isolate = Isolate::New(uv_default_loop());

Handle<Object> process_l = SetupProcessObject(argc, argv);

v8_typed_array::AttachBindings(context->Global());

// Create all the objects, load modules, do everything.
// so your next reading stop should be node::Load()!
Load(process_l);

// All our arguments are loaded. We've evaluated all of the scripts. We
// might even have created TCP servers. Now we enter the main eventloop. If
// there are no watchers on the loop (except for the ones that were
// uv_unref'd) then this function exits. As long as there are active
// watchers, it blocks.
uv_run(NODE_LOOP());

EmitExit(process_l);

StartThread(isolate, argc, argv);
isolate->Dispose();

#ifndef NDEBUG
Expand Down

0 comments on commit 19640de

Please sign in to comment.