Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
move isolate V8 functions out of node.cc
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Dec 23, 2011
1 parent 2ac02f4 commit 1a3b283
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 91 deletions.
85 changes: 1 addition & 84 deletions src/node.cc
Expand Up @@ -21,6 +21,7 @@

#include <node.h>
#include <node_isolate.h>
#include <node_internals.h>

#include <uv.h>

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 4 additions & 0 deletions src/node_extensions.h
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions src/node_internals.h
Expand Up @@ -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.
Expand Down
113 changes: 111 additions & 2 deletions src/node_isolate.cc
Expand Up @@ -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;
Expand Down Expand Up @@ -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 changes: 2 additions & 1 deletion 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 + ')',
Expand Down
9 changes: 5 additions & 4 deletions 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) {
Expand All @@ -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) {
Expand All @@ -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());
}

0 comments on commit 1a3b283

Please sign in to comment.