Reviewers: adamk,

Message:
PTAL, this will fix the tree (at least my part of the failure :)

Description:
Add support for multiple Workers in d8

The previous version only allowed one Worker, but this was causing the V8 Linux
isolates build to fail:
http://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20isolates/builds/4128

BUG=chromium:497295
LOG=n

Please review this at https://codereview.chromium.org/1192923002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+49, -10 lines):
  M src/d8.h
  M src/d8.cc
  M test/mjsunit/d8-worker.js


Index: src/d8.cc
diff --git a/src/d8.cc b/src/d8.cc
index 28342363e940f77e9faf402c61c5b888d5eb0d29..3f0b6c95b4468ddf63563b66a052045478bb2dba 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -205,7 +205,7 @@ base::Mutex Shell::context_mutex_;
 const base::TimeTicks Shell::kInitialTicks =
     base::TimeTicks::HighResolutionNow();
 Persistent<Context> Shell::utility_context_;
-Worker Shell::worker_;
+i::List<Worker*> Shell::workers_;
 i::List<SharedArrayBuffer::Contents> Shell::externalized_shared_contents_;
 #endif  // !V8_SHARED

@@ -686,8 +686,12 @@ void Shell::WorkerNew(const v8::FunctionCallbackInfo<v8::Value>& args) {
     return;
   }

+  Worker* worker = new Worker;
+  args.This()->SetInternalField(0, External::New(isolate, worker));
+  workers_.Add(worker);
+
   String::Utf8Value function_string(args[0]->ToString());
-  worker_.StartExecuteInThread(isolate, *function_string);
+  worker->StartExecuteInThread(isolate, *function_string);
 }


@@ -701,6 +705,15 @@ void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
     return;
   }

+  Local<Value> this_value = args.This()->GetInternalField(0);
+  if (!this_value->IsExternal()) {
+    Throw(isolate, "this is not a Worker");
+    return;
+  }
+
+  Worker* worker =
+      static_cast<Worker*>(Local<External>::Cast(this_value)->Value());
+
   Handle<Value> message = args[0];
   ObjectList to_transfer;
   if (args.Length() >= 2) {
@@ -729,7 +742,7 @@ void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
   ObjectList seen_objects;
   SerializationData* data = new SerializationData;
   if (SerializeValue(isolate, message, to_transfer, &seen_objects, data)) {
-    worker_.PostMessage(data);
+    worker->PostMessage(data);
   } else {
     delete data;
   }
@@ -739,7 +752,17 @@ void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) { void Shell::WorkerGetMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
   Isolate* isolate = args.GetIsolate();
   HandleScope handle_scope(isolate);
-  SerializationData* data = worker_.GetMessage();
+
+  Local<Value> this_value = args.This()->GetInternalField(0);
+  if (!this_value->IsExternal()) {
+    Throw(isolate, "this is not a Worker");
+    return;
+  }
+
+  Worker* worker =
+      static_cast<Worker*>(Local<External>::Cast(this_value)->Value());
+
+  SerializationData* data = worker->GetMessage();
   if (data) {
     int offset = 0;
     Local<Value> data_value;
@@ -752,7 +775,19 @@ void Shell::WorkerGetMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {


void Shell::WorkerTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) {
-  worker_.Terminate();
+  Isolate* isolate = args.GetIsolate();
+  HandleScope handle_scope(isolate);
+  Local<Value> this_value = args.This()->GetInternalField(0);
+  if (!this_value->IsExternal()) {
+    Throw(isolate, "this is not a Worker");
+    return;
+  }
+
+  Worker* worker =
+      static_cast<Worker*>(Local<External>::Cast(this_value)->Value());
+  worker->Terminate();
+  workers_.RemoveElement(worker);
+  delete worker;
 }
 #endif  // !V8_SHARED

@@ -1100,6 +1135,7 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
   worker_fun_template->PrototypeTemplate()->Set(
       String::NewFromUtf8(isolate, "getMessage"),
       FunctionTemplate::New(isolate, WorkerGetMessage));
+  worker_fun_template->InstanceTemplate()->SetInternalFieldCount(1);
   global_template->Set(String::NewFromUtf8(isolate, "Worker"),
                        worker_fun_template);
 #endif  // !V8_SHARED
@@ -2148,7 +2184,13 @@ MaybeLocal<Value> Shell::DeserializeValue(Isolate* isolate,


 void Shell::CleanupWorkers() {
-  worker_.Terminate();
+  for (int i = 0; i < workers_.length(); ++i) {
+    Worker* worker = workers_[i];
+    worker->Terminate();
+    delete worker;
+  }
+  workers_.Clear();
+
   for (int i = 0; i < externalized_shared_contents_.length(); ++i) {
     const SharedArrayBuffer::Contents& contents =
         externalized_shared_contents_[i];
Index: src/d8.h
diff --git a/src/d8.h b/src/d8.h
index 11a1c6287faa4fa803cfaf4c083eb6a3b006a752..23b66e4c3234b9f7871ee0c47c4e07895626345e 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -461,7 +461,7 @@ class Shell : public i::AllStatic {
   static base::OS::MemoryMappedFile* counters_file_;
   static base::Mutex context_mutex_;
   static const base::TimeTicks kInitialTicks;
-  static Worker worker_;
+  static i::List<Worker*> workers_;
static i::List<SharedArrayBuffer::Contents> externalized_shared_contents_;

   static Counter* GetCounter(const char* name, bool is_histogram);
Index: test/mjsunit/d8-worker.js
diff --git a/test/mjsunit/d8-worker.js b/test/mjsunit/d8-worker.js
index 787a48538938bda4e99e7e0d889cf6a44d08c551..807791717e1f6f7f047a9cc718468ad4f138a176 100644
--- a/test/mjsunit/d8-worker.js
+++ b/test/mjsunit/d8-worker.js
@@ -103,9 +103,6 @@ if (this.Worker) {

   assertEquals("Starting worker", w.getMessage());

-  // Currently can only create one worker at a time.
-  assertThrows(function() { new Worker(f); });
-
   w.postMessage(undefined);
   w.postMessage(null);
   w.postMessage(true);


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to