exit program on top level exceptions
(also lots of reorg.)
This commit is contained in:
Родитель
a890b67406
Коммит
e02b71ebe8
|
@ -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
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
31
node_http.cc
31
node_http.cc
|
@ -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
|
||||
|
|
23
node_tcp.cc
23
node_tcp.cc
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче