From 74a8215a8699f89ee4b82ca616a4eafa3b11203b Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 3 Feb 2012 16:32:00 +0100 Subject: [PATCH] Revert support for isolates. It was decided that the performance benefits that isolates offer (faster spin-up times for worker processes, faster inter-worker communication, possibly a lower memory footprint) are not actual bottlenecks for most people and do not outweigh the potential stability issues and intrusive changes to the code base that first-class support for isolates requires. Hence, this commit backs out all isolates-related changes. Good bye, isolates. We hardly knew ye. --- configure | 6 - lib/_debugger.js | 64 +- lib/child_process.js | 69 +- node.gyp | 12 - src/cares_wrap.cc | 19 +- src/fs_event_wrap.cc | 9 +- src/handle_wrap.cc | 5 +- src/ngx-queue.h | 109 ---- src/node.cc | 280 ++++---- src/node.h | 4 - src/node.js | 32 - src/node_buffer.cc | 68 +- src/node_buffer.h | 1 + src/node_crypto.cc | 47 +- src/node_extensions.h | 4 - src/node_file.cc | 54 +- src/node_http_parser.cc | 98 +-- src/node_internals.h | 15 - src/node_isolate.cc | 815 ------------------------ src/node_isolate.h | 185 ------ src/node_script.cc | 51 +- src/node_signal_watcher.cc | 21 +- src/node_vars.cc | 48 -- src/node_vars.h | 197 ------ src/node_zlib.cc | 8 +- src/pipe_wrap.cc | 9 +- src/process_wrap.cc | 7 +- src/stream_wrap.cc | 41 +- src/tcp_wrap.cc | 42 +- src/timer_wrap.cc | 19 +- src/tty_wrap.cc | 7 +- src/udp_wrap.cc | 17 +- test/addons/shared-buffer/binding.cc | 55 -- test/addons/shared-buffer/binding.gyp | 8 - test/addons/shared-buffer/test.js | 19 - test/simple/test-child-process-fork.js | 8 +- test/simple/test-child-process-fork2.js | 6 +- test/simple/test-child-process-fork3.js | 6 +- test/simple/test-debugger-repl-utf8.js | 19 +- test/simple/test-debugger-repl.js | 19 +- test/simple/test-isolates-ping-pong.js | 68 -- test/simple/test-isolates0.js | 60 -- test/simple/test-isolates1.js | 13 - test/simple/test-isolates2.js | 13 - test/simple/test-isolates3.js | 13 - 45 files changed, 413 insertions(+), 2257 deletions(-) delete mode 100644 src/ngx-queue.h delete mode 100644 src/node_isolate.cc delete mode 100644 src/node_isolate.h delete mode 100644 src/node_vars.cc delete mode 100644 src/node_vars.h delete mode 100644 test/addons/shared-buffer/binding.cc delete mode 100644 test/addons/shared-buffer/binding.gyp delete mode 100644 test/addons/shared-buffer/test.js delete mode 100644 test/simple/test-isolates-ping-pong.js delete mode 100644 test/simple/test-isolates0.js delete mode 100644 test/simple/test-isolates1.js delete mode 100644 test/simple/test-isolates2.js delete mode 100644 test/simple/test-isolates3.js diff --git a/configure b/configure index d9ef98e3a4..3575346110 100755 --- a/configure +++ b/configure @@ -32,11 +32,6 @@ parser.add_option("--without-waf", dest="without_waf", help="Don\'t install node-waf") -parser.add_option("--without-isolates", - action="store_true", - dest="without_isolates", - help="Build without isolates (no threads, single loop) [Default: False]") - parser.add_option("--without-ssl", action="store_true", dest="without_ssl", @@ -172,7 +167,6 @@ def target_arch(): def configure_node(o): # TODO add gdb - o['variables']['node_use_isolates'] = b(not options.without_isolates) o['variables']['node_prefix'] = options.prefix if options.prefix else '' o['variables']['node_use_dtrace'] = b(options.with_dtrace) o['variables']['node_install_npm'] = b(not options.without_npm) diff --git a/lib/_debugger.js b/lib/_debugger.js index c3f0631fad..00de2b1e70 100644 --- a/lib/_debugger.js +++ b/lib/_debugger.js @@ -25,7 +25,7 @@ var util = require('util'), vm = require('vm'), repl = require('repl'), inherits = util.inherits, - fork = require('child_process').fork; + spawn = require('child_process').spawn; exports.start = function(argv, stdin, stdout) { argv || (argv = process.argv.slice(2)); @@ -39,7 +39,7 @@ exports.start = function(argv, stdin, stdout) { stdin = stdin || process.openStdin(); stdout = stdout || process.stdout; - var args = argv, + var args = ['--debug-brk'].concat(argv), interface = new Interface(stdin, stdout, args); stdin.resume(); @@ -169,8 +169,6 @@ function Client() { this.scripts = {}; this.breakpoints = []; - this.isolates = process.features.isolates; - // Note that 'Protocol' requires strings instead of Buffers. socket.setEncoding('utf8'); socket.on('data', function(d) { @@ -1597,51 +1595,20 @@ Interface.prototype.trySpawn = function(cb) { } } - var client = self.client = new Client(), - connectionAttempts = 0; - if (!this.child) { - if (client.isolates) { - this.child = fork(this.args.shift(), this.args, { - thread: true, - debug: function(d) { - d.onmessage = function(event) { - client._onResponse({ - headers: {}, - body: JSON.parse(event) - }); - }; - - // Monkey patch client to send requests directly to debugger - client.req = function(req, cb) { - req.type = 'request'; - cb.request_seq = req.seq = this.protocol.reqSeq++; - this._reqCallbacks.push(cb); - - d.write(JSON.stringify(req)); - }; - - client.emit('ready'); - - client._onResponse({ - headers: { Type: 'connect' }, - body: {} - }); - }, - debugBrk: true - }); - this.child.kill = function() { - self.error('isolate.kill is not implemented yet!'); - }; - } else { - this.child = fork('--debug-brk', this.args); - } + this.child = spawn(process.execPath, this.args); + + this.child.stdout.on('data', this.childPrint.bind(this)); + this.child.stderr.on('data', this.childPrint.bind(this)); } this.pause(); + var client = self.client = new Client(), + connectionAttempts = 0; + client.once('ready', function() { - if (!client.isolates) self.stdout.write(' ok\n'); + self.stdout.write(' ok\n'); // Restore breakpoints breakpoints.forEach(function(bp) { @@ -1689,14 +1656,11 @@ Interface.prototype.trySpawn = function(cb) { function attemptConnect() { ++connectionAttempts; self.stdout.write('.'); - client.connect(port, host); } - if (!client.isolates) { - setTimeout(function() { - self.print('connecting..', true); - attemptConnect(); - }, 50); - } + setTimeout(function() { + self.print('connecting..', true); + attemptConnect(); + }, 50); }; diff --git a/lib/child_process.js b/lib/child_process.js index 9723730ce7..9c1193daa2 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -209,11 +209,11 @@ exports.fork = function(modulePath /*, args, options*/) { options.env.NODE_CHANNEL_FD = 42; // stdin is the IPC channel. - if (!options.thread) options.stdinStream = createPipe(true); + options.stdinStream = createPipe(true); var child = spawn(process.execPath, args, options); - if (!options.thread) setupChannel(child, options.stdinStream); + setupChannel(child, options.stdinStream); return child; }; @@ -370,7 +370,7 @@ var spawn = exports.spawn = function(file, args, options) { envPairs.push(key + '=' + env[key]); } - var child = (options && options.thread) ? (new Isolate) : (new ChildProcess); + var child = new ChildProcess(); child.spawn({ file: file, @@ -379,8 +379,7 @@ var spawn = exports.spawn = function(file, args, options) { windowsVerbatimArguments: !!(options && options.windowsVerbatimArguments), envPairs: envPairs, customFds: options ? options.customFds : null, - stdinStream: options ? options.stdinStream : null, - options: options + stdinStream: options ? options.stdinStream : null }); return child; @@ -537,63 +536,3 @@ ChildProcess.prototype.kill = function(sig) { // TODO: raise error if r == -1? } }; - - -// Lazy loaded. -var isolates = null; - - -function Isolate() { - if (!process.features.isolates) { - throw new Error('Compiled without isolates support.'); - } - - if (!isolates) { - isolates = process.binding('isolates'); - } - - this._handle = null; -} -inherits(Isolate, EventEmitter); // maybe inherit from ChildProcess? - - -Isolate.prototype.spawn = function(options) { - var self = this; - - if (self._handle) throw new Error('Isolate already running.'); - self._handle = isolates.create(options.args, options.options); - if (!self._handle) throw new Error('Cannot create isolate.'); - - self._handle.onmessage = function(msg, recvHandle) { - msg = JSON.parse('' + msg); - - // Update simultaneous accepts on Windows - net._setSimultaneousAccepts(recvHandle); - - self.emit('message', msg, recvHandle); - }; - - self._handle.onexit = function() { - self._handle = null; - self.emit('exit'); - }; -}; - - -Isolate.prototype.kill = function(sig) { - if (!this._handle) throw new Error('Isolate not running.'); - // ignore silently for now, need a way to signal the other thread -}; - - -Isolate.prototype.send = function(msg, sendHandle) { - if (typeof msg === 'undefined') throw new TypeError('Bad argument.'); - if (!this._handle) throw new Error('Isolate not running.'); - msg = JSON.stringify(msg); - msg = new Buffer(msg); - - // Update simultaneous accepts on Windows - net._setSimultaneousAccepts(sendHandle); - - return this._handle.send(msg, sendHandle); -}; diff --git a/node.gyp b/node.gyp index d23d1e4ace..e08f447ba6 100644 --- a/node.gyp +++ b/node.gyp @@ -8,7 +8,6 @@ 'node_use_dtrace': 'false', 'node_use_openssl%': 'true', 'node_use_system_openssl%': 'false', - 'node_use_isolates%': 'true', 'library_files': [ 'src/node.js', 'lib/_debugger.js', @@ -73,9 +72,7 @@ 'src/cares_wrap.cc', 'src/handle_wrap.cc', 'src/node.cc', - 'src/node_vars.cc', 'src/node_buffer.cc', - 'src/node_isolate.cc', 'src/node_constants.cc', 'src/node_extensions.cc', 'src/node_file.cc', @@ -95,12 +92,9 @@ 'src/v8_typed_array.cc', 'src/udp_wrap.cc', # headers to make for a more pleasant IDE experience - 'src/ngx-queue.h', 'src/handle_wrap.h', 'src/node.h', - 'src/node_vars.h', 'src/node_buffer.h', - 'src/node_isolate.h', 'src/node_constants.h', 'src/node_crypto.h', 'src/node_extensions.h', @@ -133,12 +127,6 @@ ], 'conditions': [ - [ 'node_use_isolates=="true"', { - 'defines': [ 'HAVE_ISOLATES=1' ], - }, { - 'defines': [ 'HAVE_ISOLATES=0' ], - }], - [ 'node_use_openssl=="true"', { 'defines': [ 'HAVE_OPENSSL=1' ], 'sources': [ 'src/node_crypto.cc' ], diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 64e96581b0..a881c25b07 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -49,11 +48,6 @@ #endif -#include -#define oncomplete_sym NODE_VAR(oncomplete_sym) -#define ares_channel NODE_VAR(ares_channel) - - namespace node { namespace cares_wrap { @@ -75,6 +69,11 @@ using v8::Value; typedef class ReqWrap GetAddrInfoReqWrap; +static Persistent oncomplete_sym; + +static ares_channel ares_channel; + + static Local HostentToAddresses(struct hostent* host) { HandleScope scope; Local addresses = Array::New(); @@ -608,7 +607,7 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { if (status) { // Error - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); argv[0] = Local::New(Null()); } else { // Success @@ -711,7 +710,7 @@ static Handle GetAddrInfo(const Arguments& args) { hints.ai_family = fam; hints.ai_socktype = SOCK_STREAM; - int r = uv_getaddrinfo(Loop(), + int r = uv_getaddrinfo(uv_default_loop(), &req_wrap->req_, AfterGetAddrInfo, *hostname, @@ -720,7 +719,7 @@ static Handle GetAddrInfo(const Arguments& args) { req_wrap->Dispatched(); if (r) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); delete req_wrap; return scope.Close(v8::Null()); } else { @@ -737,7 +736,7 @@ static void Initialize(Handle target) { assert(r == ARES_SUCCESS); struct ares_options options; - uv_ares_init_options(Loop(), &ares_channel, &options, 0); + uv_ares_init_options(uv_default_loop(), &ares_channel, &options, 0); assert(r == 0); NODE_SET_METHOD(target, "queryA", Query); diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc index 1f99e856a8..48cdabc00e 100644 --- a/src/fs_event_wrap.cc +++ b/src/fs_event_wrap.cc @@ -21,7 +21,6 @@ #include #include -#include #include @@ -110,15 +109,15 @@ Handle FSEventWrap::Start(const Arguments& args) { String::Utf8Value path(args[0]->ToString()); - int r = uv_fs_event_init(Loop(), &wrap->handle_, *path, OnEvent, 0); + int r = uv_fs_event_init(uv_default_loop(), &wrap->handle_, *path, OnEvent, 0); if (r == 0) { // Check for persistent argument if (!args[1]->IsTrue()) { - uv_unref(Loop()); + uv_unref(uv_default_loop()); } wrap->initialized_ = true; } else { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); } return scope.Close(Integer::New(r)); @@ -146,7 +145,7 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename, // assumption that a rename implicitly means an attribute change. Not too // unreasonable, right? Still, we should revisit this before v1.0. if (status) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); eventStr = String::Empty(); } else if (events & UV_RENAME) { diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc index 86c2a9e670..eb6713edad 100644 --- a/src/handle_wrap.cc +++ b/src/handle_wrap.cc @@ -21,7 +21,6 @@ #include #include -#include namespace node { @@ -71,7 +70,7 @@ Handle HandleWrap::Unref(const Arguments& args) { } wrap->unref = true; - uv_unref(Loop()); + uv_unref(uv_default_loop()); return v8::Undefined(); } @@ -89,7 +88,7 @@ Handle HandleWrap::Ref(const Arguments& args) { } wrap->unref = false; - uv_ref(Loop()); + uv_ref(uv_default_loop()); return v8::Undefined(); } diff --git a/src/ngx-queue.h b/src/ngx-queue.h deleted file mode 100644 index 5d077c5d13..0000000000 --- a/src/ngx-queue.h +++ /dev/null @@ -1,109 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - */ - - -#ifndef _NGX_QUEUE_H_INCLUDED_ -#define _NGX_QUEUE_H_INCLUDED_ - -#ifdef _WIN32 -# include -#endif - -typedef struct ngx_queue_s ngx_queue_t; - -struct ngx_queue_s { - ngx_queue_t *prev; - ngx_queue_t *next; -}; - - -#define ngx_queue_init(q) \ - (q)->prev = q; \ - (q)->next = q - - -#define ngx_queue_empty(h) \ - (h == (h)->prev) - - -#define ngx_queue_insert_head(h, x) \ - (x)->next = (h)->next; \ - (x)->next->prev = x; \ - (x)->prev = h; \ - (h)->next = x - - -#define ngx_queue_insert_after ngx_queue_insert_head - - -#define ngx_queue_insert_tail(h, x) \ - (x)->prev = (h)->prev; \ - (x)->prev->next = x; \ - (x)->next = h; \ - (h)->prev = x - - -#define ngx_queue_head(h) \ - (h)->next - - -#define ngx_queue_last(h) \ - (h)->prev - - -#define ngx_queue_sentinel(h) \ - (h) - - -#define ngx_queue_next(q) \ - (q)->next - - -#define ngx_queue_prev(q) \ - (q)->prev - - -#if (NGX_DEBUG) - -#define ngx_queue_remove(x) \ - (x)->next->prev = (x)->prev; \ - (x)->prev->next = (x)->next; \ - (x)->prev = NULL; \ - (x)->next = NULL - -#else - -#define ngx_queue_remove(x) \ - (x)->next->prev = (x)->prev; \ - (x)->prev->next = (x)->next - -#endif - - -#define ngx_queue_split(h, q, n) \ - (n)->prev = (h)->prev; \ - (n)->prev->next = n; \ - (n)->next = q; \ - (h)->prev = (q)->prev; \ - (h)->prev->next = h; \ - (q)->prev = n; - - -#define ngx_queue_add(h, n) \ - (h)->prev->next = (n)->next; \ - (n)->next->prev = (h)->prev; \ - (h)->prev = (n)->prev; \ - (h)->prev->next = h; - - -#define ngx_queue_data(q, type, link) \ - (type *) ((unsigned char *) q - offsetof(type, link)) - - -#define ngx_queue_foreach(q, h) \ - for ((q) = ngx_queue_head(h); (q) != (h); (q) = ngx_queue_next(q)) - - -#endif /* _NGX_QUEUE_H_INCLUDED_ */ diff --git a/src/node.cc b/src/node.cc index 5ae4f0c11e..ab755d743b 100644 --- a/src/node.cc +++ b/src/node.cc @@ -20,8 +20,6 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. #include -#include -#include #include @@ -92,65 +90,81 @@ using namespace v8; extern char **environ; # endif +namespace node { -#include - -// We do the following to minimize the detal between v0.6 branch. We want to -// use the variables as they were being used before. -#define check_tick_watcher NODE_VAR(check_tick_watcher) -#define code_symbol NODE_VAR(code_symbol) -#define emit_symbol NODE_VAR(emit_symbol) -#define errno_symbol NODE_VAR(errno_symbol) -#define errpath_symbol NODE_VAR(errpath_symbol) -#define gc_check NODE_VAR(gc_check) -#define gc_idle NODE_VAR(gc_idle) -#define gc_timer NODE_VAR(gc_timer) -#define getbuf NODE_VAR(getbuf) -#define heap_total_symbol NODE_VAR(heap_total_symbol) -#define heap_used_symbol NODE_VAR(heap_used_symbol) -#define listeners_symbol NODE_VAR(listeners_symbol) -#define need_tick_cb NODE_VAR(need_tick_cb) -#define prepare_tick_watcher NODE_VAR(prepare_tick_watcher) -#define process NODE_VAR(process) -#define rss_symbol NODE_VAR(rss_symbol) -#define syscall_symbol NODE_VAR(syscall_symbol) -#define tick_callback_sym NODE_VAR(tick_callback_sym) -#define tick_spinner NODE_VAR(tick_spinner) -#define tick_time_head NODE_VAR(tick_time_head) -#define tick_times NODE_VAR(tick_times) -#define uncaught_exception_symbol NODE_VAR(uncaught_exception_symbol) -#define use_npn NODE_VAR(use_npn) -#define use_sni NODE_VAR(use_sni) -#define uncaught_exception_counter NODE_VAR(uncaught_exception_counter) -#define binding_cache NODE_VAR(binding_cache) -#define module_load_list NODE_VAR(module_load_list) -#define node_isolate NODE_VAR(node_isolate) -#define debugger_running NODE_VAR(debugger_running) -#define prog_start_time NODE_VAR(prog_start_time) -namespace node { +static Persistent process; -#define TICK_TIME(n) tick_times[(tick_time_head - (n)) % RPM_SAMPLES] +static Persistent errno_symbol; +static Persistent syscall_symbol; +static Persistent errpath_symbol; +static Persistent code_symbol; -static int option_end_index; -static unsigned long max_stack_size; -static unsigned short debug_port = 5858; -static bool debug_wait_connect; -static bool use_debug_agent; -static const char* eval_string; -static bool print_eval; +static Persistent rss_symbol; +static Persistent heap_total_symbol; +static Persistent heap_used_symbol; -static void CheckStatus(uv_timer_t* watcher, int status); +static Persistent listeners_symbol; +static Persistent uncaught_exception_symbol; +static Persistent emit_symbol; + + +static bool print_eval = false; +static char *eval_string = NULL; +static int option_end_index = 0; +static bool use_debug_agent = false; +static bool debug_wait_connect = false; +static int debug_port=5858; +static int max_stack_size = 0; +static uv_check_t check_tick_watcher; +static uv_prepare_t prepare_tick_watcher; +static uv_idle_t tick_spinner; +static bool need_tick_cb; +static Persistent tick_callback_sym; -uv_loop_t* Loop() { -#if defined(HAVE_ISOLATES) && HAVE_ISOLATES - return Isolate::GetCurrent()->GetLoop(); + +#ifdef OPENSSL_NPN_NEGOTIATED +static bool use_npn = true; #else - return uv_default_loop(); +static bool use_npn = false; #endif -} +#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB +static bool use_sni = true; +#else +static bool use_sni = false; +#endif + +#ifdef __POSIX__ +// Buffer for getpwnam_r(), getgrpam_r() and other misc callers; keep this +// scoped at file-level rather than method-level to avoid excess stack usage. +static char getbuf[PATH_MAX + 1]; +#endif + +// We need to notify V8 when we're idle so that it can run the garbage +// collector. The interface to this is V8::IdleNotification(). It returns +// true if the heap hasn't be fully compacted, and needs to be run again. +// Returning false means that it doesn't have anymore work to do. +// +// A rather convoluted algorithm has been devised to determine when Node is +// idle. You'll have to figure it out for yourself. +static uv_check_t gc_check; +static uv_idle_t gc_idle; +static uv_timer_t gc_timer; +bool need_gc; + +// process-relative uptime base, initialized at start-up +static double prog_start_time; + +#define FAST_TICK 700. +#define GC_WAIT_TIME 5000. +#define RPM_SAMPLES 100 +#define TICK_TIME(n) tick_times[(tick_time_head - (n)) % RPM_SAMPLES] +static int64_t tick_times[RPM_SAMPLES]; +static int tick_time_head; + +static void CheckStatus(uv_timer_t* watcher, int status); static void StartGCTimer () { if (!uv_is_active((uv_handle_t*) &gc_timer)) { @@ -178,7 +192,7 @@ static void Idle(uv_idle_t* watcher, int status) { static void Check(uv_check_t* watcher, int status) { assert(watcher == &gc_check); - tick_times[tick_time_head] = uv_now(Loop()); + tick_times[tick_time_head] = uv_now(uv_default_loop()); tick_time_head = (tick_time_head + 1) % RPM_SAMPLES; StartGCTimer(); @@ -208,7 +222,7 @@ static void Tick(void) { need_tick_cb = false; if (uv_is_active((uv_handle_t*) &tick_spinner)) { uv_idle_stop(&tick_spinner); - uv_unref(Loop()); + uv_unref(uv_default_loop()); } HandleScope scope; @@ -250,7 +264,7 @@ static Handle NeedTickCallback(const Arguments& args) { // tick_spinner to keep the event loop alive long enough to handle it. if (!uv_is_active((uv_handle_t*) &tick_spinner)) { uv_idle_start(&tick_spinner, Spin); - uv_ref(Loop()); + uv_ref(uv_default_loop()); } return Undefined(); } @@ -1506,7 +1520,7 @@ static void CheckStatus(uv_timer_t* watcher, int status) { } } - double d = uv_now(Loop()) - TICK_TIME(3); + double d = uv_now(uv_default_loop()) - TICK_TIME(3); //printfb("timer d = %f\n", d); @@ -1535,7 +1549,7 @@ static Handle Uptime(const Arguments& args) { v8::Handle UVCounters(const v8::Arguments& args) { HandleScope scope; - uv_counters_t* c = &Loop()->counters; + uv_counters_t* c = &uv_default_loop()->counters; Local obj = Object::New(); @@ -1730,6 +1744,7 @@ static void OnFatalError(const char* location, const char* message) { exit(1); } +static int uncaught_exception_counter = 0; void FatalException(TryCatch &try_catch) { HandleScope scope; @@ -1789,6 +1804,9 @@ static void DebugBreakMessageHandler(const v8::Debug::Message& message) { } +Persistent binding_cache; +Persistent module_load_list; + static Handle Binding(const Arguments& args) { HandleScope scope; @@ -1974,15 +1992,6 @@ static Handle GetFeatures() { obj->Set(String::NewSymbol("tls"), Boolean::New(get_builtin_module("crypto") != NULL)); - - obj->Set(String::NewSymbol("isolates"), -#if HAVE_ISOLATES - True() -#else - False() -#endif - ); - return scope.Close(obj); } @@ -1999,6 +2008,7 @@ Handle SetupProcessObject(int argc, char *argv[]) { process = Persistent::New(process_template->GetFunction()->NewInstance()); + process->SetAccessor(String::New("title"), ProcessTitleGetter, ProcessTitleSetter); @@ -2292,6 +2302,9 @@ static void ParseArgs(int argc, char **argv) { } +static Isolate* node_isolate = NULL; +static volatile bool debugger_running = false; + static void EnableDebug(bool wait_connect) { // If we're called from another thread, make sure to enter the right // v8 isolate. @@ -2322,7 +2335,6 @@ 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); @@ -2525,7 +2537,10 @@ static Handle DebugPause(const Arguments& args) { } -char** ProcessInit(int argc, char *argv[]) { +char** Init(int argc, char *argv[]) { + // Initialize prog_start_time to get relative uptime. + uv_uptime(&prog_start_time); + // Hack aroung with the argv pointer. Used for process.title = "blah". argv = uv_setup_args(argc, argv); @@ -2565,100 +2580,79 @@ char** ProcessInit(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__ - return argv; -} - - -void EmitExit(v8::Handle process_l) { - // process.emit('exit') - Local emit_v = process_l->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_l, 1, args); - if (try_catch.HasCaught()) { - FatalException(try_catch); - } -} - - -// Create a new isolate with node::Isolate::New() before you call this function -void StartThread(node::Isolate* isolate, - int argc, - char** argv) { - HandleScope scope; - - assert(node::Isolate::GetCurrent() == isolate); - - uv_loop_t* loop = isolate->GetLoop(); - uv_prepare_init(loop, &prepare_tick_watcher); + uv_prepare_init(uv_default_loop(), &prepare_tick_watcher); uv_prepare_start(&prepare_tick_watcher, PrepareTick); - uv_unref(loop); + uv_unref(uv_default_loop()); - uv_check_init(loop, &check_tick_watcher); + uv_check_init(uv_default_loop(), &check_tick_watcher); uv_check_start(&check_tick_watcher, node::CheckTick); - uv_unref(loop); + uv_unref(uv_default_loop()); - uv_idle_init(loop, &tick_spinner); - uv_unref(loop); + uv_idle_init(uv_default_loop(), &tick_spinner); + uv_unref(uv_default_loop()); - uv_check_init(loop, &gc_check); + uv_check_init(uv_default_loop(), &gc_check); uv_check_start(&gc_check, node::Check); - uv_unref(loop); + uv_unref(uv_default_loop()); - uv_idle_init(loop, &gc_idle); - uv_unref(loop); + uv_idle_init(uv_default_loop(), &gc_idle); + uv_unref(uv_default_loop()); - uv_timer_init(loop, &gc_timer); - uv_unref(loop); + uv_timer_init(uv_default_loop(), &gc_timer); + uv_unref(uv_default_loop()); V8::SetFatalErrorHandler(node::OnFatalError); // Fetch a reference to the main isolate, so we have a reference to it // even when we need it to access it from another (debugger) thread. - node_isolate = v8::Isolate::GetCurrent(); + node_isolate = Isolate::GetCurrent(); - // Only main isolate is allowed to run a debug agent and listen for signals - if (isolate->id_ == 1) { - // If the --debug flag was specified then initialize the debug thread. - if (use_debug_agent) { - EnableDebug(debug_wait_connect); - } else { + // If the --debug flag was specified then initialize the debug thread. + if (use_debug_agent) { + EnableDebug(debug_wait_connect); + } else { #ifdef _WIN32 - RegisterDebugSignalHandler(); + RegisterDebugSignalHandler(); #else // Posix - RegisterSignalHandler(SIGUSR1, EnableDebugSignalHandler); + RegisterSignalHandler(SIGUSR1, EnableDebugSignalHandler); #endif // __POSIX__ - } - } else if (isolate->debug_state != Isolate::kNone) { - isolate->debugger_instance->Init(); } - Handle process_l = SetupProcessObject(argc, argv); - - process_l->Set(String::NewSymbol("tid"), - Integer::NewFromUnsigned(isolate->id_)); + return argv; +} - // TODO check (isolate->channel_ != NULL) - if (isolate->id_ > 1) { - process_l->Set(String::NewSymbol("_send"), - FunctionTemplate::New(Isolate::Send)->GetFunction()); - process_l->Set(String::NewSymbol("_exit"), - FunctionTemplate::New(Isolate::Unref)->GetFunction()); +void EmitExit(v8::Handle process_l) { + // process.emit('exit') + Local emit_v = process_l->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_l, 1, args); + if (try_catch.HasCaught()) { + FatalException(try_catch); } +} - // FIXME crashes with "CHECK(heap->isolate() == Isolate::Current()) failed" - //v8_typed_array::AttachBindings(v8::Context::GetCurrent()->Global()); - // Initialize prog_start_time to get relative uptime. - uv_uptime(&prog_start_time); +int Start(int argc, char *argv[]) { + // This needs to run *before* V8::Initialize() + argv = Init(argc, argv); + + v8::V8::Initialize(); + v8::HandleScope handle_scope; + + // Create the one and only Context. + Persistent context = v8::Context::New(); + v8::Context::Scope context_scope(context); + + Handle 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()! @@ -2669,29 +2663,13 @@ void StartThread(node::Isolate* isolate, // 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); + uv_run(uv_default_loop()); EmitExit(process_l); -} - - -int Start(int argc, char *argv[]) { - // This needs to run *before* V8::Initialize() - argv = ProcessInit(argc, argv); - - v8::V8::Initialize(); - v8::HandleScope handle_scope; - - // Create the main node::Isolate object - node::Isolate::Initialize(); - Isolate* isolate = new node::Isolate(); - isolate->tid_ = (uv_thread_t) -1; - isolate->Enter(); - StartThread(isolate, argc, argv); - isolate->Dispose(); #ifndef NDEBUG // Clean up. + context.Dispose(); V8::Dispose(); #endif // NDEBUG diff --git a/src/node.h b/src/node.h index 9acc75c32d..703c74478e 100644 --- a/src/node.h +++ b/src/node.h @@ -84,10 +84,6 @@ v8::Handle SetupProcessObject(int argc, char *argv[]); void Load(v8::Handle process); void EmitExit(v8::Handle process); -// Returns the loop for the current isolate. If compiled with -// --without-isolates then this will always return uv_default_loop(); -uv_loop_t* Loop(); - #define NODE_PSYMBOL(s) \ v8::Persistent::New(v8::String::NewSymbol(s)) diff --git a/src/node.js b/src/node.js index bc76d671d6..d179c8821c 100644 --- a/src/node.js +++ b/src/node.js @@ -120,33 +120,6 @@ }); } } - - if (process.tid === 1) return; - - var net = NativeModule.require('net'); - - // isolate initialization - process.send = function(msg, sendHandle) { - if (typeof msg === 'undefined') throw new TypeError('Bad argument.'); - msg = JSON.stringify(msg); - msg = new Buffer(msg); - - // Update simultaneous accepts on Windows - net._setSimultaneousAccepts(sendHandle); - - return process._send(msg, sendHandle); - }; - - process._onmessage = function(msg, recvHandle) { - msg = JSON.parse('' + msg); - - // Update simultaneous accepts on Windows - net._setSimultaneousAccepts(recvHandle); - - process.emit('message', msg, recvHandle); - }; - - process.exit = process._exit; } startup.globalVariables = function() { @@ -455,11 +428,6 @@ cp._forkChild(); assert(process.send); - } else if (process.tid !== 1) { - // Load tcp_wrap to avoid situation where we might immediately receive - // a message. - // FIXME is this really necessary? - process.binding('tcp_wrap'); } } diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 71e7ff36cf..924eff3b8f 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -36,12 +36,6 @@ #define MIN(a,b) ((a) < (b) ? (a) : (b)) -#include -#define length_symbol NODE_VAR(length_symbol) -#define chars_written_sym NODE_VAR(chars_written_sym) -#define write_sym NODE_VAR(write_sym) -#define buffer_constructor_template NODE_VAR(buffer_constructor_template) - namespace node { using namespace v8; @@ -67,6 +61,10 @@ using namespace v8; } +static Persistent length_symbol; +static Persistent chars_written_sym; +static Persistent write_sym; +Persistent Buffer::constructor_template; static inline size_t base64_decoded_size(const char *src, size_t size) { @@ -132,7 +130,7 @@ Buffer* Buffer::New(size_t length) { HandleScope scope; Local arg = Integer::NewFromUnsigned(length); - Local b = buffer_constructor_template->GetFunction()->NewInstance(1, &arg); + Local b = constructor_template->GetFunction()->NewInstance(1, &arg); if (b.IsEmpty()) return NULL; return ObjectWrap::Unwrap(b); @@ -143,7 +141,7 @@ Buffer* Buffer::New(char* data, size_t length) { HandleScope scope; Local arg = Integer::NewFromUnsigned(0); - Local obj = buffer_constructor_template->GetFunction()->NewInstance(1, &arg); + Local obj = constructor_template->GetFunction()->NewInstance(1, &arg); Buffer *buffer = ObjectWrap::Unwrap(obj); buffer->Replace(data, length, NULL, NULL); @@ -157,7 +155,7 @@ Buffer* Buffer::New(char *data, size_t length, HandleScope scope; Local arg = Integer::NewFromUnsigned(0); - Local obj = buffer_constructor_template->GetFunction()->NewInstance(1, &arg); + Local obj = constructor_template->GetFunction()->NewInstance(1, &arg); Buffer *buffer = ObjectWrap::Unwrap(obj); buffer->Replace(data, length, callback, hint); @@ -168,7 +166,7 @@ Buffer* Buffer::New(char *data, size_t length, Handle Buffer::New(const Arguments &args) { if (!args.IsConstructCall()) { - return FromConstructorTemplate(buffer_constructor_template, args); + return FromConstructorTemplate(constructor_template, args); } HandleScope scope; @@ -470,7 +468,7 @@ Handle Buffer::Utf8Write(const Arguments &args) { int length = s->Length(); if (length == 0) { - buffer_constructor_template->GetFunction()->Set(chars_written_sym, + constructor_template->GetFunction()->Set(chars_written_sym, Integer::New(0)); return scope.Close(Integer::New(0)); } @@ -494,7 +492,7 @@ Handle Buffer::Utf8Write(const Arguments &args) { (String::HINT_MANY_WRITES_EXPECTED | String::NO_NULL_TERMINATION)); - buffer_constructor_template->GetFunction()->Set(chars_written_sym, + constructor_template->GetFunction()->Set(chars_written_sym, Integer::New(char_written)); return scope.Close(Integer::New(written)); @@ -532,7 +530,7 @@ Handle Buffer::Ucs2Write(const Arguments &args) { (String::HINT_MANY_WRITES_EXPECTED | String::NO_NULL_TERMINATION)); - buffer_constructor_template->GetFunction()->Set(chars_written_sym, + constructor_template->GetFunction()->Set(chars_written_sym, Integer::New(written)); return scope.Close(Integer::New(written * 2)); @@ -571,7 +569,7 @@ Handle Buffer::AsciiWrite(const Arguments &args) { (String::HINT_MANY_WRITES_EXPECTED | String::NO_NULL_TERMINATION)); - buffer_constructor_template->GetFunction()->Set(chars_written_sym, + constructor_template->GetFunction()->Set(chars_written_sym, Integer::New(written)); return scope.Close(Integer::New(written)); @@ -661,7 +659,7 @@ Handle Buffer::Base64Write(const Arguments &args) { *dst++ = ((c & 0x03) << 6) | (d & 0x3F); } - buffer_constructor_template->GetFunction()->Set(chars_written_sym, + constructor_template->GetFunction()->Set(chars_written_sym, Integer::New(s.length())); return scope.Close(Integer::New(dst - start)); @@ -695,7 +693,7 @@ Handle Buffer::BinaryWrite(const Arguments &args) { int written = DecodeWrite(p, max_length, s, BINARY); - buffer_constructor_template->GetFunction()->Set(chars_written_sym, + constructor_template->GetFunction()->Set(chars_written_sym, Integer::New(written)); return scope.Close(Integer::New(written)); @@ -747,7 +745,7 @@ bool Buffer::HasInstance(v8::Handle val) { return true; // Also check for SlowBuffers that are empty. - if (buffer_constructor_template->HasInstance(obj)) + if (constructor_template->HasInstance(obj)) return true; return false; @@ -761,35 +759,35 @@ void Buffer::Initialize(Handle target) { chars_written_sym = Persistent::New(String::NewSymbol("_charsWritten")); Local t = FunctionTemplate::New(Buffer::New); - buffer_constructor_template = Persistent::New(t); - buffer_constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - buffer_constructor_template->SetClassName(String::NewSymbol("SlowBuffer")); + constructor_template = Persistent::New(t); + constructor_template->InstanceTemplate()->SetInternalFieldCount(1); + constructor_template->SetClassName(String::NewSymbol("SlowBuffer")); // copy free - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "binarySlice", Buffer::BinarySlice); - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "asciiSlice", Buffer::AsciiSlice); - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "base64Slice", Buffer::Base64Slice); - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "ucs2Slice", Buffer::Ucs2Slice); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "binarySlice", Buffer::BinarySlice); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "asciiSlice", Buffer::AsciiSlice); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "base64Slice", Buffer::Base64Slice); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "ucs2Slice", Buffer::Ucs2Slice); // TODO NODE_SET_PROTOTYPE_METHOD(t, "utf16Slice", Utf16Slice); // copy - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "utf8Slice", Buffer::Utf8Slice); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "utf8Slice", Buffer::Utf8Slice); - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "utf8Write", Buffer::Utf8Write); - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "asciiWrite", Buffer::AsciiWrite); - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "binaryWrite", Buffer::BinaryWrite); - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "base64Write", Buffer::Base64Write); - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "ucs2Write", Buffer::Ucs2Write); - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "fill", Buffer::Fill); - NODE_SET_PROTOTYPE_METHOD(buffer_constructor_template, "copy", Buffer::Copy); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "utf8Write", Buffer::Utf8Write); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "asciiWrite", Buffer::AsciiWrite); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "binaryWrite", Buffer::BinaryWrite); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "base64Write", Buffer::Base64Write); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "ucs2Write", Buffer::Ucs2Write); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "fill", Buffer::Fill); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "copy", Buffer::Copy); - NODE_SET_METHOD(buffer_constructor_template->GetFunction(), + NODE_SET_METHOD(constructor_template->GetFunction(), "byteLength", Buffer::ByteLength); - NODE_SET_METHOD(buffer_constructor_template->GetFunction(), + NODE_SET_METHOD(constructor_template->GetFunction(), "makeFastBuffer", Buffer::MakeFastBuffer); - target->Set(String::NewSymbol("SlowBuffer"), buffer_constructor_template->GetFunction()); + target->Set(String::NewSymbol("SlowBuffer"), constructor_template->GetFunction()); } diff --git a/src/node_buffer.h b/src/node_buffer.h index 3d1c2b2de9..ef7cf4fd83 100644 --- a/src/node_buffer.h +++ b/src/node_buffer.h @@ -65,6 +65,7 @@ namespace node { class NODE_EXTERN Buffer: public ObjectWrap { public: + static v8::Persistent constructor_template; static bool HasInstance(v8::Handle val); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 59cb7fbb29..41bb2bd40e 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -24,7 +24,6 @@ #include #include -#include #include #include @@ -64,34 +63,29 @@ static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL | XN_FLAG_SEP_MULTILINE | XN_FLAG_FN_SN; - -#include -// We do the following to minimize the detal between v0.6 branch. We want to -// use the variables as they were being used before. -#define on_headers_sym NODE_VAR(on_headers_sym) -#define errno_symbol NODE_VAR(errno_symbol) -#define syscall_symbol NODE_VAR(syscall_symbol) -#define subject_symbol NODE_VAR(subject_symbol) -#define subjectaltname_symbol NODE_VAR(subjectaltname_symbol) -#define modulus_symbol NODE_VAR(modulus_symbol) -#define exponent_symbol NODE_VAR(exponent_symbol) -#define issuer_symbol NODE_VAR(issuer_symbol) -#define valid_from_symbol NODE_VAR(valid_from_symbol) -#define valid_to_symbol NODE_VAR(valid_to_symbol) -#define fingerprint_symbol NODE_VAR(fingerprint_symbol) -#define name_symbol NODE_VAR(name_symbol) -#define version_symbol NODE_VAR(version_symbol) -#define ext_key_usage_symbol NODE_VAR(ext_key_usage_symbol) -#define secure_context_constructor NODE_VAR(secure_context_constructor) - - namespace node { namespace crypto { -static uv_rwlock_t* locks; - using namespace v8; +static Persistent errno_symbol; +static Persistent syscall_symbol; +static Persistent subject_symbol; +static Persistent subjectaltname_symbol; +static Persistent modulus_symbol; +static Persistent exponent_symbol; +static Persistent issuer_symbol; +static Persistent valid_from_symbol; +static Persistent valid_to_symbol; +static Persistent fingerprint_symbol; +static Persistent name_symbol; +static Persistent version_symbol; +static Persistent ext_key_usage_symbol; + +static Persistent secure_context_constructor; + +static uv_rwlock_t* locks; + static unsigned long crypto_id_cb(void) { #ifdef _WIN32 @@ -4165,8 +4159,7 @@ PBKDF2(const Arguments& args) { req = new uv_work_t(); req->data = request; - uv_queue_work(Loop(), req, EIO_PBKDF2, EIO_PBKDF2After); - + uv_queue_work(uv_default_loop(), req, EIO_PBKDF2, EIO_PBKDF2After); return Undefined(); err: @@ -4288,7 +4281,7 @@ Handle RandomBytes(const Arguments& args) { Local callback_v = Local(Function::Cast(*args[1])); req->callback_ = Persistent::New(callback_v); - uv_queue_work(Loop(), + uv_queue_work(uv_default_loop(), &req->work_req_, RandomBytesWork, RandomBytesAfter); diff --git a/src/node_extensions.h b/src/node_extensions.h index c7833d43ad..7a7702c9fb 100644 --- a/src/node_extensions.h +++ b/src/node_extensions.h @@ -35,10 +35,6 @@ NODE_EXT_LIST_ITEM(node_signal_watcher) NODE_EXT_LIST_ITEM(node_os) NODE_EXT_LIST_ITEM(node_zlib) -#if defined(HAVE_ISOLATES) && HAVE_ISOLATES -NODE_EXT_LIST_ITEM(node_isolates) -#endif - // libuv rewrite NODE_EXT_LIST_ITEM(node_timer_wrap) NODE_EXT_LIST_ITEM(node_tcp_wrap) diff --git a/src/node_file.cc b/src/node_file.cc index fd9be59b75..3042f2e2b2 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -22,7 +22,6 @@ #include "node.h" #include "node_file.h" #include "node_buffer.h" -#include #ifdef __POSIX__ # include "node_stat_watcher.h" #endif @@ -41,30 +40,6 @@ #endif -#include -// We do the following to minimize the detal between v0.6 branch. We want to -// use the variables as they were being used before. -#define on_headers_sym NODE_VAR(on_headers_sym) -#define encoding_symbol NODE_VAR(encoding_symbol) -#define errno_symbol NODE_VAR(errno_symbol) -#define buf_symbol NODE_VAR(buf_symbol) -#define oncomplete_sym NODE_VAR(oncomplete_sym) -#define stats_constructor_template NODE_VAR(stats_constructor_template) -#define dev_symbol NODE_VAR(dev_symbol) -#define ino_symbol NODE_VAR(ino_symbol) -#define mode_symbol NODE_VAR(mode_symbol) -#define nlink_symbol NODE_VAR(nlink_symbol) -#define uid_symbol NODE_VAR(uid_symbol) -#define gid_symbol NODE_VAR(gid_symbol) -#define rdev_symbol NODE_VAR(rdev_symbol) -#define size_symbol NODE_VAR(size_symbol) -#define blksize_symbol NODE_VAR(blksize_symbol) -#define blocks_symbol NODE_VAR(blocks_symbol) -#define atime_symbol NODE_VAR(atime_symbol) -#define mtime_symbol NODE_VAR(mtime_symbol) -#define ctime_symbol NODE_VAR(ctime_symbol) - - namespace node { using namespace v8; @@ -78,6 +53,11 @@ using namespace v8; typedef class ReqWrap FSReqWrap; +static Persistent encoding_symbol; +static Persistent errno_symbol; +static Persistent buf_symbol; +static Persistent oncomplete_sym; + #ifdef _LARGEFILE_SOURCE static inline int IsInt64(double x) { @@ -229,7 +209,7 @@ struct fs_req_wrap { #define ASYNC_CALL(func, callback, ...) \ FSReqWrap* req_wrap = new FSReqWrap(); \ - int r = uv_fs_##func(Loop(), &req_wrap->req_, \ + int r = uv_fs_##func(uv_default_loop(), &req_wrap->req_, \ __VA_ARGS__, After); \ req_wrap->object_->Set(oncomplete_sym, callback); \ req_wrap->Dispatched(); \ @@ -237,16 +217,16 @@ struct fs_req_wrap { uv_fs_t* req = &req_wrap->req_; \ req->result = r; \ req->path = NULL; \ - req->errorno = uv_last_error(Loop()).code; \ + req->errorno = uv_last_error(uv_default_loop()).code; \ After(req); \ } \ return scope.Close(req_wrap->object_); #define SYNC_CALL(func, path, ...) \ fs_req_wrap req_wrap; \ - int result = uv_fs_##func(Loop(), &req_wrap.req, __VA_ARGS__, NULL); \ + int result = uv_fs_##func(uv_default_loop(), &req_wrap.req, __VA_ARGS__, NULL); \ if (result < 0) { \ - int code = uv_last_error(Loop()).code; \ + int code = uv_last_error(uv_default_loop()).code; \ return ThrowException(UVException(code, #func, "", path)); \ } @@ -273,6 +253,22 @@ static Handle Close(const Arguments& args) { } +static Persistent stats_constructor_template; + +static Persistent dev_symbol; +static Persistent ino_symbol; +static Persistent mode_symbol; +static Persistent nlink_symbol; +static Persistent uid_symbol; +static Persistent gid_symbol; +static Persistent rdev_symbol; +static Persistent size_symbol; +static Persistent blksize_symbol; +static Persistent blocks_symbol; +static Persistent atime_symbol; +static Persistent mtime_symbol; +static Persistent ctime_symbol; + Local BuildStatsObject(NODE_STAT_STRUCT *s) { HandleScope scope; diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index 8360c43300..8d9000d9d7 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -47,57 +47,61 @@ // allocations. -#include -// We do the following to minimize the detal between v0.6 branch. We want to -// use the variables as they were being used before. -#define on_headers_sym NODE_VAR(on_headers_sym) -#define on_headers_complete_sym NODE_VAR(on_headers_complete_sym) -#define on_body_sym NODE_VAR(on_body_sym) -#define on_message_complete_sym NODE_VAR(on_message_complete_sym) -#define delete_sym NODE_VAR(delete_sym) -#define get_sym NODE_VAR(get_sym) -#define head_sym NODE_VAR(head_sym) -#define post_sym NODE_VAR(post_sym) -#define put_sym NODE_VAR(put_sym) -#define connect_sym NODE_VAR(connect_sym) -#define options_sym NODE_VAR(options_sym) -#define trace_sym NODE_VAR(trace_sym) -#define patch_sym NODE_VAR(patch_sym) -#define copy_sym NODE_VAR(copy_sym) -#define lock_sym NODE_VAR(lock_sym) -#define mkcol_sym NODE_VAR(mkcol_sym) -#define move_sym NODE_VAR(move_sym) -#define propfind_sym NODE_VAR(propfind_sym) -#define proppatch_sym NODE_VAR(proppatch_sym) -#define unlock_sym NODE_VAR(unlock_sym) -#define report_sym NODE_VAR(report_sym) -#define mkactivity_sym NODE_VAR(mkactivity_sym) -#define checkout_sym NODE_VAR(checkout_sym) -#define merge_sym NODE_VAR(merge_sym) -#define msearch_sym NODE_VAR(msearch_sym) -#define notify_sym NODE_VAR(notify_sym) -#define subscribe_sym NODE_VAR(subscribe_sym) -#define unsubscribe_sym NODE_VAR(unsubscribe_sym) -#define unknown_method_sym NODE_VAR(unknown_method_sym) -#define method_sym NODE_VAR(method_sym) -#define status_code_sym NODE_VAR(status_code_sym) -#define http_version_sym NODE_VAR(http_version_sym) -#define version_major_sym NODE_VAR(version_major_sym) -#define version_minor_sym NODE_VAR(version_minor_sym) -#define should_keep_alive_sym NODE_VAR(should_keep_alive_sym) -#define upgrade_sym NODE_VAR(upgrade_sym) -#define headers_sym NODE_VAR(headers_sym) -#define url_sym NODE_VAR(url_sym) -#define settings NODE_VAR(settings) -#define current_buffer NODE_VAR(current_buffer) -#define current_buffer_data NODE_VAR(current_buffer_data) -#define current_buffer_len NODE_VAR(current_buffer_len) - - namespace node { using namespace v8; +static Persistent on_headers_sym; +static Persistent on_headers_complete_sym; +static Persistent on_body_sym; +static Persistent on_message_complete_sym; + +static Persistent delete_sym; +static Persistent get_sym; +static Persistent head_sym; +static Persistent post_sym; +static Persistent put_sym; +static Persistent connect_sym; +static Persistent options_sym; +static Persistent trace_sym; +static Persistent patch_sym; +static Persistent copy_sym; +static Persistent lock_sym; +static Persistent mkcol_sym; +static Persistent move_sym; +static Persistent propfind_sym; +static Persistent proppatch_sym; +static Persistent unlock_sym; +static Persistent report_sym; +static Persistent mkactivity_sym; +static Persistent checkout_sym; +static Persistent merge_sym; +static Persistent msearch_sym; +static Persistent notify_sym; +static Persistent subscribe_sym; +static Persistent unsubscribe_sym; +static Persistent unknown_method_sym; + +static Persistent method_sym; +static Persistent status_code_sym; +static Persistent http_version_sym; +static Persistent version_major_sym; +static Persistent version_minor_sym; +static Persistent should_keep_alive_sym; +static Persistent upgrade_sym; +static Persistent headers_sym; +static Persistent url_sym; + +static struct http_parser_settings settings; + + +// This is a hack to get the current_buffer to the callbacks with the least +// amount of overhead. Nothing else will run while http_parser_execute() +// runs, therefore this pointer can be set and used for the execution. +static Local* current_buffer; +static char* current_buffer_data; +static size_t current_buffer_len; + #define HTTP_CB(name) \ static int name(http_parser* p_) { \ diff --git a/src/node_internals.h b/src/node_internals.h index 11dc8fa3a9..89c949946e 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -24,13 +24,6 @@ namespace node { -// This function starts an Isolate. This function is defined in node.cc -// currently so that we minimize the diff between master and v0.6 for easy -// merging. In the future, when v0.6 is extinct, StartThread should be moved -// to node_isolate.cc. -class Isolate; -void StartThread(Isolate* isolate, int argc, char** argv); - #ifndef offset_of // g++ in strict mode complains loudly about the system offsetof() macro // because it uses NULL as the base address. @@ -47,14 +40,6 @@ void StartThread(Isolate* isolate, int argc, char** argv); #define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0])) #endif -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName(); \ - DISALLOW_COPY_AND_ASSIGN(TypeName) - } // namespace node #endif // SRC_NODE_INTERNALS_H_ diff --git a/src/node_isolate.cc b/src/node_isolate.cc deleted file mode 100644 index 5a1d2db4d5..0000000000 --- a/src/node_isolate.cc +++ /dev/null @@ -1,815 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -#define isolate_debugger_constructor NODE_VAR(isolate_debugger_constructor) - -#define ISOLATEMESSAGE_SHARED_STREAM 0x0001 - - -namespace node { - -using v8::Arguments; -using v8::Array; -using v8::Context; -using v8::False; -using v8::Function; -using v8::FunctionTemplate; -using v8::Handle; -using v8::HandleScope; -using v8::Integer; -using v8::Local; -using v8::Null; -using v8::Object; -using v8::ObjectTemplate; -using v8::Persistent; -using v8::String; -using v8::True; -using v8::Undefined; -using v8::Value; -using v8::Undefined; - -static volatile bool initialized; -static volatile int id; -static volatile int isolate_count; -static ngx_queue_t isolate_list; -static uv_mutex_t isolate_mutex; - -#ifdef NDEBUG -# define IF_DEBUG(expr) -#else -# define IF_DEBUG(expr) expr; -#endif - -template -class Queue { -public: - Queue() { - if (uv_mutex_init(&mutex_)) abort(); - ngx_queue_init(&queue_); - } - - ~Queue() { - IF_DEBUG({ - uv_mutex_lock(&mutex_); - assert(ngx_queue_empty(&queue_)); - uv_mutex_unlock(&mutex_); - }) - uv_mutex_destroy(&mutex_); - } - - void Produce(T item) { - Message* m = new Message; - m->item_ = item; - - uv_mutex_lock(&mutex_); - ngx_queue_insert_tail(&queue_, &m->queue_); - uv_mutex_unlock(&mutex_); - } - - bool Consume(T& item) { - ngx_queue_t* q = NULL; - - uv_mutex_lock(&mutex_); - if (!ngx_queue_empty(&queue_)) { - q = ngx_queue_head(&queue_); - ngx_queue_remove(q); - } - uv_mutex_unlock(&mutex_); - - if (q == NULL) return false; - - Message* m = ngx_queue_data(q, Message, queue_); - item = m->item_; - delete m; - - return true; - } - -private: - struct Message { - ngx_queue_t queue_; - T item_; - }; - - ngx_queue_t queue_; - uv_mutex_t mutex_; -}; - - -template -class Channel { -public: - typedef void (*Callback)(T item, void* arg); - - Channel(uv_loop_t* loop, Callback callback, void* arg) { - callback_ = callback; - arg_ = arg; - uv_async_init(loop, &async_, OnMessage); - uv_unref(loop); - } - - ~Channel() { - uv_ref(async_.loop); - uv_close(reinterpret_cast(&async_), NULL); - } - - void Send(T item) { - queue_.Produce(item); - uv_async_send(&async_); - } - -private: - static void OnMessage(uv_async_t* handle, int status) { - Channel* c = container_of(handle, Channel, async_); - c->OnMessage(); - } - - void OnMessage() { - T item; - while (queue_.Consume(item)) callback_(item, arg_); - } - - void* arg_; - Callback callback_; - uv_async_t async_; - Queue queue_; -}; - - -struct IsolateMessage { - int flags; - struct { - size_t size_; - char* buffer_; - } data_; - uv_stream_info_t shared_stream_info_; - - IsolateMessage(const char* buffer, size_t size, - uv_stream_info_t* shared_stream_info) { - flags = 0; - - // make a copy for now - data_.size_ = size; - data_.buffer_ = new char[size]; - memcpy(data_.buffer_, buffer, size); - - if (shared_stream_info) { - flags |= ISOLATEMESSAGE_SHARED_STREAM; - shared_stream_info_ = *shared_stream_info; - } - } - - ~IsolateMessage() { - delete[] data_.buffer_; - } - - static void Free(char* data, void* arg) { - IsolateMessage* msg = static_cast(arg); - assert(data == msg->data_.buffer_); - delete msg; - } -}; - - -class IsolateChannel: public Channel { -public: - IsolateChannel(uv_loop_t* loop, Callback callback, void* arg) - : Channel(loop, callback, arg) - { - } -}; - - -Handle Isolate::Send(const Arguments& args) { - HandleScope scope; - - Isolate* isolate = Isolate::GetCurrent(); - assert(Buffer::HasInstance(args[0])); - assert(isolate->send_channel_ != NULL); - - Local obj = args[0]->ToObject(); - const char* data = Buffer::Data(obj); - size_t size = Buffer::Length(obj); - - IsolateMessage* msg; - - if (args[1]->IsObject()) { - uv_stream_info_t stream_info; - - Local send_stream_obj = args[1]->ToObject(); - assert(send_stream_obj->InternalFieldCount() > 0); - StreamWrap* send_stream_wrap = static_cast( - send_stream_obj->GetPointerFromInternalField(0)); - uv_stream_t* send_stream = send_stream_wrap->GetStream(); - int r = uv_export(send_stream, &stream_info); - assert(r == 0); - msg = new IsolateMessage(data, size, &stream_info); - } else { - msg = new IsolateMessage(data, size, NULL); - } - - isolate->send_channel_->Send(msg); - - return Undefined(); -} - - -Handle Isolate::Unref(const Arguments& args) { - HandleScope scope; - - Isolate* isolate = Isolate::GetCurrent(); - uv_unref(isolate->loop_); - - return Undefined(); -} - - -void Isolate::OnMessage(IsolateMessage* msg, void* arg) { - HandleScope scope; - - Isolate* self = static_cast(arg); - NODE_ISOLATE_CHECK(self); - - Buffer* buf = Buffer::New(msg->data_.buffer_, msg->data_.size_, - IsolateMessage::Free, msg); - - int argc = 1; - Handle argv[2] = { - buf->handle_ - }; - - if (msg->flags & ISOLATEMESSAGE_SHARED_STREAM) { - // Instantiate the client javascript object and handle. - Local pending_obj = TCPWrap::Instantiate(); - - // Unwrap the client javascript object. - assert(pending_obj->InternalFieldCount() > 0); - TCPWrap* pending_wrap = - static_cast(pending_obj->GetPointerFromInternalField(0)); - - int r = uv_import(pending_wrap->GetStream(), &msg->shared_stream_info_); - assert(r == 0); - - argv[1] = pending_obj; - argc++; - } - - MakeCallback(self->globals_.process, "_onmessage", argc, argv); -} - - -void Isolate::Initialize() { - if (initialized) return; - if (uv_mutex_init(&isolate_mutex)) abort(); - ngx_queue_init(&isolate_list); - initialized = true; -} - - -int Isolate::Count() { - int count; - uv_mutex_lock(&isolate_mutex); - count = isolate_count; - uv_mutex_unlock(&isolate_mutex); - return count; -} - - -Isolate::Isolate() { - send_channel_ = NULL; // set (and deleted) by the parent isolate - recv_channel_ = NULL; - - uv_mutex_lock(&isolate_mutex); - assert(initialized && "node::Isolate::Initialize() hasn't been called"); - ngx_queue_insert_tail(&isolate_list, &isolate_list_); - isolate_count++; - id_ = ++id; - uv_mutex_unlock(&isolate_mutex); - - if (id_ == 1) { - loop_ = uv_default_loop(); - } else { - loop_ = uv_loop_new(); - // Artificially ref the isolate loop so that the child - // isolate stays alive by default. process.exit will - // unref the loop (see Isolate::Unref). - uv_ref(loop_); - } - - debug_state = kNone; - debugger_instance = NULL; - - ngx_queue_init(&at_exit_callbacks_); - - v8_isolate_ = v8::Isolate::New(); - assert(v8_isolate_->GetData() == NULL); - v8_isolate_->SetData(this); - - globals_init_ = false; -} - - -Isolate::~Isolate() { - if (!argv_) return; - for (size_t i = 0; argv_[i]; ++i) delete[] argv_[i]; - delete[] argv_; -} - - -struct globals* Isolate::Globals() { - return &globals_; -} - - -void Isolate::AtExit(AtExitCallback callback, void* arg) { - struct AtExitCallbackInfo* it = new AtExitCallbackInfo; - - //NODE_ISOLATE_CHECK(this); - - it->callback_ = callback; - it->arg_ = arg; - - ngx_queue_insert_head(&at_exit_callbacks_, &it->queue_); -} - - -void Isolate::Enter() { - v8_isolate_->Enter(); - - if (v8_context_.IsEmpty()) { - v8_context_ = Context::New(); - } - v8_context_->Enter(); - - if (!globals_init_) { - globals_init_ = true; - globals_init(&globals_); - } - - NODE_ISOLATE_CHECK(this); -} - - -void Isolate::Exit() { - NODE_ISOLATE_CHECK(this); - v8_context_->Exit(); - v8_isolate_->Exit(); -} - - -void Isolate::Dispose() { - NODE_ISOLATE_CHECK(this); - - while (!ngx_queue_empty(&at_exit_callbacks_)) { - ngx_queue_t* q = ngx_queue_head(&at_exit_callbacks_); - ngx_queue_remove(q); - - AtExitCallbackInfo* it = ngx_queue_data(q, AtExitCallbackInfo, queue_); - it->callback_(it->arg_); - - delete it; - } - - assert(v8_context_->InContext()); - v8_context_->Exit(); - v8_context_.Clear(); - v8_context_.Dispose(); - - v8_isolate_->Exit(); - v8_isolate_->Dispose(); - v8_isolate_ = NULL; - - uv_mutex_lock(&isolate_mutex); - isolate_count--; - ngx_queue_remove(&isolate_list_); - assert(isolate_count >= 0); - assert((isolate_count == 0 && ngx_queue_empty(&isolate_list)) - || (isolate_count > 0 && !ngx_queue_empty(&isolate_list))); - uv_mutex_unlock(&isolate_mutex); -} - - -struct IsolateWrap: public ObjectWrap { -public: - IsolateWrap(Isolate* parent_isolate) { - parent_isolate_ = parent_isolate; - - uv_loop_t* parent_loop = parent_isolate->GetLoop(); - recv_channel_ = new IsolateChannel( - parent_loop, IsolateWrap::OnMessage, this); - - isolate_ = new Isolate; - send_channel_ = new IsolateChannel( - isolate_->loop_, Isolate::OnMessage, isolate_); - - isolate_->send_channel_ = recv_channel_; - isolate_->recv_channel_ = send_channel_; - - // TODO this could be folded into the regular channel - uv_async_init(parent_loop, &child_exit_, AfterChildExit); - isolate_->AtExit(AtChildExit, this); - - HandleScope scope; - Local tpl = ObjectTemplate::New(); - tpl->SetInternalFieldCount(1); - - Local obj = tpl->NewInstance(); - Wrap(obj); - Ref(); // unref'd when the child isolate exits - - obj->Set(String::NewSymbol("tid"), - Integer::New(isolate_->id_)); - - obj->Set(String::NewSymbol("send"), - FunctionTemplate::New(Send)->GetFunction()); - } - - ~IsolateWrap() { - delete isolate_; - delete recv_channel_; - delete send_channel_; - } - - Isolate* GetIsolate() { - return isolate_; - } - -private: - // runs in the child thread - static void AtChildExit(void* arg) { - IsolateWrap* self = static_cast(arg); - uv_async_send(&self->child_exit_); - } - - // runs in the parent thread - static void AfterChildExit(uv_async_t* handle, int status) { - IsolateWrap* self = container_of(handle, IsolateWrap, child_exit_); - self->OnExit(); - } - - void OnExit() { - if (uv_thread_join(&isolate_->tid_)) abort(); - uv_close(reinterpret_cast(&child_exit_), NULL); - MakeCallback(handle_, "onexit", 0, NULL); - Unref(); // child is dead, it's safe to GC the JS object now - } - - static void OnMessage(IsolateMessage* msg, void* arg) { - IsolateWrap* self = static_cast(arg); - self->OnMessage(msg); - } - - void OnMessage(IsolateMessage* msg) { - NODE_ISOLATE_CHECK(parent_isolate_); - HandleScope scope; - Buffer* buf = Buffer::New( - msg->data_.buffer_, msg->data_.size_, IsolateMessage::Free, msg); - - int argc = 1; - Handle argv[2] = { - buf->handle_ - }; - - if (msg->flags & ISOLATEMESSAGE_SHARED_STREAM) { - // Instantiate the client javascript object and handle. - Local pending_obj = TCPWrap::Instantiate(); - - // Unwrap the client javascript object. - assert(pending_obj->InternalFieldCount() > 0); - TCPWrap* pending_wrap = - static_cast(pending_obj->GetPointerFromInternalField(0)); - - int r = uv_import(pending_wrap->GetStream(), &msg->shared_stream_info_); - assert(r == 0); - - argv[1] = pending_obj; - argc++; - } - - MakeCallback(handle_, "onmessage", argc, argv); - } - - // TODO merge with Isolate::Send(), it's almost identical - static Handle Send(const Arguments& args) { - HandleScope scope; - IsolateWrap* self = Unwrap(args.This()); - assert(Buffer::HasInstance(args[0])); - - Local obj = args[0]->ToObject(); - const char* data = Buffer::Data(obj); - size_t size = Buffer::Length(obj); - - IsolateMessage* msg; - - if (args[1]->IsObject()) { - uv_stream_info_t stream_info; - - Local send_stream_obj = args[1]->ToObject(); - assert(send_stream_obj->InternalFieldCount() > 0); - StreamWrap* send_stream_wrap = static_cast( - send_stream_obj->GetPointerFromInternalField(0)); - uv_stream_t* send_stream = send_stream_wrap->GetStream(); - int r = uv_export(send_stream, &stream_info); - assert(r == 0); - msg = new IsolateMessage(data, size, &stream_info); - } else { - msg = new IsolateMessage(data, size, NULL); - } - - self->send_channel_->Send(msg); - return Undefined(); - } - - DISALLOW_IMPLICIT_CONSTRUCTORS(IsolateWrap); - Isolate* isolate_; - Isolate* parent_isolate_; - IsolateChannel* send_channel_; - IsolateChannel* recv_channel_; - uv_async_t child_exit_; // side effect: keeps the parent's event loop alive - // until the child exits -}; - - -static void RunIsolate(void* arg) { - Isolate* isolate = static_cast(arg); - isolate->Enter(); - StartThread(isolate, isolate->argc_, isolate->argv_); - isolate->Dispose(); -} - - -static Handle CreateIsolate(const Arguments& args) { - HandleScope scope; - - assert(args[0]->IsArray()); - - Local argv = args[0].As(); - assert(argv->Length() >= 2); - - Isolate* current_isolate = node::Isolate::GetCurrent(); - IsolateWrap* wrap = new IsolateWrap(current_isolate); - Isolate* isolate = wrap->GetIsolate(); - - // Copy over arguments into isolate - isolate->argc_ = argv->Length(); - isolate->argv_ = new char*[isolate->argc_ + 1]; - for (int i = 0; i < isolate->argc_; ++i) { - String::Utf8Value str(argv->Get(i)); - size_t size = 1 + strlen(*str); - isolate->argv_[i] = new char[size]; - memcpy(isolate->argv_[i], *str, size); - } - isolate->argv_[isolate->argc_] = NULL; - - // If options object was provided - if (args.Length() > 1) { - Local options = args[1].As(); - Local opt_debug = options->Get(String::New("debug")); - Local opt_debug_brk = options->Get(String::New("debugBrk")); - - // Handle .debug = true case - if (opt_debug->IsFunction()) { - isolate->debug_state = opt_debug_brk->IsTrue() ? - Isolate::kDebugBrk - : - Isolate::kDebug; - isolate->debugger_instance = IsolateDebugger::New(opt_debug); - } - } - - if (uv_thread_create(&isolate->tid_, RunIsolate, isolate)) - return Null(); // wrap is collected by the GC - else - return wrap->handle_; -} - - -static Handle CountIsolate(const Arguments& args) { - HandleScope scope; - return scope.Close(Integer::New(Isolate::Count())); -} - - -void InitIsolates(Handle target) { - HandleScope scope; - NODE_SET_METHOD(target, "create", CreateIsolate); - NODE_SET_METHOD(target, "count", CountIsolate); - - IsolateDebugger::Initialize(); -} - - -class IsolateDebuggerMessage { - public: - IsolateDebugger* d_; - uint16_t* value_; - int len_; - - IsolateDebuggerMessage(IsolateDebugger* d, uint16_t* value, int len) { - d_ = d; - value_ = new uint16_t[len]; - len_ = len; - memcpy(value_, value, len * sizeof(value_[0])); - } - - ~IsolateDebuggerMessage() { - delete[] value_; - } -}; - - -void IsolateDebugger::Initialize() { - HandleScope scope; - - Local t = FunctionTemplate::New(IsolateDebugger::New); - isolate_debugger_constructor = Persistent::New(t); - - t->InstanceTemplate()->SetInternalFieldCount(1); - t->SetClassName(String::NewSymbol("IsolateDebugger")); - - NODE_SET_PROTOTYPE_METHOD(t, "write", IsolateDebugger::Write); -} - - -IsolateDebugger::IsolateDebugger(Handle init) { - debuggee_ = NULL; - initialized_ = false; - host_ = Isolate::GetCurrent(); - host_loop_ = host_->GetLoop(); - init_callback_fn_ = Persistent::New(init); - - // Init async handle to invoke js callback once - // debugger will be initialized - uv_async_init(host_loop_, - &init_callback_, - IsolateDebugger::InitCallback); - init_callback_.data = reinterpret_cast(this); - - msg_channel_ = new Channel( - host_loop_, MessageCallback, NULL); -} - - -IsolateDebugger::~IsolateDebugger() { - init_callback_fn_.Clear(); - init_callback_fn_.Dispose(); - delete msg_channel_; -} - - -void IsolateDebugger::Init(void) { - HandleScope scope; - - Isolate* isolate = Isolate::GetCurrent(); - - debuggee_ = isolate; - debuggee_v8_ = isolate->GetV8Isolate(); - v8::Debug::SetMessageHandler2(IsolateDebugger::DebugMessageHandler); - - // Expose v8debug for isolate - - if (isolate->debug_state == Isolate::kDebugBrk) { - Local debugContext = v8::Debug::GetDebugContext(); - - debugContext->SetSecurityToken( - isolate->GetV8Context()->GetSecurityToken() - ); - isolate->GetV8Context()->Global()->Set( - String::New("v8debug"), - debugContext->Global() - ); - } - - initialized_ = true; - - uv_async_send(&init_callback_); -} - - -void IsolateDebugger::InitCallback(uv_async_t* c, int status) { - assert(c->data != NULL); - - IsolateDebugger* d = reinterpret_cast(c->data); - - d->host_->Enter(); - HandleScope scope; - - Handle argv[1] = { d->handle_ }; - Function::Cast(*d->init_callback_fn_)->Call(d->handle_, 1, argv); - - d->host_->Exit(); - - // Unreference loop - uv_unref(d->host_loop_); -} - - -Handle IsolateDebugger::New(const Arguments& args) { - HandleScope scope; - - IsolateDebugger* d = new IsolateDebugger(args[0]); - d->Wrap(args.Holder()); - - return args.This(); -} - - -IsolateDebugger* IsolateDebugger::New(Handle init) { - HandleScope scope; - - Handle argv[1] = { init }; - Handle i = isolate_debugger_constructor->GetFunction()->NewInstance( - 1, - argv - ); - - return ObjectWrap::Unwrap(i); -} - - -Handle IsolateDebugger::Write(const Arguments& args) { - HandleScope scope; - - if (args.Length() != 1) { - return ThrowException(String::New( - "IsolateDebugger::Write requires one argument" - )); - } - - IsolateDebugger* d = ObjectWrap::Unwrap(args.This()); - assert(d->initialized_); - - String::Value v(args[0]->ToString()); - v8::Debug::SendCommand(*v, - v.length(), - NULL, - d->debuggee_v8_); - - return Undefined(); -} - - -void IsolateDebugger::DebugMessageHandler(const v8::Debug::Message& message) { - IsolateDebugger* d = Isolate::GetCurrent()->debugger_instance; - - String::Value v(message.GetJSON()); - d->msg_channel_->Send(new IsolateDebuggerMessage(d, *v, v.length())); -} - - -void IsolateDebugger::MessageCallback(IsolateDebuggerMessage* msg, void*) { - assert(msg != NULL); - - IsolateDebugger *d = msg->d_; - // Enter parent isolate context - d->host_->Enter(); - HandleScope scope; - - // debugger.onmessage should be a function! - Handle argv[] = { String::New(msg->value_, msg->len_) }; - MakeCallback(d->handle_, "onmessage", ARRAY_SIZE(argv), argv); - - // Free memory allocated for message - delete msg; - - // And leave isolate - d->host_->Exit(); -} - - -} // namespace node - - -NODE_MODULE(node_isolates, node::InitIsolates) diff --git a/src/node_isolate.h b/src/node_isolate.h deleted file mode 100644 index 12e5921a5b..0000000000 --- a/src/node_isolate.h +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef SRC_NODE_ISOLATE_H_ -#define SRC_NODE_ISOLATE_H_ - -#include "v8.h" -#include "v8-debug.h" -#include "uv.h" -#include "node_vars.h" -#include "node_object_wrap.h" -#include "ngx-queue.h" - -#ifdef NDEBUG -# define NODE_ISOLATE_CHECK(ptr) ((void) (ptr)) -#else -# include -# define NODE_ISOLATE_CHECK(ptr) \ - do { \ - node::Isolate* data_ = node::Isolate::GetCurrent(); \ - assert(data_ == (ptr)); \ - } \ - while (0) -#endif - - -namespace node { - -template - -class Channel; - -class IsolateWrap; -class IsolateChannel; -class IsolateMessage; -class IsolateDebugger; -class IsolateDebuggerMessage; - -class Isolate { -public: - char** argv_; - int argc_; - uv_thread_t tid_; - - enum { - kNone, - kDebug, - kDebugBrk - } debug_state; - IsolateDebugger* debugger_instance; - - // Call this before instantiating any Isolate - static void Initialize(); - static int Count(); - - typedef void (*AtExitCallback)(void* arg); - - static v8::Handle Send(const v8::Arguments& args); - static v8::Handle Unref(const v8::Arguments& args); - - static Isolate* GetCurrent() { - return reinterpret_cast(v8::Isolate::GetCurrent()->GetData()); - } - - uv_loop_t* GetLoop() { - NODE_ISOLATE_CHECK(this); - return loop_; - } - - v8::Isolate* GetV8Isolate() { - NODE_ISOLATE_CHECK(this); - return v8_isolate_; - } - - v8::Handle GetV8Context() { - NODE_ISOLATE_CHECK(this); - return v8_context_; - } - - /* Register a handler that should run when the current isolate exits. - * Handlers run in LIFO order. - */ - void AtExit(AtExitCallback callback, void *arg); - - struct globals* Globals(); - - unsigned int id_; - - // This constructor is used for every non-main thread - Isolate(); - ~Isolate(); - - void Enter(); - void Exit(); - - /* Shutdown the isolate. Call this method at thread death. */ - void Dispose(); - -private: - friend class IsolateWrap; - - struct AtExitCallbackInfo { - AtExitCallback callback_; - ngx_queue_t queue_; - void* arg_; - }; - - static void OnMessage(IsolateMessage*, void*); - - // Forbid implicit constructors and copy constructors - void operator=(const Isolate&) {} - Isolate(const Isolate&) {} - - ngx_queue_t isolate_list_; // linked list of all isolates - ngx_queue_t at_exit_callbacks_; - v8::Persistent v8_context_; - v8::Isolate* v8_isolate_; - IsolateChannel* send_channel_; - IsolateChannel* recv_channel_; - uv_loop_t* loop_; - - // Global variables for this isolate. - struct globals globals_; - bool globals_init_; -}; - -class IsolateDebugger : ObjectWrap { -public: - static void Initialize(); - void Init(); - static void InitCallback(uv_async_t* c, int status); - - static v8::Handle New(const v8::Arguments& args); - static IsolateDebugger* New(v8::Handle init); - - static v8::Handle Write(const v8::Arguments& args); - - static void DebugMessageHandler(const v8::Debug::Message& message); - static void MessageCallback(IsolateDebuggerMessage* msg, void*); - - IsolateDebugger(v8::Handle init); - ~IsolateDebugger(); - -protected: - Isolate* host_; - uv_loop_t* host_loop_; - - uv_async_t init_callback_; - v8::Persistent init_callback_fn_; - - bool initialized_; - Isolate* debuggee_; - v8::Isolate* debuggee_v8_; - - struct debug_msg_s { - uint16_t* value; - int len; - - IsolateDebugger* d; - }; - - Channel* msg_channel_; -}; - -} // namespace node - -#endif // SRC_NODE_ISOLATE_H_ diff --git a/src/node_script.cc b/src/node_script.cc index a6fdba6b1e..1f51113c92 100644 --- a/src/node_script.cc +++ b/src/node_script.cc @@ -21,7 +21,6 @@ #include #include -#include #include namespace node { @@ -44,8 +43,6 @@ using v8::Integer; using v8::Function; using v8::FunctionTemplate; -#define wrapped_context_constructor NODE_VAR(wrapped_context_constructor) -#define wrapped_script_constructor NODE_VAR(wrapped_script_constructor) class WrappedContext : ObjectWrap { public: @@ -58,6 +55,8 @@ class WrappedContext : ObjectWrap { protected: + static Persistent constructor_template; + WrappedContext(); ~WrappedContext(); @@ -65,6 +64,9 @@ class WrappedContext : ObjectWrap { }; +Persistent WrappedContext::constructor_template; + + class WrappedScript : ObjectWrap { public: static void Initialize(Handle target); @@ -79,6 +81,8 @@ class WrappedScript : ObjectWrap { static Handle EvalMachine(const Arguments& args); protected: + static Persistent constructor_template; + WrappedScript() : ObjectWrap() {} ~WrappedScript(); @@ -131,17 +135,17 @@ void WrappedContext::Initialize(Handle target) { HandleScope scope; Local t = FunctionTemplate::New(WrappedContext::New); - wrapped_context_constructor = Persistent::New(t); - wrapped_context_constructor->InstanceTemplate()->SetInternalFieldCount(1); - wrapped_context_constructor->SetClassName(String::NewSymbol("Context")); + constructor_template = Persistent::New(t); + constructor_template->InstanceTemplate()->SetInternalFieldCount(1); + constructor_template->SetClassName(String::NewSymbol("Context")); target->Set(String::NewSymbol("Context"), - wrapped_context_constructor->GetFunction()); + constructor_template->GetFunction()); } bool WrappedContext::InstanceOf(Handle value) { - return !value.IsEmpty() && wrapped_context_constructor->HasInstance(value); + return !value.IsEmpty() && constructor_template->HasInstance(value); } @@ -166,7 +170,7 @@ WrappedContext::~WrappedContext() { Local WrappedContext::NewInstance() { - Local context = wrapped_context_constructor->GetFunction()->NewInstance(); + Local context = constructor_template->GetFunction()->NewInstance(); return context; } @@ -176,57 +180,60 @@ Persistent WrappedContext::GetV8Context() { } +Persistent WrappedScript::constructor_template; + + void WrappedScript::Initialize(Handle target) { HandleScope scope; Local t = FunctionTemplate::New(WrappedScript::New); - wrapped_script_constructor = Persistent::New(t); - wrapped_script_constructor->InstanceTemplate()->SetInternalFieldCount(1); + constructor_template = Persistent::New(t); + constructor_template->InstanceTemplate()->SetInternalFieldCount(1); // Note: We use 'NodeScript' instead of 'Script' so that we do not // conflict with V8's Script class defined in v8/src/messages.js // See GH-203 https://github.com/joyent/node/issues/203 - wrapped_script_constructor->SetClassName(String::NewSymbol("NodeScript")); + constructor_template->SetClassName(String::NewSymbol("NodeScript")); - NODE_SET_PROTOTYPE_METHOD(wrapped_script_constructor, + NODE_SET_PROTOTYPE_METHOD(constructor_template, "createContext", WrappedScript::CreateContext); - NODE_SET_PROTOTYPE_METHOD(wrapped_script_constructor, + NODE_SET_PROTOTYPE_METHOD(constructor_template, "runInContext", WrappedScript::RunInContext); - NODE_SET_PROTOTYPE_METHOD(wrapped_script_constructor, + NODE_SET_PROTOTYPE_METHOD(constructor_template, "runInThisContext", WrappedScript::RunInThisContext); - NODE_SET_PROTOTYPE_METHOD(wrapped_script_constructor, + NODE_SET_PROTOTYPE_METHOD(constructor_template, "runInNewContext", WrappedScript::RunInNewContext); - NODE_SET_METHOD(wrapped_script_constructor, + NODE_SET_METHOD(constructor_template, "createContext", WrappedScript::CreateContext); - NODE_SET_METHOD(wrapped_script_constructor, + NODE_SET_METHOD(constructor_template, "runInContext", WrappedScript::CompileRunInContext); - NODE_SET_METHOD(wrapped_script_constructor, + NODE_SET_METHOD(constructor_template, "runInThisContext", WrappedScript::CompileRunInThisContext); - NODE_SET_METHOD(wrapped_script_constructor, + NODE_SET_METHOD(constructor_template, "runInNewContext", WrappedScript::CompileRunInNewContext); target->Set(String::NewSymbol("NodeScript"), - wrapped_script_constructor->GetFunction()); + constructor_template->GetFunction()); } Handle WrappedScript::New(const Arguments& args) { if (!args.IsConstructCall()) { - return FromConstructorTemplate(wrapped_script_constructor, args); + return FromConstructorTemplate(constructor_template, args); } HandleScope scope; diff --git a/src/node_signal_watcher.cc b/src/node_signal_watcher.cc index d87b3c3326..1027b3efd1 100644 --- a/src/node_signal_watcher.cc +++ b/src/node_signal_watcher.cc @@ -22,27 +22,26 @@ #include #include -#include -#define callback_symbol NODE_VAR(callback_symbol) -#define signal_watcher_constructor_template NODE_VAR(signal_watcher_constructor_template) - namespace node { using namespace v8; +Persistent SignalWatcher::constructor_template; +static Persistent callback_symbol; + void SignalWatcher::Initialize(Handle target) { HandleScope scope; Local t = FunctionTemplate::New(SignalWatcher::New); - signal_watcher_constructor_template = Persistent::New(t); - signal_watcher_constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - signal_watcher_constructor_template->SetClassName(String::NewSymbol("SignalWatcher")); + constructor_template = Persistent::New(t); + constructor_template->InstanceTemplate()->SetInternalFieldCount(1); + constructor_template->SetClassName(String::NewSymbol("SignalWatcher")); - NODE_SET_PROTOTYPE_METHOD(signal_watcher_constructor_template, "start", SignalWatcher::Start); - NODE_SET_PROTOTYPE_METHOD(signal_watcher_constructor_template, "stop", SignalWatcher::Stop); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "start", SignalWatcher::Start); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", SignalWatcher::Stop); target->Set(String::NewSymbol("SignalWatcher"), - signal_watcher_constructor_template->GetFunction()); + constructor_template->GetFunction()); callback_symbol = NODE_PSYMBOL("callback"); } @@ -74,7 +73,7 @@ void SignalWatcher::Callback(EV_P_ ev_signal *watcher, int revents) { Handle SignalWatcher::New(const Arguments& args) { if (!args.IsConstructCall()) { - return FromConstructorTemplate(signal_watcher_constructor_template, args); + return FromConstructorTemplate(constructor_template, args); } HandleScope scope; diff --git a/src/node_vars.cc b/src/node_vars.cc deleted file mode 100644 index 01bf4067e5..0000000000 --- a/src/node_vars.cc +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#if HAVE_OPENSSL -# include -#endif -#include - -namespace node { - -// For now we just statically initialize the globals structure. Later there -// will be one struct globals for each isolate. - -void globals_init(struct globals* g) { - memset(g, 0, sizeof(struct globals)); - -#ifdef OPENSSL_NPN_NEGOTIATED - g->use_npn = true; -#else - g->use_npn = false; -#endif - -#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB - g->use_sni = true; -#else - g->use_sni = false; -#endif -} - - -#if HAVE_ISOLATES -struct globals* globals_get() { - node::Isolate* isolate = node::Isolate::GetCurrent(); - return isolate->Globals(); -} -#else -static struct globals g_struct; -static struct globals* g_ptr; - -struct globals* globals_get() { - if (!g_ptr) { - g_ptr = &g_struct; - globals_init(g_ptr); - } - return g_ptr; -} -#endif // HAVE_ISOLATES - -} // namespace node diff --git a/src/node_vars.h b/src/node_vars.h deleted file mode 100644 index e0acbff447..0000000000 --- a/src/node_vars.h +++ /dev/null @@ -1,197 +0,0 @@ -#ifndef NODE_VARS_H -#define NODE_VARS_H - -// This file contains all Isolate-local variables. We allow people to -// compile Node either with Isolates or without. In the case that they -// compile without isolates, these will be static variables. - -#include -#include -#include - -#if defined(_MSC_VER) -# define PATH_MAX MAX_PATH -#endif - -#ifndef PATH_MAX -# define PATH_MAX 4096 -#endif - -namespace node { - - -#define NODE_VAR(x) (globals_get()->x) - -struct globals { - // node.cc - v8::Persistent process; - v8::Persistent errno_symbol; - v8::Persistent syscall_symbol; - v8::Persistent errpath_symbol; - v8::Persistent code_symbol; - v8::Persistent rss_symbol; - v8::Persistent heap_total_symbol; - v8::Persistent heap_used_symbol; - v8::Persistent listeners_symbol; - v8::Persistent uncaught_exception_symbol; - v8::Persistent emit_symbol; - uv_check_t check_tick_watcher; - uv_prepare_t prepare_tick_watcher; - uv_idle_t tick_spinner; - bool need_tick_cb; - v8::Persistent tick_callback_sym; - bool use_npn; - bool use_sni; - // Buffer for getpwnam_r(), getgrpam_r() and other misc callers; keep this - // scoped at file-level rather than method-level to avoid excess stack usage. - char getbuf[PATH_MAX + 1]; - // We need to notify V8 when we're idle so that it can run the garbage - // collector. The interface to this is V8::IdleNotification(). It returns - // true if the heap hasn't be fully compacted, and needs to be run again. - // Returning false means that it doesn't have anymore work to do. - // - // A rather convoluted algorithm has been devised to determine when Node is - // idle. You'll have to figure it out for yourself. - uv_check_t gc_check; - uv_idle_t gc_idle; - uv_timer_t gc_timer; - bool need_gc; -# define FAST_TICK 700. -# define GC_WAIT_TIME 5000. -# define RPM_SAMPLES 100 - int64_t tick_times[RPM_SAMPLES]; - int tick_time_head; - int uncaught_exception_counter; - v8::Persistent binding_cache; - v8::Persistent module_load_list; - v8::Isolate* node_isolate; - volatile bool debugger_running; - double prog_start_time; - - // stream_wrap.cc - size_t slab_used; - uv_stream_t* handle_that_last_alloced; - v8::Persistent slab_sym; - v8::Persistent buffer_sym; - v8::Persistent write_queue_size_sym; - bool stream_wrap_initialized; - - // tcp_wrap.cc - v8::Persistent tcpConstructor; - v8::Persistent family_symbol; - v8::Persistent address_symbol; - v8::Persistent port_symbol; - - // node_http_parser.cc - v8::Persistent on_headers_sym; - v8::Persistent on_headers_complete_sym; - v8::Persistent on_body_sym; - v8::Persistent on_message_complete_sym; - v8::Persistent delete_sym; - v8::Persistent get_sym; - v8::Persistent head_sym; - v8::Persistent post_sym; - v8::Persistent put_sym; - v8::Persistent connect_sym; - v8::Persistent options_sym; - v8::Persistent trace_sym; - v8::Persistent patch_sym; - v8::Persistent copy_sym; - v8::Persistent lock_sym; - v8::Persistent mkcol_sym; - v8::Persistent move_sym; - v8::Persistent propfind_sym; - v8::Persistent proppatch_sym; - v8::Persistent unlock_sym; - v8::Persistent report_sym; - v8::Persistent mkactivity_sym; - v8::Persistent checkout_sym; - v8::Persistent merge_sym; - v8::Persistent msearch_sym; - v8::Persistent notify_sym; - v8::Persistent subscribe_sym; - v8::Persistent unsubscribe_sym; - v8::Persistent unknown_method_sym; - v8::Persistent method_sym; - v8::Persistent status_code_sym; - v8::Persistent http_version_sym; - v8::Persistent version_major_sym; - v8::Persistent version_minor_sym; - v8::Persistent should_keep_alive_sym; - v8::Persistent upgrade_sym; - v8::Persistent headers_sym; - v8::Persistent url_sym; - struct http_parser_settings settings; - // This is a hack to get the current_buffer to the callbacks with the least - // amount of overhead. Nothing else will run while http_parser_execute() - // runs, therefore this pointer can be set and used for the execution. - v8::Local* current_buffer; - char* current_buffer_data; - size_t current_buffer_len; - - // node_file.cc - v8::Persistent encoding_symbol; - v8::Persistent buf_symbol; - v8::Persistent oncomplete_sym; - v8::Persistent stats_constructor_template; - v8::Persistent dev_symbol; - v8::Persistent ino_symbol; - v8::Persistent mode_symbol; - v8::Persistent nlink_symbol; - v8::Persistent uid_symbol; - v8::Persistent gid_symbol; - v8::Persistent rdev_symbol; - v8::Persistent size_symbol; - v8::Persistent blksize_symbol; - v8::Persistent blocks_symbol; - v8::Persistent atime_symbol; - v8::Persistent mtime_symbol; - v8::Persistent ctime_symbol; - - // node_zlib.cc - v8::Persistent callback_sym; - - // node_crypto.cc - v8::Persistent subject_symbol; - v8::Persistent subjectaltname_symbol; - v8::Persistent modulus_symbol; - v8::Persistent exponent_symbol; - v8::Persistent issuer_symbol; - v8::Persistent valid_from_symbol; - v8::Persistent valid_to_symbol; - v8::Persistent fingerprint_symbol; - v8::Persistent name_symbol; - v8::Persistent version_symbol; - v8::Persistent ext_key_usage_symbol; - v8::Persistent secure_context_constructor; - - // node_buffer.cc - v8::Persistent length_symbol; - v8::Persistent chars_written_sym; - v8::Persistent write_sym; - v8::Persistent buffer_constructor_template; - - // node_script.cc - v8::Persistent wrapped_context_constructor; - v8::Persistent wrapped_script_constructor; - - // node_isolate.cc - v8::Persistent isolate_debugger_constructor; - - // node_signal_watcher.cc - v8::Persistent callback_symbol; - v8::Persistent signal_watcher_constructor_template; - - // cares_wrap.cc - ::ares_channel ares_channel; -}; - -// Initialize globals struct. -void globals_init(struct globals*); - -// Get the globals struct for the current Isolate. The returned pointer is -// already initialized. -struct globals* globals_get(); - -} // namespace node -#endif // NODE_VARS_H diff --git a/src/node_zlib.cc b/src/node_zlib.cc index 808ceb0bae..a27fcef375 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -29,16 +29,14 @@ #include #include -#include -// We do the following to minimize the detal between v0.6 branch. We want to -// use the variables as they were being used before. -#define callback_sym NODE_VAR(callback_sym) namespace node { using namespace v8; +static Persistent callback_sym; + enum node_zlib_mode { DEFLATE = 1, INFLATE, @@ -127,7 +125,7 @@ template class ZCtx : public ObjectWrap { // set this so that later on, I can easily tell how much was written. ctx->chunk_size_ = out_len; - uv_queue_work(Loop(), + uv_queue_work(uv_default_loop(), work_req, ZCtx::Process, ZCtx::After); diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index c33de3858f..1870837bca 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -124,7 +123,7 @@ Handle PipeWrap::New(const Arguments& args) { PipeWrap::PipeWrap(Handle object, bool ipc) : StreamWrap(object, (uv_stream_t*) &handle_) { - int r = uv_pipe_init(Loop(), &handle_, ipc); + int r = uv_pipe_init(uv_default_loop(), &handle_, ipc); assert(r == 0); // How do we proxy this error up to javascript? // Suggestion: uv_pipe_init() returns void. handle_.data = reinterpret_cast(this); @@ -142,7 +141,7 @@ Handle PipeWrap::Bind(const Arguments& args) { int r = uv_pipe_bind(&wrap->handle_, *name); // Error starting the pipe. - if (r) SetErrno(uv_last_error(Loop())); + if (r) SetErrno(uv_last_error(uv_default_loop())); return scope.Close(Integer::New(r)); } @@ -173,7 +172,7 @@ Handle PipeWrap::Listen(const Arguments& args) { int r = uv_listen((uv_stream_t*)&wrap->handle_, backlog, OnConnection); // Error starting the pipe. - if (r) SetErrno(uv_last_error(Loop())); + if (r) SetErrno(uv_last_error(uv_default_loop())); return scope.Close(Integer::New(r)); } @@ -226,7 +225,7 @@ void PipeWrap::AfterConnect(uv_connect_t* req, int status) { assert(wrap->object_.IsEmpty() == false); if (status) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); } Local argv[3] = { diff --git a/src/process_wrap.cc b/src/process_wrap.cc index 5c4282ffb0..6600a044c8 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -176,10 +175,10 @@ class ProcessWrap : public HandleWrap { Get(String::NewSymbol("windowsVerbatimArguments"))->IsTrue(); #endif - int r = uv_spawn(Loop(), &wrap->process_, options); + int r = uv_spawn(uv_default_loop(), &wrap->process_, options); if (r) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); } else { wrap->SetHandle((uv_handle_t*)&wrap->process_); @@ -212,7 +211,7 @@ class ProcessWrap : public HandleWrap { int r = uv_process_kill(&wrap->process_, signal); - if (r) SetErrno(uv_last_error(Loop())); + if (r) SetErrno(uv_last_error(uv_default_loop())); return scope.Close(Integer::New(r)); } diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 37eb592522..b363049793 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -21,24 +21,11 @@ #include #include -#include #include #include #include #include -#include - -// We do the following to minimize the detal between v0.6 branch. We want to -// use the variables as they were being used before. -#define slab_used NODE_VAR(slab_used) -#define slab_sym NODE_VAR(slab_sym) -#define handle_that_last_alloced NODE_VAR(handle_that_last_alloced) -#define buffer_sym NODE_VAR(buffer_sym) -#define buffer_constructor_template NODE_VAR(buffer_constructor_template) -#define write_queue_size_sym NODE_VAR(write_queue_size_sym) -#define stream_wrap_initialized NODE_VAR(stream_wrap_initialized) - namespace node { @@ -79,11 +66,19 @@ typedef class ReqWrap ShutdownWrap; typedef class ReqWrap WriteWrap; +static size_t slab_used; +static uv_stream_t* handle_that_last_alloced; +static Persistent slab_sym; +static Persistent buffer_sym; +static Persistent write_queue_size_sym; +static bool initialized; + + void StreamWrap::Initialize(Handle target) { - if (stream_wrap_initialized) { + if (initialized) { return; } else { - stream_wrap_initialized = true; + initialized = true; } HandleScope scope; @@ -134,7 +129,7 @@ Handle StreamWrap::ReadStart(const Arguments& args) { } // Error starting the tcp. - if (r) SetErrno(uv_last_error(Loop())); + if (r) SetErrno(uv_last_error(uv_default_loop())); return scope.Close(Integer::New(r)); } @@ -148,7 +143,7 @@ Handle StreamWrap::ReadStop(const Arguments& args) { int r = uv_read_stop(wrap->stream_); // Error starting the tcp. - if (r) SetErrno(uv_last_error(Loop())); + if (r) SetErrno(uv_last_error(uv_default_loop())); return scope.Close(Integer::New(r)); } @@ -158,7 +153,7 @@ char* StreamWrap::NewSlab(Handle global, Handle wrap_obj) { HandleScope scope; Local arg = Integer::NewFromUnsigned(SLAB_SIZE); - Local b = buffer_constructor_template->GetFunction()-> + Local b = Buffer::constructor_template->GetFunction()-> NewInstance(1, &arg); if (b.IsEmpty()) return NULL; global->SetHiddenValue(slab_sym, b); @@ -231,7 +226,7 @@ void StreamWrap::OnReadCommon(uv_stream_t* handle, ssize_t nread, slab_used -= buf.len; } - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); MakeCallback(wrap->object_, "onread", 0, NULL); return; } @@ -344,7 +339,7 @@ Handle StreamWrap::Write(const Arguments& args) { wrap->UpdateWriteQueueSize(); if (r) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); delete req_wrap; return scope.Close(v8::Null()); } else { @@ -364,7 +359,7 @@ void StreamWrap::AfterWrite(uv_write_t* req, int status) { assert(wrap->object_.IsEmpty() == false); if (status) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); } wrap->UpdateWriteQueueSize(); @@ -394,7 +389,7 @@ Handle StreamWrap::Shutdown(const Arguments& args) { req_wrap->Dispatched(); if (r) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); delete req_wrap; return scope.Close(v8::Null()); } else { @@ -414,7 +409,7 @@ void StreamWrap::AfterShutdown(uv_shutdown_t* req, int status) { HandleScope scope; if (status) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); } Local argv[3] = { diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 2871025d76..b2b8c5cd56 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -56,15 +55,6 @@ return scope.Close(Integer::New(-1)); \ } -#include - -// We do the following to minimize the detal between v0.6 branch. We want to -// use the variables as they were being used before. -#define tcpConstructor NODE_VAR(tcpConstructor) -#define family_symbol NODE_VAR(family_symbol) -#define address_symbol NODE_VAR(address_symbol) -#define port_symbol NODE_VAR(port_symbol) - namespace node { using v8::Object; @@ -82,6 +72,12 @@ using v8::Arguments; using v8::Integer; using v8::Undefined; +static Persistent tcpConstructor; +static Persistent family_symbol; +static Persistent address_symbol; +static Persistent port_symbol; + + typedef class ReqWrap ConnectWrap; @@ -155,7 +151,7 @@ Handle TCPWrap::New(const Arguments& args) { TCPWrap::TCPWrap(Handle object) : StreamWrap(object, (uv_stream_t*) &handle_) { - int r = uv_tcp_init(Loop(), &handle_); + int r = uv_tcp_init(uv_default_loop(), &handle_); assert(r == 0); // How do we proxy this error up to javascript? // Suggestion: uv_tcp_init() returns void. UpdateWriteQueueSize(); @@ -183,7 +179,7 @@ Handle TCPWrap::GetSockName(const Arguments& args) { Local sockname = Object::New(); if (r != 0) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); } else { family = address.ss_family; @@ -225,7 +221,7 @@ Handle TCPWrap::GetPeerName(const Arguments& args) { Local sockname = Object::New(); if (r != 0) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); } else { family = address.ss_family; @@ -258,7 +254,7 @@ Handle TCPWrap::SetNoDelay(const Arguments& args) { int r = uv_tcp_nodelay(&wrap->handle_, 1); if (r) - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); return Undefined(); } @@ -274,7 +270,7 @@ Handle TCPWrap::SetKeepAlive(const Arguments& args) { int r = uv_tcp_keepalive(&wrap->handle_, enable, delay); if (r) - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); return Undefined(); } @@ -290,7 +286,7 @@ Handle TCPWrap::SetSimultaneousAccepts(const Arguments& args) { int r = uv_tcp_simultaneous_accepts(&wrap->handle_, enable ? 1 : 0); if (r) - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); return Undefined(); } @@ -309,7 +305,7 @@ Handle TCPWrap::Bind(const Arguments& args) { int r = uv_tcp_bind(&wrap->handle_, address); // Error starting the tcp. - if (r) SetErrno(uv_last_error(Loop())); + if (r) SetErrno(uv_last_error(uv_default_loop())); return scope.Close(Integer::New(r)); } @@ -327,7 +323,7 @@ Handle TCPWrap::Bind6(const Arguments& args) { int r = uv_tcp_bind6(&wrap->handle_, address); // Error starting the tcp. - if (r) SetErrno(uv_last_error(Loop())); + if (r) SetErrno(uv_last_error(uv_default_loop())); return scope.Close(Integer::New(r)); } @@ -343,7 +339,7 @@ Handle TCPWrap::Listen(const Arguments& args) { int r = uv_listen((uv_stream_t*)&wrap->handle_, backlog, OnConnection); // Error starting the tcp. - if (r) SetErrno(uv_last_error(Loop())); + if (r) SetErrno(uv_last_error(uv_default_loop())); return scope.Close(Integer::New(r)); } @@ -378,7 +374,7 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) { // Successful accept. Call the onconnection callback in JavaScript land. argv[0] = client_obj; } else { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); argv[0] = v8::Null(); } @@ -397,7 +393,7 @@ void TCPWrap::AfterConnect(uv_connect_t* req, int status) { assert(wrap->object_.IsEmpty() == false); if (status) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); } Local argv[3] = { @@ -433,7 +429,7 @@ Handle TCPWrap::Connect(const Arguments& args) { req_wrap->Dispatched(); if (r) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); delete req_wrap; return scope.Close(v8::Null()); } else { @@ -460,7 +456,7 @@ Handle TCPWrap::Connect6(const Arguments& args) { req_wrap->Dispatched(); if (r) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); delete req_wrap; return scope.Close(v8::Null()); } else { diff --git a/src/timer_wrap.cc b/src/timer_wrap.cc index 2b29e5f854..470c2d6b98 100644 --- a/src/timer_wrap.cc +++ b/src/timer_wrap.cc @@ -21,7 +21,6 @@ #include #include -#include #define UNWRAP \ assert(!args.Holder().IsEmpty()); \ @@ -92,7 +91,7 @@ class TimerWrap : public HandleWrap { : HandleWrap(object, (uv_handle_t*) &handle_) { active_ = false; - int r = uv_timer_init(Loop(), &handle_); + int r = uv_timer_init(uv_default_loop(), &handle_); assert(r == 0); handle_.data = this; @@ -100,11 +99,11 @@ class TimerWrap : public HandleWrap { // uv_timer_init adds a loop reference. (That is, it calls uv_ref.) This // is not the behavior we want in Node. Timers should not increase the // ref count of the loop except when active. - uv_unref(Loop()); + uv_unref(uv_default_loop()); } ~TimerWrap() { - if (!active_) uv_ref(Loop()); + if (!active_) uv_ref(uv_default_loop()); } void StateChange() { @@ -114,11 +113,11 @@ class TimerWrap : public HandleWrap { if (!was_active && active_) { // If our state is changing from inactive to active, we // increase the loop's reference count. - uv_ref(Loop()); + uv_ref(uv_default_loop()); } else if (was_active && !active_) { // If our state is changing from active to inactive, we // decrease the loop's reference count. - uv_unref(Loop()); + uv_unref(uv_default_loop()); } } @@ -133,7 +132,7 @@ class TimerWrap : public HandleWrap { int r = uv_timer_start(&wrap->handle_, OnTimeout, timeout, repeat); // Error starting the timer. - if (r) SetErrno(uv_last_error(Loop())); + if (r) SetErrno(uv_last_error(uv_default_loop())); wrap->StateChange(); @@ -147,7 +146,7 @@ class TimerWrap : public HandleWrap { int r = uv_timer_stop(&wrap->handle_); - if (r) SetErrno(uv_last_error(Loop())); + if (r) SetErrno(uv_last_error(uv_default_loop())); wrap->StateChange(); @@ -161,7 +160,7 @@ class TimerWrap : public HandleWrap { int r = uv_timer_again(&wrap->handle_); - if (r) SetErrno(uv_last_error(Loop())); + if (r) SetErrno(uv_last_error(uv_default_loop())); wrap->StateChange(); @@ -187,7 +186,7 @@ class TimerWrap : public HandleWrap { int64_t repeat = uv_timer_get_repeat(&wrap->handle_); - if (repeat < 0) SetErrno(uv_last_error(Loop())); + if (repeat < 0) SetErrno(uv_last_error(uv_default_loop())); return scope.Close(Integer::New(repeat)); } diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc index 31949011f3..486c2a70b4 100644 --- a/src/tty_wrap.cc +++ b/src/tty_wrap.cc @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -125,7 +124,7 @@ class TTYWrap : StreamWrap { int r = uv_tty_get_winsize(&wrap->handle_, &width, &height); if (r) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); return v8::Undefined(); } @@ -144,7 +143,7 @@ class TTYWrap : StreamWrap { int r = uv_tty_set_mode(&wrap->handle_, args[0]->IsTrue()); if (r) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); } return scope.Close(Integer::New(r)); @@ -170,7 +169,7 @@ class TTYWrap : StreamWrap { TTYWrap(Handle object, int fd, bool readable) : StreamWrap(object, (uv_stream_t*)&handle_) { - uv_tty_init(Loop(), &handle_, fd, readable); + uv_tty_init(uv_default_loop(), &handle_, fd, readable); } uv_tty_t handle_; diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 5f4b7eed19..c99ecbafe9 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -124,7 +123,7 @@ private: UDPWrap::UDPWrap(Handle object): HandleWrap(object, (uv_handle_t*)&handle_) { - int r = uv_udp_init(Loop(), &handle_); + int r = uv_udp_init(uv_default_loop(), &handle_); assert(r == 0); // can't fail anyway handle_.data = reinterpret_cast(this); } @@ -203,7 +202,7 @@ Handle UDPWrap::DoBind(const Arguments& args, int family) { } if (r) - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); return scope.Close(Integer::New(r)); } @@ -314,7 +313,7 @@ Handle UDPWrap::DoSend(const Arguments& args, int family) { req_wrap->Dispatched(); if (r) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); delete req_wrap; return Null(); } @@ -341,8 +340,8 @@ Handle UDPWrap::RecvStart(const Arguments& args) { // UV_EALREADY means that the socket is already bound but that's okay int r = uv_udp_recv_start(&wrap->handle_, OnAlloc, OnRecv); - if (r && uv_last_error(Loop()).code != UV_EALREADY) { - SetErrno(uv_last_error(Loop())); + if (r && uv_last_error(uv_default_loop()).code != UV_EALREADY) { + SetErrno(uv_last_error(uv_default_loop())); return False(); } @@ -378,7 +377,7 @@ Handle UDPWrap::GetSockName(const Arguments& args) { return scope.Close(sockname); } else { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); return Null(); } } @@ -397,7 +396,7 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) { assert(wrap->object_.IsEmpty() == false); if (status) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); } Local argv[4] = { @@ -475,7 +474,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle, }; if (nread == -1) { - SetErrno(uv_last_error(Loop())); + SetErrno(uv_last_error(uv_default_loop())); } else { Local rinfo = Object::New(); diff --git a/test/addons/shared-buffer/binding.cc b/test/addons/shared-buffer/binding.cc deleted file mode 100644 index d81f1d4f22..0000000000 --- a/test/addons/shared-buffer/binding.cc +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include - -using namespace v8; - -extern "C" { - void init(Handle target); -} - - -#define BUFSIZE 1024 -static uint8_t buf[BUFSIZE]; -static uv_mutex_t lock; - - -Handle Get(const Arguments& args) { - HandleScope scope; - - int index = args[0]->Uint32Value(); - - if (index < 0 || BUFSIZE <= index) { - return ThrowException(Exception::Error(String::New("out of bounds"))); - } - - return scope.Close(Integer::New(buf[index])); -} - - -Handle Set(const Arguments& args) { - uv_mutex_lock(&lock); - HandleScope scope; - - int index = args[0]->Uint32Value(); - - if (index < 0 || BUFSIZE <= index) { - return ThrowException(Exception::Error(String::New("out of bounds"))); - } - - buf[index] = args[1]->Uint32Value(); - - Local val = Integer::New(buf[index]); - - uv_mutex_unlock(&lock); - - return scope.Close(val); -} - - -void init(Handle target) { - NODE_SET_METHOD(target, "get", Get); - NODE_SET_METHOD(target, "set", Set); - target->Set(String::New("length"), Integer::New(BUFSIZE)); - uv_mutex_init(&lock); -} diff --git a/test/addons/shared-buffer/binding.gyp b/test/addons/shared-buffer/binding.gyp deleted file mode 100644 index 3bfb84493f..0000000000 --- a/test/addons/shared-buffer/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'binding', - 'sources': [ 'binding.cc' ] - } - ] -} diff --git a/test/addons/shared-buffer/test.js b/test/addons/shared-buffer/test.js deleted file mode 100644 index 9ba896f28a..0000000000 --- a/test/addons/shared-buffer/test.js +++ /dev/null @@ -1,19 +0,0 @@ -var assert = require('assert'); -var binding = require('./out/Release/binding'); -var isolates = process.binding('isolates'); - -console.log("binding.length =", binding.length); - -if (process.tid === 1) { - var isolate = isolates.create(process.argv); - for (var i = 0; i < binding.length; i++) { - console.log('parent', - 'binding.set(' + i + ', ' + i + ')', - binding.set(i, i)); - } -} else { - for (var i = 0; i < binding.length; i++) { - console.log('child', 'binding.get(' + i + ')', binding.get(i)); - } -} - diff --git a/test/simple/test-child-process-fork.js b/test/simple/test-child-process-fork.js index ea99ae7704..41cc28c72e 100644 --- a/test/simple/test-child-process-fork.js +++ b/test/simple/test-child-process-fork.js @@ -24,13 +24,7 @@ var common = require('../common'); var fork = require('child_process').fork; var args = ['foo', 'bar']; -var options = { - thread: process.TEST_ISOLATE ? true : false -}; - -var n = fork(common.fixturesDir + '/child-process-spawn-node.js', - args, - options); +var n = fork(common.fixturesDir + '/child-process-spawn-node.js', args); assert.deepEqual(args, ['foo', 'bar']); var messageCount = 0; diff --git a/test/simple/test-child-process-fork2.js b/test/simple/test-child-process-fork2.js index 66dff69ac5..6f292fa199 100644 --- a/test/simple/test-child-process-fork2.js +++ b/test/simple/test-child-process-fork2.js @@ -27,11 +27,7 @@ var net = require('net'); var socketCloses = 0; var N = 10; -var options = { - thread: process.TEST_ISOLATE ? true : false -}; - -var n = fork(common.fixturesDir + '/fork2.js', [], options); +var n = fork(common.fixturesDir + '/fork2.js'); var messageCount = 0; diff --git a/test/simple/test-child-process-fork3.js b/test/simple/test-child-process-fork3.js index 21d547e026..a8a8985f05 100644 --- a/test/simple/test-child-process-fork3.js +++ b/test/simple/test-child-process-fork3.js @@ -25,12 +25,8 @@ var fork = require('child_process').fork; var filename = common.fixturesDir + '/destroy-stdin.js'; -var options = { - thread: process.TEST_ISOLATE ? true : false -}; - // Ensure that we don't accidentally close fd 0 and // reuse it for something else, it causes all kinds // of obscure bugs. process.stdin.destroy(); -fork(filename, [], options).stdin.on('end', process.exit); +fork(filename).stdin.on('end', process.exit); diff --git a/test/simple/test-debugger-repl-utf8.js b/test/simple/test-debugger-repl-utf8.js index 308f6305eb..820a539143 100644 --- a/test/simple/test-debugger-repl-utf8.js +++ b/test/simple/test-debugger-repl-utf8.js @@ -76,19 +76,12 @@ function addTest(input, output) { } // Initial lines -if (process.features.isolates) { - addTest(null, [ - /break in .*:1/, - /1/, /2/, /3/ - ]); -} else { - addTest(null, [ - /listening on port 5858/, - /connecting... ok/, - /break in .*:1/, - /1/, /2/, /3/ - ]); -} +addTest(null, [ + /listening on port 5858/, + /connecting... ok/, + /break in .*:1/, + /1/, /2/, /3/ +]); // Next addTest('n', [ diff --git a/test/simple/test-debugger-repl.js b/test/simple/test-debugger-repl.js index a81da29e5a..df1b14298e 100644 --- a/test/simple/test-debugger-repl.js +++ b/test/simple/test-debugger-repl.js @@ -81,19 +81,12 @@ function addTest(input, output) { } // Initial lines -if (process.features.isolates) { - addTest(null, [ - /break in .*:1/, - /1/, /2/, /3/ - ]); -} else { - addTest(null, [ - /listening on port 5858/, - /connecting... ok/, - /break in .*:1/, - /1/, /2/, /3/ - ]); -} +addTest(null, [ + /listening on port 5858/, + /connecting... ok/, + /break in .*:1/, + /1/, /2/, /3/ +]); // Next addTest('n', [ diff --git a/test/simple/test-isolates-ping-pong.js b/test/simple/test-isolates-ping-pong.js deleted file mode 100644 index 4340ff6e25..0000000000 --- a/test/simple/test-isolates-ping-pong.js +++ /dev/null @@ -1,68 +0,0 @@ -var isolates = process.binding('isolates'); -var assert = require('assert'); - -var N_ISOLATES = 4; -var N_MESSAGES = 20; -var N_MESSAGES_PER_TICK = 4; - -assert(N_MESSAGES % N_MESSAGES_PER_TICK == 0); - -if (process.tid === 1) - master(); -else - child(); - -function master() { - for (var i = 0; i < N_ISOLATES; ++i) spawn(); - - function spawn() { - var isolate = isolates.create(process.argv); - - var gotExit = false; // exit event emitted? - var msgId = 0; // message IDs seen so far - var tick = 0; - - isolate.onexit = function() { - gotExit = true; - }; - - isolate.onmessage = function(buf) { - var msg = JSON.parse(buf); - assert.equal(msg.id, msgId + 1); // verify that messages arrive in order - assert.equal(msg.tick, tick); // and on the proper tick (=full mq drain) - msgId = msg.id; - if (msgId % N_MESSAGES_PER_TICK == 0) tick++; - isolate.send(buf); - }; - - process.on('exit', function() { - assert.equal(gotExit, true); - assert.equal(msgId, N_MESSAGES); - assert.equal(tick, N_MESSAGES / N_MESSAGES_PER_TICK); - }); - } -} - -function child() { - var msgId = 0; - var tick = 0; - - function send() { - // Send multiple messages, verify that the message queue - // is completely drained on each tick of the event loop. - for (var i = 0; i < N_MESSAGES_PER_TICK; ++i) { - process.send({tick:tick, id:++msgId}); - } - - if (msgId < N_MESSAGES) { - setTimeout(send, 10); - } - - tick++; - } - - send(); - - process._onmessage = function(m) { - }; -} diff --git a/test/simple/test-isolates0.js b/test/simple/test-isolates0.js deleted file mode 100644 index b85fc63023..0000000000 --- a/test/simple/test-isolates0.js +++ /dev/null @@ -1,60 +0,0 @@ -var fs = require('fs'); -var http = require('http'); -var isolates = process.binding('isolates'); - -console.log("count: %d", isolates.count()); - -if (process.tid === 1) { - var isolate = isolates.create(process.argv, { - debug: function init(d) { - d.onmessage = function(data) { - data = JSON.parse(data); - if (data.event === 'break') { - d.write(JSON.stringify({ - type: 'request', - seq: 1, - command: 'continue' - })); - } - }; - } - }); - - isolate.onmessage = function() { - console.error("onmessage"); - }; - isolate.onexit = function() { - console.error("onexit"); - }; - - console.error("master"); - fs.stat(__dirname, function(err, stat) { - if (err) throw err; - console.error('thread 1', stat.mtime); - }); - - setTimeout(function() { - fs.stat(__dirname, function(err, stat) { - if (err) throw err; - console.error('thread 1', stat.mtime); - }); - }, 500); - - console.log("thread 1 count: %d", isolates.count()); -} else { - console.error("slave"); - fs.stat(__dirname, function(err, stat) { - if (err) throw err; - console.error('thread 2', stat.mtime); - }); - - setTimeout(function() { - fs.stat(__dirname, function(err, stat) { - if (err) throw err; - console.error('thread 2', stat.mtime); - process.exit(); - }); - }, 500); - - console.error("thread 2 count: %d", isolates.count()); -} diff --git a/test/simple/test-isolates1.js b/test/simple/test-isolates1.js deleted file mode 100644 index 1823b8fe76..0000000000 --- a/test/simple/test-isolates1.js +++ /dev/null @@ -1,13 +0,0 @@ -// Skip this test if Node is not compiled with isolates support. -if (!process.features.isolates) return; - -var assert = require('assert'); - -// This is the same test as test-child-process-fork except it uses isolates -// instead of processes. process.TEST_ISOLATE is a ghetto method of passing -// some information into the other test. -process.TEST_ISOLATE = true; -require('./test-child-process-fork'); - -var numThreads = process.binding('isolates').count(); -assert.ok(numThreads > 1); diff --git a/test/simple/test-isolates2.js b/test/simple/test-isolates2.js deleted file mode 100644 index a3c30c770b..0000000000 --- a/test/simple/test-isolates2.js +++ /dev/null @@ -1,13 +0,0 @@ -// Skip this test if Node is not compiled with isolates support. -if (!process.features.isolates) return; - -var assert = require('assert'); - -// This is the same test as test-child-process-fork2 except it uses isolates -// instead of processes. process.TEST_ISOLATE is a ghetto method of passing -// some information into the other test. -process.TEST_ISOLATE = true; -require('./test-child-process-fork2'); - -var numThreads = process.binding('isolates').count(); -assert.ok(numThreads > 1); diff --git a/test/simple/test-isolates3.js b/test/simple/test-isolates3.js deleted file mode 100644 index d354bca01d..0000000000 --- a/test/simple/test-isolates3.js +++ /dev/null @@ -1,13 +0,0 @@ -// Skip this test if Node is not compiled with isolates support. -if (!process.features.isolates) return; - -var assert = require('assert'); - -// This is the same test as test-child-process-fork3 except it uses isolates -// instead of processes. process.TEST_ISOLATE is a ghetto method of passing -// some information into the other test. -process.TEST_ISOLATE = true; -require('./test-child-process-fork3'); - -var numThreads = process.binding('isolates').count(); -assert.ok(numThreads > 1);