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";
|
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) {
|
server.onRequest = function (request) {
|
||||||
|
|
||||||
|
@ -21,8 +22,12 @@ server.onRequest = function (request) {
|
||||||
request.respond("Content-Type: text/plain\r\n");
|
request.respond("Content-Type: text/plain\r\n");
|
||||||
request.respond("Transfer-Encoding: chunked\r\n");
|
request.respond("Transfer-Encoding: chunked\r\n");
|
||||||
request.respond("\r\n");
|
request.respond("\r\n");
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
log("Running at http://localhost:" + port + "/");
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
server.close();
|
server.close();
|
||||||
*/
|
*/
|
||||||
|
|
74
node.cc
74
node.cc
|
@ -1,4 +1,4 @@
|
||||||
#include <oi.h>
|
#include "node.h"
|
||||||
|
|
||||||
#include "node_tcp.h"
|
#include "node_tcp.h"
|
||||||
#include "node_http.h"
|
#include "node_http.h"
|
||||||
|
@ -6,24 +6,37 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <v8.h>
|
|
||||||
|
|
||||||
using namespace v8;
|
using namespace v8;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static struct ev_loop *loop;
|
static int exit_code = 0;
|
||||||
|
|
||||||
static Persistent<Context> context;
|
void
|
||||||
static Persistent<Function> process_;
|
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.
|
// Reads a file into a v8 string.
|
||||||
static Handle<String> ReadFile
|
static Handle<String>
|
||||||
( const string& name
|
ReadFile (const string& name)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
FILE* file = fopen(name.c_str(), "rb");
|
FILE* file = fopen(name.c_str(), "rb");
|
||||||
if (file == NULL) return Handle<String>();
|
if (file == NULL) return Handle<String>();
|
||||||
|
@ -44,12 +57,8 @@ static Handle<String> ReadFile
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ParseOptions
|
static void
|
||||||
( int argc
|
ParseOptions (int argc, char* argv[], map<string, string>& options, string* file)
|
||||||
, char* argv[]
|
|
||||||
, map<string, string>& options
|
|
||||||
, string* file
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
string arg = argv[i];
|
string arg = argv[i];
|
||||||
|
@ -64,9 +73,8 @@ static void ParseOptions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool compile
|
static bool
|
||||||
( Handle<String> script
|
compile (Handle<String> script)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
HandleScope handle_scope;
|
HandleScope handle_scope;
|
||||||
|
|
||||||
|
@ -99,26 +107,30 @@ static bool compile
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Handle<Value> LogCallback
|
static Handle<Value>
|
||||||
( const Arguments& args
|
LogCallback (const Arguments& args)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (args.Length() < 1) return v8::Undefined();
|
if (args.Length() < 1) return v8::Undefined();
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
Handle<Value> arg = args[0];
|
Handle<Value> arg = args[0];
|
||||||
String::Utf8Value value(arg);
|
String::Utf8Value value(arg);
|
||||||
|
|
||||||
printf("Logged: %s\n", *value);
|
printf("%s\n", *value);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
return v8::Undefined();
|
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
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
loop = ev_default_loop(0);
|
|
||||||
|
|
||||||
map<string, string> options;
|
map<string, string> options;
|
||||||
string file;
|
string file;
|
||||||
ParseOptions(argc, argv, options, &file);
|
ParseOptions(argc, argv, options, &file);
|
||||||
|
@ -133,24 +145,26 @@ main (int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context = Context::New(NULL, ObjectTemplate::New());
|
Persistent<Context> context = Context::New(NULL, ObjectTemplate::New());
|
||||||
Context::Scope context_scope(context);
|
Context::Scope context_scope(context);
|
||||||
|
|
||||||
Local<Object> g = Context::GetCurrent()->Global();
|
Local<Object> g = Context::GetCurrent()->Global();
|
||||||
g->Set( String::New("log"), FunctionTemplate::New(LogCallback)->GetFunction());
|
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
|
// Compile and run the script
|
||||||
if (!compile(source))
|
if (!compile(source))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
ev_loop(loop, 0);
|
ev_loop(node_loop(), 0);
|
||||||
|
|
||||||
context.Dispose();
|
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_http.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
#include <oi_socket.h>
|
#include <oi_socket.h>
|
||||||
#include <ebb_request_parser.h>
|
#include <ebb_request_parser.h>
|
||||||
|
@ -6,13 +7,10 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include <v8.h>
|
|
||||||
|
|
||||||
using namespace v8;
|
using namespace v8;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static Persistent<ObjectTemplate> request_template;
|
static Persistent<ObjectTemplate> request_template;
|
||||||
static struct ev_loop *loop;
|
|
||||||
|
|
||||||
// globals
|
// globals
|
||||||
static Persistent<String> path_str;
|
static Persistent<String> path_str;
|
||||||
|
@ -226,10 +224,9 @@ on_headers_complete (ebb_request *req)
|
||||||
const int argc = 1;
|
const int argc = 1;
|
||||||
Handle<Value> argv[argc] = { js_request };
|
Handle<Value> argv[argc] = { js_request };
|
||||||
Handle<Value> r = request->connection.js_onRequest->Call(Context::GetCurrent()->Global(), argc, argv);
|
Handle<Value> r = request->connection.js_onRequest->Call(Context::GetCurrent()->Global(), argc, argv);
|
||||||
if (r.IsEmpty()) {
|
|
||||||
String::Utf8Value error(try_catch.Exception());
|
if(try_catch.HasCaught())
|
||||||
printf("error: %s\n", *error);
|
node_fatal_exception(try_catch);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -346,10 +343,8 @@ HttpRequest::MakeBodyCallback (const char *base, size_t length)
|
||||||
|
|
||||||
Handle<Value> result = onBody->Call(js_object, argc, argv);
|
Handle<Value> result = onBody->Call(js_object, argc, argv);
|
||||||
|
|
||||||
if (result.IsEmpty()) {
|
if(try_catch.HasCaught())
|
||||||
String::Utf8Value error(try_catch.Exception());
|
node_fatal_exception(try_catch);
|
||||||
printf("error: %s\n", *error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Local<Object>
|
Local<Object>
|
||||||
|
@ -490,7 +485,7 @@ Server::Start(struct addrinfo *servinfo)
|
||||||
{
|
{
|
||||||
int r = oi_server_listen(&server, servinfo);
|
int r = oi_server_listen(&server, servinfo);
|
||||||
if(r == 0)
|
if(r == 0)
|
||||||
oi_server_attach(&server, loop);
|
oi_server_attach(&server, node_loop());
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,25 +536,23 @@ server_constructor (const Arguments& args)
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return Undefined(); // XXX raise error?
|
return Undefined(); // XXX raise error?
|
||||||
|
|
||||||
printf("Running at http://localhost:%s/\n", *port);
|
|
||||||
|
|
||||||
return args.This();
|
return args.This();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Object>
|
void
|
||||||
node_http_initialize (struct ev_loop *_loop)
|
node_http_initialize (Handle<Object> target)
|
||||||
{
|
{
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
|
|
||||||
loop = _loop;
|
|
||||||
|
|
||||||
Local<Object> http = Object::New();
|
Local<Object> http = Object::New();
|
||||||
|
target->Set (String::NewSymbol("HTTP"), http);
|
||||||
|
|
||||||
Local<FunctionTemplate> server_t = FunctionTemplate::New(server_constructor);
|
Local<FunctionTemplate> server_t = FunctionTemplate::New(server_constructor);
|
||||||
server_t->InstanceTemplate()->SetInternalFieldCount(1);
|
server_t->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
|
|
||||||
http->Set(String::New("Server"), server_t->GetFunction());
|
http->Set(String::New("Server"), server_t->GetFunction());
|
||||||
|
|
||||||
|
|
||||||
path_str = Persistent<String>::New( String::NewSymbol("path") );
|
path_str = Persistent<String>::New( String::NewSymbol("path") );
|
||||||
uri_str = Persistent<String>::New( String::NewSymbol("uri") );
|
uri_str = Persistent<String>::New( String::NewSymbol("uri") );
|
||||||
query_string_str = Persistent<String>::New( String::NewSymbol("query_string") );
|
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") );
|
put_str = Persistent<String>::New( String::New("PUT") );
|
||||||
trace_str = Persistent<String>::New( String::New("TRACE") );
|
trace_str = Persistent<String>::New( String::New("TRACE") );
|
||||||
unlock_str = Persistent<String>::New( String::New("UNLOCK") );
|
unlock_str = Persistent<String>::New( String::New("UNLOCK") );
|
||||||
|
|
||||||
return scope.Close(http);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,7 @@
|
||||||
#define node_http_h
|
#define node_http_h
|
||||||
|
|
||||||
#include <v8.h>
|
#include <v8.h>
|
||||||
#include <ev.h>
|
|
||||||
|
|
||||||
using namespace v8;
|
void node_http_initialize (v8::Handle<v8::Object> target);
|
||||||
|
|
||||||
Handle<Object> node_http_initialize (struct ev_loop *);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
23
node_tcp.cc
23
node_tcp.cc
|
@ -1,4 +1,5 @@
|
||||||
#include "node_tcp.h"
|
#include "node_tcp.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
#include <oi_socket.h>
|
#include <oi_socket.h>
|
||||||
#include <oi_async.h>
|
#include <oi_async.h>
|
||||||
|
@ -7,6 +8,7 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
|
using namespace v8;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -50,8 +52,6 @@ static struct addrinfo tcp_hints =
|
||||||
/* ai_next */ , 0
|
/* ai_next */ , 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ev_loop *loop;
|
|
||||||
|
|
||||||
class TCPClient {
|
class TCPClient {
|
||||||
public:
|
public:
|
||||||
oi_task resolve_task;
|
oi_task resolve_task;
|
||||||
|
@ -110,8 +110,7 @@ static void resolve_done
|
||||||
client->socket.data = client;
|
client->socket.data = client;
|
||||||
|
|
||||||
oi_socket_connect (&client->socket, client->address);
|
oi_socket_connect (&client->socket, client->address);
|
||||||
oi_socket_attach (&client->socket, loop);
|
oi_socket_attach (&client->socket, node_loop());
|
||||||
|
|
||||||
|
|
||||||
freeaddrinfo(client->address);
|
freeaddrinfo(client->address);
|
||||||
client->address = NULL;
|
client->address = NULL;
|
||||||
|
@ -166,21 +165,17 @@ static Handle<Value> Connect
|
||||||
oi_async_submit (&thread_pool, &client->resolve_task);
|
oi_async_submit (&thread_pool, &client->resolve_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Object> node_tcp_initialize
|
void
|
||||||
( struct ev_loop *_loop
|
node_tcp_initialize (Handle<Object> target)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
loop = _loop;
|
|
||||||
|
|
||||||
oi_async_init(&thread_pool);
|
oi_async_init(&thread_pool);
|
||||||
oi_async_attach(loop, &thread_pool);
|
oi_async_attach(node_loop(), &thread_pool);
|
||||||
|
|
||||||
HandleScope scope;
|
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());
|
tcp->Set(String::NewSymbol("connect"), FunctionTemplate::New(Connect)->GetFunction());
|
||||||
|
|
||||||
return scope.Close(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,7 @@
|
||||||
#define node_tcp_h
|
#define node_tcp_h
|
||||||
|
|
||||||
#include <v8.h>
|
#include <v8.h>
|
||||||
#include <ev.h>
|
|
||||||
|
|
||||||
using namespace v8;
|
void node_tcp_initialize (v8::Handle<v8::Object> target);
|
||||||
|
|
||||||
Handle<Object> node_tcp_initialize (struct ev_loop *);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <ev.h>
|
#include "node.h"
|
||||||
#include <v8.h>
|
#include "node_timer.h"
|
||||||
|
|
||||||
using namespace v8;
|
using namespace v8;
|
||||||
static struct ev_loop *loop;
|
|
||||||
|
|
||||||
class Timer {
|
class Timer {
|
||||||
public:
|
public:
|
||||||
|
@ -37,12 +37,12 @@ Timer::Timer (Handle<Function> _callback, int _argc, Handle<Value> _argv[], ev_t
|
||||||
|
|
||||||
ev_timer_init (&watcher, onTimeout, after, repeat);
|
ev_timer_init (&watcher, onTimeout, after, repeat);
|
||||||
watcher.data = this;
|
watcher.data = this;
|
||||||
ev_timer_start (loop, &watcher);
|
ev_timer_start (node_loop(), &watcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer::~Timer ()
|
Timer::~Timer ()
|
||||||
{
|
{
|
||||||
ev_timer_stop (loop, &watcher);
|
ev_timer_stop (node_loop(), &watcher);
|
||||||
|
|
||||||
callback.Dispose();
|
callback.Dispose();
|
||||||
|
|
||||||
|
@ -57,11 +57,10 @@ Timer::CallCallback ()
|
||||||
|
|
||||||
TryCatch try_catch;
|
TryCatch try_catch;
|
||||||
|
|
||||||
Handle<Value> r = callback->Call (Context::GetCurrent()->Global(), argc, argv);
|
callback->Call (Context::GetCurrent()->Global(), argc, argv);
|
||||||
if (r.IsEmpty()) {
|
|
||||||
String::Utf8Value error(try_catch.Exception());
|
if(try_catch.HasCaught())
|
||||||
printf("timer callback error: %s\n", *error);
|
node_fatal_exception(try_catch);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Local<External>
|
Local<External>
|
||||||
|
@ -166,10 +165,8 @@ static Handle<Value> setInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
node_timer_initialize (Handle<Object> target, struct ev_loop *_loop)
|
node_timer_initialize (Handle<Object> target)
|
||||||
{
|
{
|
||||||
loop = _loop;
|
|
||||||
|
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
|
|
||||||
target->Set ( String::New("setTimeout")
|
target->Set ( String::New("setTimeout")
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
#ifndef node_timer_h
|
#ifndef node_timer_h
|
||||||
#define node_timer_h
|
#define node_timer_h
|
||||||
|
|
||||||
#include <ev.h>
|
|
||||||
#include <v8.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
|
#endif // node_timer_h
|
||||||
|
|
Загрузка…
Ссылка в новой задаче