From f67e8f243c9cbddb4989d9950cf3ef1b11c8d528 Mon Sep 17 00:00:00 2001 From: Dean McNamee Date: Tue, 15 Mar 2011 22:39:16 +0000 Subject: [PATCH] Export more functions for initializing and starting node. For greater flexibility in controlling node's initialization and startup, the following new functions are exported. - node::Init() - node::SetupProcessObject() - node::Load() - node::EmitExit() These are some of the major steps involved in node::Setup(). Exporting these functions allows an embedding program to write a replacement for node::Start(), and to have access to the node process object after it's created. --- src/node.cc | 87 ++++++++++++++++++++++++++++++++--------------------- src/node.h | 7 ++++- 2 files changed, 58 insertions(+), 36 deletions(-) diff --git a/src/node.cc b/src/node.cc index 267d59332d..7dae9db2d9 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1933,7 +1933,7 @@ static Handle EnvEnumerator(const AccessorInfo& info) { } -static void Load(int argc, char *argv[]) { +Handle SetupProcessObject(int argc, char *argv[]) { HandleScope scope; int i, j; @@ -2064,12 +2064,31 @@ static void Load(int argc, char *argv[]) { process->Set(String::NewSymbol("EventEmitter"), EventEmitter::constructor_template->GetFunction()); + return process; +} + + +static void AtExit() { + node::Stdio::Flush(); + node::Stdio::DisableRawMode(STDIN_FILENO); +} + + +static void SignalExit(int signal) { + Stdio::DisableRawMode(STDIN_FILENO); + _exit(1); +} + + +void Load(Handle process) { // Compile, execute the src/node.js file. (Which was included as static C // string in node_natives.h. 'natve_node' is the string containing that // source code.) // The node.js file returns a function 'f' + atexit(AtExit); + TryCatch try_catch; Local f_value = ExecuteString(MainSource(), @@ -2156,11 +2175,11 @@ static void PrintHelp() { } // Parse node command line arguments. -static void ParseArgs(int *argc, char **argv) { +static void ParseArgs(int argc, char **argv) { int i; // TODO use parse opts - for (i = 1; i < *argc; i++) { + for (i = 1; i < argc; i++) { const char *arg = argv[i]; if (strstr(arg, "--debug") == arg) { ParseDebugOpt(arg); @@ -2181,7 +2200,7 @@ static void ParseArgs(int *argc, char **argv) { PrintHelp(); exit(0); } else if (strcmp(arg, "--eval") == 0 || strcmp(arg, "-e") == 0) { - if (*argc <= i + 1) { + if (argc <= i + 1) { fprintf(stderr, "Error: --eval requires an argument\n"); exit(1); } @@ -2198,18 +2217,6 @@ static void ParseArgs(int *argc, char **argv) { } -static void AtExit() { - node::Stdio::Flush(); - node::Stdio::DisableRawMode(STDIN_FILENO); -} - - -static void SignalExit(int signal) { - Stdio::DisableRawMode(STDIN_FILENO); - _exit(1); -} - - static void EnableDebug(bool wait_connect) { // Start the debug thread and it's associated TCP server on port 5858. bool r = Debug::EnableAgent("node " NODE_VERSION, debug_port); @@ -2262,12 +2269,12 @@ static int RegisterSignalHandler(int signal, void (*handler)(int)) { #endif // __POSIX__ -int Start(int argc, char *argv[]) { +char** Init(int argc, char *argv[]) { // Hack aroung with the argv pointer. Used for process.title = "blah". argv = node::Platform::SetupArgs(argc, argv); // Parse a few arguments which are specific to Node. - node::ParseArgs(&argc, argv); + node::ParseArgs(argc, argv); // Parse the rest of the args (up to the 'option_end_index' (where '--' was // in the command line)) int v8argc = node::option_end_index; @@ -2354,9 +2361,6 @@ int Start(int argc, char *argv[]) { eio_set_max_poll_reqs(10); } - V8::Initialize(); - HandleScope handle_scope; - V8::SetFatalErrorHandler(node::OnFatalError); @@ -2386,15 +2390,39 @@ int Start(int argc, char *argv[]) { #endif // __POSIX__ } + return argv; +} + + +void EmitExit(v8::Handle process) { + // process.emit('exit') + Local emit_v = process->Get(String::New("emit")); + assert(emit_v->IsFunction()); + Local emit = Local::Cast(emit_v); + Local args[] = { String::New("exit") }; + TryCatch try_catch; + emit->Call(process, 1, args); + if (try_catch.HasCaught()) { + FatalException(try_catch); + } +} + + +int Start(int argc, char *argv[]) { + v8::V8::Initialize(); + v8::HandleScope handle_scope; + + argv = Init(argc, argv); + // Create the one and only Context. Persistent context = v8::Context::New(); v8::Context::Scope context_scope(context); - atexit(node::AtExit); + Handle process = SetupProcessObject(argc, argv); // Create all the objects, load modules, do everything. // so your next reading stop should be node::Load()! - node::Load(argc, argv); + Load(process); // TODO Probably don't need to start this each time. // Avoids failing on test/simple/test-eio-race3.js though @@ -2407,18 +2435,7 @@ int Start(int argc, char *argv[]) { // watchers, it blocks. ev_loop(EV_DEFAULT_UC_ 0); - - // process.emit('exit') - Local emit_v = process->Get(String::New("emit")); - assert(emit_v->IsFunction()); - Local emit = Local::Cast(emit_v); - Local args[] = { String::New("exit") }; - TryCatch try_catch; - emit->Call(process, 1, args); - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - + EmitExit(process); #ifndef NDEBUG // Clean up. diff --git a/src/node.h b/src/node.h index f232704895..2b37d736dc 100644 --- a/src/node.h +++ b/src/node.h @@ -37,7 +37,12 @@ namespace node { -int Start (int argc, char *argv[]); +int Start(int argc, char *argv[]); + +char** Init(int argc, char *argv[]); +v8::Handle SetupProcessObject(int argc, char *argv[]); +void Load(v8::Handle process); +void EmitExit(v8::Handle process); #define NODE_PSYMBOL(s) Persistent::New(String::NewSymbol(s))