Browse Source

move isolate V8 functions out of node.cc

v0.7.4-release
Ryan Dahl 13 years ago
committed by Ben Noordhuis
parent
commit
5fc0c27d5c
  1. 85
      src/node.cc
  2. 4
      src/node_extensions.h
  3. 7
      src/node_internals.h
  4. 113
      src/node_isolate.cc
  5. 3
      test/addons/shared-buffer/test.js
  6. 9
      test/simple/test-isolates.js

85
src/node.cc

@ -21,6 +21,7 @@
#include <node.h>
#include <node_isolate.h>
#include <node_internals.h>
#include <uv.h>
@ -142,10 +143,6 @@ static bool print_eval;
static void CheckStatus(uv_timer_t* watcher, int status);
void StartThread(Isolate* isolate,
int argc,
char** argv);
uv_loop_t* Loop() {
#if defined(HAVE_ISOLATES) && HAVE_ISOLATES
@ -1859,82 +1856,6 @@ static Handle<Value> Binding(const Arguments& args) {
}
static void RunIsolate(void* arg) {
node::Isolate* isolate = reinterpret_cast<node::Isolate*>(arg);
isolate->Enter();
StartThread(isolate, isolate->argc_, isolate->argv_);
isolate->Dispose();
delete isolate;
}
static char magic_isolate_cookie_[] = "magic isolate cookie";
static Handle<Value> NewIsolate(const Arguments& args) {
HandleScope scope;
assert(args[0]->IsArray());
Local<Array> argv = args[0].As<Array>();
assert(argv->Length() >= 2);
// Note that isolate lock is aquired in the constructor here. It will not
// be unlocked until RunIsolate starts and calls isolate->Enter().
Isolate* isolate = new node::Isolate();
// 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 (uv_thread_create(&isolate->tid_, RunIsolate, isolate)) {
delete isolate;
return Null();
}
Local<ObjectTemplate> tpl = ObjectTemplate::New();
tpl->SetInternalFieldCount(2);
Local<Object> obj = tpl->NewInstance();
obj->SetPointerInInternalField(0, magic_isolate_cookie_);
obj->SetPointerInInternalField(1, isolate);
return scope.Close(obj);
}
static Handle<Value> CountIsolate(const Arguments& args) {
HandleScope scope;
return scope.Close(Integer::New(Isolate::Count()));
}
static Handle<Value> JoinIsolate(const Arguments& args) {
HandleScope scope;
assert(args[0]->IsObject());
Local<Object> obj = args[0]->ToObject();
assert(obj->InternalFieldCount() == 2);
assert(obj->GetPointerFromInternalField(0) == magic_isolate_cookie_);
Isolate* ti = reinterpret_cast<Isolate*>(
obj->GetPointerFromInternalField(1));
if (uv_thread_join(&ti->tid_))
return False(); // error
else
return True(); // ok
}
static Handle<Value> ProcessTitleGetter(Local<String> property,
const AccessorInfo& info) {
HandleScope scope;
@ -2206,10 +2127,6 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
NODE_SET_METHOD(process, "binding", Binding);
NODE_SET_METHOD(process, "_newIsolate", NewIsolate);
NODE_SET_METHOD(process, "_countIsolate", CountIsolate);
NODE_SET_METHOD(process, "_joinIsolate", JoinIsolate);
return process;
}

4
src/node_extensions.h

@ -34,6 +34,10 @@ 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)

7
src/node_internals.h

@ -24,6 +24,13 @@
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.

113
src/node_isolate.cc

@ -19,16 +19,34 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "node_isolate.h"
#include <node.h>
#include <node_isolate.h>
#include <node_internals.h>
#include <v8.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
namespace node {
using v8::Arguments;
using v8::Array;
using v8::False;
using v8::Handle;
using v8::HandleScope;
using v8::Integer;
using v8::Local;
using v8::Null;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::True;
using v8::Value;
static char magic_isolate_cookie_[] = "magic isolate cookie";
static volatile bool initialized;
static volatile int id;
@ -166,4 +184,95 @@ void Isolate::Dispose() {
}
static void RunIsolate(void* arg) {
node::Isolate* isolate = reinterpret_cast<node::Isolate*>(arg);
isolate->Enter();
// TODO in the future when v0.6 is dead, move StartThread and related
// handles into node_isolate.cc. It is currently organized like this to
// minimize diff (and thus merge conflicts) between the legacy v0.6
// branch.
StartThread(isolate, isolate->argc_, isolate->argv_);
isolate->Dispose();
delete isolate;
}
static Handle<Value> CreateIsolate(const Arguments& args) {
HandleScope scope;
assert(args[0]->IsArray());
Local<Array> argv = args[0].As<Array>();
assert(argv->Length() >= 2);
// Note that isolate lock is aquired in the constructor here. It will not
// be unlocked until RunIsolate starts and calls isolate->Enter().
Isolate* isolate = new node::Isolate();
// 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 (uv_thread_create(&isolate->tid_, RunIsolate, isolate)) {
delete isolate;
return Null();
}
// TODO instead of ObjectTemplate - have a special wrapper.
Local<ObjectTemplate> tpl = ObjectTemplate::New();
tpl->SetInternalFieldCount(2);
Local<Object> obj = tpl->NewInstance();
obj->SetPointerInInternalField(0, magic_isolate_cookie_);
obj->SetPointerInInternalField(1, isolate);
return scope.Close(obj);
}
static Handle<Value> CountIsolate(const Arguments& args) {
HandleScope scope;
return scope.Close(Integer::New(Isolate::Count()));
}
static Handle<Value> JoinIsolate(const Arguments& args) {
HandleScope scope;
assert(args[0]->IsObject());
Local<Object> obj = args[0]->ToObject();
assert(obj->InternalFieldCount() == 2);
assert(obj->GetPointerFromInternalField(0) == magic_isolate_cookie_);
Isolate* ti = reinterpret_cast<Isolate*>(
obj->GetPointerFromInternalField(1));
if (uv_thread_join(&ti->tid_))
return False(); // error
else
return True(); // ok
}
void InitIsolates(Handle<Object> target) {
HandleScope scope;
NODE_SET_METHOD(target, "create", CreateIsolate);
NODE_SET_METHOD(target, "count", CountIsolate);
NODE_SET_METHOD(target, "join", JoinIsolate);
}
} // namespace node
NODE_MODULE(node_isolates, node::InitIsolates)

3
test/addons/shared-buffer/test.js

@ -1,10 +1,11 @@
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 = process._newIsolate(process.argv);
var isolate = isolates.create(process.argv);
for (var i = 0; i < binding.length; i++) {
console.log('parent',
'binding.set(' + i + ', ' + i + ')',

9
test/simple/test-isolates.js

@ -1,10 +1,11 @@
var fs = require('fs');
var http = require('http');
var isolates = process.binding('isolates');
console.log("count: %d", process._countIsolate());
console.log("count: %d", isolates.count());
if (process.tid === 1) {
var isolate = process._newIsolate(process.argv);
var isolate = isolates.create(process.argv);
//process._joinIsolate(isolate);
console.error("master");
fs.stat(__dirname, function(err, stat) {
@ -19,7 +20,7 @@ if (process.tid === 1) {
});
}, 500);
console.log("thread 1 count: %d", process._countIsolate());
console.log("thread 1 count: %d", isolates.count());
} else {
console.error("slave");
fs.stat(__dirname, function(err, stat) {
@ -34,5 +35,5 @@ if (process.tid === 1) {
});
}, 500);
console.error("thread 2 count: %d", process._countIsolate());
console.error("thread 2 count: %d", isolates.count());
}

Loading…
Cancel
Save