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_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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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 + ')',
|
||||
|
@ -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…
x
Reference in New Issue
Block a user