isolates: add _newIsolate() and _joinIsolate() to process object
authorBen Noordhuis <info@bnoordhuis.nl>
Wed, 23 Nov 2011 20:46:22 +0000 (21:46 +0100)
committerRyan Dahl <ry@tinyclouds.org>
Tue, 27 Dec 2011 20:54:21 +0000 (12:54 -0800)
src/node.cc
src/node_isolate.cc

index e80fec8..6352583 100644 (file)
@@ -1847,6 +1847,52 @@ static Handle<Value> Binding(const Arguments& args) {
 }
 
 
+static void RunIsolate(void* arg) {
+  uv_loop_t* loop = uv_loop_new();
+  Isolate* isolate = Isolate::New(loop);
+}
+
+
+static char magic_isolate_cookie_[] = "magic isolate cookie";
+
+
+static Handle<Value> NewIsolate(const Arguments& args) {
+  HandleScope scope;
+
+  uv_thread_t* tid = new uv_thread_t;
+
+  if (uv_thread_create(tid, RunIsolate, NULL))
+    return Null();
+
+  Local<ObjectTemplate> tpl = ObjectTemplate::New();
+  tpl->SetInternalFieldCount(2);
+
+  Local<Object> obj = tpl->NewInstance();
+  obj->SetPointerInInternalField(0, magic_isolate_cookie_);
+  obj->SetPointerInInternalField(1, tid);
+
+  return scope.Close(obj);
+}
+
+
+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_);
+
+  uv_thread_t* tid = (uv_thread_t*) obj->GetPointerFromInternalField(1);
+
+  if (uv_thread_join(tid))
+    return False(); // error
+  else
+    return True();  // ok
+}
+
+
 static Handle<Value> ProcessTitleGetter(Local<String> property,
                                         const AccessorInfo& info) {
   HandleScope scope;
@@ -2119,6 +2165,9 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
 
   NODE_SET_METHOD(process, "binding", Binding);
 
+  NODE_SET_METHOD(process, "_newIsolate", NewIsolate);
+  NODE_SET_METHOD(process, "_joinIsolate", JoinIsolate);
+
   return process;
 }
 
index 1255850..808a872 100644 (file)
@@ -35,9 +35,15 @@ Isolate* Isolate::New(uv_loop_t* loop) {
 
 
 Isolate::Isolate(uv_loop_t* loop) {
+  SLIST_INIT(&at_exit_callbacks_);
   loop_ = loop;
+
   isolate_ = v8::Isolate::GetCurrent();
-  SLIST_INIT(&at_exit_callbacks_);
+  if (isolate_ == NULL) {
+    isolate_ = v8::Isolate::New();
+    isolate_->Enter();
+  }
+
   assert(isolate_->GetData() == NULL);
   isolate_->SetData(this);
 }