exit program on top level exceptions

(also lots of reorg.)
This commit is contained in:
Ryan 2009-03-04 00:31:37 +01:00
Родитель a890b67406
Коммит e02b71ebe8
9 изменённых файлов: 95 добавлений и 90 удалений

Просмотреть файл

@ -3,7 +3,8 @@ function encode(data) {
return chunk.length.toString(16) + "\r\n" + chunk + "\r\n";
}
var server = new HTTP.Server("localhost", 8000);
var port = 8000;
var server = new HTTP.Server("localhost", port);
server.onRequest = function (request) {
@ -21,8 +22,12 @@ server.onRequest = function (request) {
request.respond("Content-Type: text/plain\r\n");
request.respond("Transfer-Encoding: chunked\r\n");
request.respond("\r\n");
};
log("Running at http://localhost:" + port + "/");
/*
server.close();
*/

74
node.cc
Просмотреть файл

@ -1,4 +1,4 @@
#include <oi.h>
#include "node.h"
#include "node_tcp.h"
#include "node_http.h"
@ -6,24 +6,37 @@
#include <stdio.h>
#include <assert.h>
#include <string>
#include <list>
#include <map>
#include <v8.h>
using namespace v8;
using namespace std;
static struct ev_loop *loop;
static int exit_code = 0;
static Persistent<Context> context;
static Persistent<Function> process_;
void
node_fatal_exception (TryCatch &try_catch)
{
HandleScope handle_scope;
Local<Message> message = try_catch.Message();
String::Utf8Value error(try_catch.Exception());
fprintf( stderr
, "Uncaught Exception. line %d '%s'\n\n"
, try_catch.Message()->GetLineNumber()
, *error
);
ev_unloop(node_loop(), EVUNLOOP_ALL);
exit_code = 1;
}
// Reads a file into a v8 string.
static Handle<String> ReadFile
( const string& name
)
static Handle<String>
ReadFile (const string& name)
{
FILE* file = fopen(name.c_str(), "rb");
if (file == NULL) return Handle<String>();
@ -44,12 +57,8 @@ static Handle<String> ReadFile
return result;
}
static void ParseOptions
( int argc
, char* argv[]
, map<string, string>& options
, string* file
)
static void
ParseOptions (int argc, char* argv[], map<string, string>& options, string* file)
{
for (int i = 1; i < argc; i++) {
string arg = argv[i];
@ -64,9 +73,8 @@ static void ParseOptions
}
}
static bool compile
( Handle<String> script
)
static bool
compile (Handle<String> script)
{
HandleScope handle_scope;
@ -99,26 +107,30 @@ static bool compile
return true;
}
static Handle<Value> LogCallback
( const Arguments& args
)
static Handle<Value>
LogCallback (const Arguments& args)
{
if (args.Length() < 1) return v8::Undefined();
HandleScope scope;
Handle<Value> arg = args[0];
String::Utf8Value value(arg);
printf("Logged: %s\n", *value);
printf("%s\n", *value);
fflush(stdout);
return v8::Undefined();
}
static void
OnFatalError (const char* location, const char* message)
{
fprintf(stderr, "Fatal error. %s %s\n", location, message);
ev_unloop(node_loop(), EVUNLOOP_ALL);
}
int
main (int argc, char *argv[])
{
loop = ev_default_loop(0);
map<string, string> options;
string file;
ParseOptions(argc, argv, options, &file);
@ -133,24 +145,26 @@ main (int argc, char *argv[])
return 1;
}
context = Context::New(NULL, ObjectTemplate::New());
Persistent<Context> context = Context::New(NULL, ObjectTemplate::New());
Context::Scope context_scope(context);
Local<Object> g = Context::GetCurrent()->Global();
g->Set( String::New("log"), FunctionTemplate::New(LogCallback)->GetFunction());
g->Set( String::New("TCP"), node_tcp_initialize(loop));
g->Set( String::New("HTTP"), node_http_initialize(loop));
node_timer_initialize(g, loop);
node_tcp_initialize(g);
node_http_initialize(g);
node_timer_initialize(g);
V8::SetFatalErrorHandler(OnFatalError);
// Compile and run the script
if (!compile(source))
return 1;
ev_loop(loop, 0);
ev_loop(node_loop(), 0);
context.Dispose();
return 0;
return exit_code;
}

11
node.h Normal file
Просмотреть файл

@ -0,0 +1,11 @@
#ifndef node_h
#define node_h
#include <ev.h>
#include <v8.h>
void node_fatal_exception (v8::TryCatch &try_catch);
#define node_loop() ev_default_loop(0)
#endif // node_h

Просмотреть файл

