move isolate V8 functions out of node.cc
This commit is contained in:
parent
20ba454ef9
commit
5fc0c27d5c
85
src/node.cc
85
src/node.cc
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <node.h>
|
#include <node.h>
|
||||||
#include <node_isolate.h>
|
#include <node_isolate.h>
|
||||||
|
#include <node_internals.h>
|
||||||
|
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
@ -142,10 +143,6 @@ static bool print_eval;
|
|||||||
|
|
||||||
static void CheckStatus(uv_timer_t* watcher, int status);
|
static void CheckStatus(uv_timer_t* watcher, int status);
|
||||||
|
|
||||||
void StartThread(Isolate* isolate,
|
|
||||||
int argc,
|
|
||||||
char** argv);
|
|
||||||
|
|
||||||
|
|
||||||
uv_loop_t* Loop() {
|
uv_loop_t* Loop() {
|
||||||
#if defined(HAVE_ISOLATES) && HAVE_ISOLATES
|
#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,
|
static Handle<Value> ProcessTitleGetter(Local<String> property,
|
||||||
const AccessorInfo& info) {
|
const AccessorInfo& info) {
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
@ -2206,10 +2127,6 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
|
|||||||
|
|
||||||
NODE_SET_METHOD(process, "binding", Binding);
|
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;
|
return process;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,10 @@ NODE_EXT_LIST_ITEM(node_signal_watcher)
|
|||||||
NODE_EXT_LIST_ITEM(node_os)
|
NODE_EXT_LIST_ITEM(node_os)
|
||||||
NODE_EXT_LIST_ITEM(node_zlib)
|
NODE_EXT_LIST_ITEM(node_zlib)
|
||||||
|
|
||||||
|
#if defined(HAVE_ISOLATES) && HAVE_ISOLATES
|
||||||
|
NODE_EXT_LIST_ITEM(node_isolates)
|
||||||
|
#endif
|
||||||
|
|
||||||
// libuv rewrite
|
// libuv rewrite
|
||||||
NODE_EXT_LIST_ITEM(node_timer_wrap)
|
NODE_EXT_LIST_ITEM(node_timer_wrap)
|
||||||
NODE_EXT_LIST_ITEM(node_tcp_wrap)
|
NODE_EXT_LIST_ITEM(node_tcp_wrap)
|
||||||
|
@ -24,6 +24,13 @@
|
|||||||
|
|
||||||
namespace node {
|
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
|
#ifndef offset_of
|
||||||
// g++ in strict mode complains loudly about the system offsetof() macro
|
// g++ in strict mode complains loudly about the system offsetof() macro
|
||||||
// because it uses NULL as the base address.
|
// because it uses NULL as the base address.
|
||||||
|
@ -19,16 +19,34 @@
|
|||||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// 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 <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace node {
|
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 bool initialized;
|
||||||
static volatile int id;
|
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
|
} // namespace node
|
||||||
|
|
||||||
|
|
||||||
|
NODE_MODULE(node_isolates, node::InitIsolates)
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var binding = require('./out/Release/binding');
|
var binding = require('./out/Release/binding');
|
||||||
|
var isolates = process.binding('isolates');
|
||||||
|
|
||||||
console.log("binding.length =", binding.length);
|
console.log("binding.length =", binding.length);
|
||||||
|
|
||||||
if (process.tid === 1) {
|
if (process.tid === 1) {
|
||||||
var isolate = process._newIsolate(process.argv);
|
var isolate = isolates.create(process.argv);
|
||||||
for (var i = 0; i < binding.length; i++) {
|
for (var i = 0; i < binding.length; i++) {
|
||||||
console.log('parent',
|
console.log('parent',
|
||||||
'binding.set(' + i + ', ' + i + ')',
|
'binding.set(' + i + ', ' + i + ')',
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var http = require('http');
|
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) {
|
if (process.tid === 1) {
|
||||||
var isolate = process._newIsolate(process.argv);
|
var isolate = isolates.create(process.argv);
|
||||||
//process._joinIsolate(isolate);
|
//process._joinIsolate(isolate);
|
||||||
console.error("master");
|
console.error("master");
|
||||||
fs.stat(__dirname, function(err, stat) {
|
fs.stat(__dirname, function(err, stat) {
|
||||||
@ -19,7 +20,7 @@ if (process.tid === 1) {
|
|||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
console.log("thread 1 count: %d", process._countIsolate());
|
console.log("thread 1 count: %d", isolates.count());
|
||||||
} else {
|
} else {
|
||||||
console.error("slave");
|
console.error("slave");
|
||||||
fs.stat(__dirname, function(err, stat) {
|
fs.stat(__dirname, function(err, stat) {
|
||||||
@ -34,5 +35,5 @@ if (process.tid === 1) {
|
|||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
console.error("thread 2 count: %d", process._countIsolate());
|
console.error("thread 2 count: %d", isolates.count());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user