@ -1,4 +1,5 @@
#include "node_http.h"
#include "node.h"
#include <oi_socket.h>
#include <ebb_request_parser.h>
@ -6,13 +7,10 @@
#include <string>
#include <list>
#include <v8.h>
using namespace v8;
using namespace std;
static Persistent<ObjectTemplate> request_template;
static struct ev_loop *loop;
// globals
static Persistent<String> path_str;
@ -226,10 +224,9 @@ on_headers_complete (ebb_request *req)
const int argc = 1;
Handle<Value> argv[argc] = { js_request };
Handle<Value> r = request->connection.js_onRequest->Call(Context::GetCurrent()->Global(), argc, argv);
if (r.IsEmpty()) {
String::Utf8Value error(try_catch.Exception());
printf("error: %s\n", *error);
}
if(try_catch.HasCaught())
node_fatal_exception(try_catch);
}
static void
@ -346,10 +343,8 @@ HttpRequest::MakeBodyCallback (const char *base, size_t length)
Handle<Value> result = onBody->Call(js_object, argc, argv);
if (result.IsEmpty()) {
String::Utf8Value error(try_catch.Exception());
printf("error: %s\n", *error);
}
if(try_catch.HasCaught())
node_fatal_exception(try_catch);
}
Local<Object>
@ -490,7 +485,7 @@ Server::Start(struct addrinfo *servinfo)
{
int r = oi_server_listen(&server, servinfo);
if(r == 0)
oi_server_attach(&server, loop);
oi_server_attach(&server, node_loop());
return r;
}
@ -541,25 +536,23 @@ server_constructor (const Arguments& args)
if (r != 0)
return Undefined(); // XXX raise error?
printf("Running at http://localhost:%s/\n", *port);
return args.This();
}
Handle<Object>
node_http_initialize (struct ev_loop *_loop)
void
node_http_initialize (Handle<Object> target)
{
HandleScope scope;
loop = _loop;
Local<Object> http = Object::New();
target->Set (String::NewSymbol("HTTP"), http);
Local<FunctionTemplate> server_t = FunctionTemplate::New(server_constructor);
server_t->InstanceTemplate()->SetInternalFieldCount(1);
http->Set(String::New("Server"), server_t->GetFunction());
path_str = Persistent<String>::New( String::NewSymbol("path") );
uri_str = Persistent<String>::New( String::NewSymbol("uri") );
query_string_str = Persistent<String>::New( String::NewSymbol("query_string") );
@ -585,6 +578,4 @@ node_http_initialize (struct ev_loop *_loop)
put_str = Persistent<String>::New( String::New("PUT") );
trace_str = Persistent<String>::New( String::New("TRACE") );
unlock_str = Persistent<String>::New( String::New("UNLOCK") );
return scope.Close(http);
}

Просмотреть файл

@ -2,10 +2,7 @@
#define node_http_h
#include <v8.h>
#include <ev.h>
using namespace v8;
Handle<Object> node_http_initialize (struct ev_loop *);
void node_http_initialize (v8::Handle<v8::Object> target);
#endif

Просмотреть файл

@ -1,4 +1,5 @@
#include "node_tcp.h"
#include "node.h"
#include <oi_socket.h>
#include <oi_async.h>
@ -7,6 +8,7 @@
#include <sys/socket.h>
#include <netdb.h>
using namespace v8;
/*
@ -50,8 +52,6 @@ static struct addrinfo tcp_hints =
/* ai_next */ , 0
};
static struct ev_loop *loop;
class TCPClient {
public:
oi_task resolve_task;
@ -110,8 +110,7 @@ static void resolve_done
client->socket.data = client;
oi_socket_connect (&client->socket, client->address);
oi_socket_attach (&client->socket, loop);
oi_socket_attach (&client->socket, node_loop());
freeaddrinfo(client->address);
client->address = NULL;
@ -166,21 +165,17 @@ static Handle<Value> Connect
oi_async_submit (&thread_pool, &client->resolve_task);
}
Handle<Object> node_tcp_initialize
( struct ev_loop *_loop
)
void
node_tcp_initialize (Handle<Object> target)
{
loop = _loop;
oi_async_init(&thread_pool);
oi_async_attach(loop, &thread_pool);
oi_async_attach(node_loop(), &thread_pool);
HandleScope scope;
Local<Object> t = Object::New();
Local<Object> tcp = Object::New();
target->Set(String::NewSymbol("TCP"), tcp);
t->Set(String::New("connect"), FunctionTemplate::New(Connect)->GetFunction());
return scope.Close(t);
tcp->Set(String::NewSymbol("connect"), FunctionTemplate::New(Connect)->GetFunction());
}

Просмотреть файл

@ -2,10 +2,7 @@
#define node_tcp_h
#include <v8.h>
#include <ev.h>
using namespace v8;
Handle<Object> node_tcp_initialize (struct ev_loop *);
void node_tcp_initialize (v8::Handle<v8::Object> target);
#endif

Просмотреть файл

@ -1,7 +1,7 @@
#include <ev.h>
#include <v8.h>
#include "node.h"
#include "node_timer.h"
using namespace v8;
static struct ev_loop *loop;
class Timer {
public:
@ -37,12 +37,12 @@ Timer::Timer (Handle<Function> _callback, int _argc, Handle<Value> _argv[], ev_t
ev_timer_init (&watcher, onTimeout, after, repeat);
watcher.data = this;
ev_timer_start (loop, &watcher);
ev_timer_start (node_loop(), &watcher);
}
Timer::~Timer ()
{
ev_timer_stop (loop, &watcher);
ev_timer_stop (node_loop(), &watcher);
callback.Dispose();
@ -57,11 +57,10 @@ Timer::CallCallback ()
TryCatch try_catch;
Handle<Value> r = callback->Call (Context::GetCurrent()->Global(), argc, argv);
if (r.IsEmpty()) {
String::Utf8Value error(try_catch.Exception());
printf("timer callback error: %s\n", *error);
}
callback->Call (Context::GetCurrent()->Global(), argc, argv);
if(try_catch.HasCaught())
node_fatal_exception(try_catch);
}
Local<External>
@ -166,10 +165,8 @@ static Handle<Value> setInterval
}
void
node_timer_initialize (Handle<Object> target, struct ev_loop *_loop)
node_timer_initialize (Handle<Object> target)
{
loop = _loop;
HandleScope scope;
target->Set ( String::New("setTimeout")

Просмотреть файл

@ -1,10 +1,8 @@
#ifndef node_timer_h
#define node_timer_h
#include <ev.h>
#include <v8.h>
using namespace v8;
void node_timer_initialize (Handle<Object> target, struct ev_loop *_loop);
void node_timer_initialize (v8::Handle<v8::Object> target);
#endif // node_timer_h