d8 workers: make sure Shell::Quit is only called once
authorbinji <binji@chromium.org>
Tue, 14 Jul 2015 17:42:03 +0000 (10:42 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 14 Jul 2015 17:42:17 +0000 (17:42 +0000)
When running with isolates, Quit can be called simultaneously by two threads.
If this happens, then both threads try to clean up the Workers, which could
crash.

BUG=v8:4279
R=jarin@chromium.org
R=machenbach@chromium.org
LOG=n

Review URL: https://codereview.chromium.org/1230403003

Cr-Commit-Position: refs/heads/master@{#29654}

src/d8.cc
src/d8.h
test/mjsunit/mjsunit.status

index 2b1832a..d882e45 100644 (file)
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -216,6 +216,7 @@ Persistent<Context> Shell::evaluation_context_;
 ArrayBuffer::Allocator* Shell::array_buffer_allocator;
 ShellOptions Shell::options;
 const char* Shell::kPrompt = "d8> ";
+base::OnceType Shell::quit_once_ = V8_ONCE_INIT;
 
 #ifndef V8_SHARED
 bool CounterMap::Match(void* key1, void* key2) {
@@ -809,16 +810,22 @@ void Shell::WorkerTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) {
 #endif  // !V8_SHARED
 
 
-void Shell::Quit(const v8::FunctionCallbackInfo<v8::Value>& args) {
-  int exit_code = args[0]->Int32Value();
+void Shell::QuitOnce(v8::FunctionCallbackInfo<v8::Value>* args) {
+  int exit_code = (*args)[0]->Int32Value();
 #ifndef V8_SHARED
   CleanupWorkers();
 #endif  // !V8_SHARED
-  OnExit(args.GetIsolate());
+  OnExit(args->GetIsolate());
   exit(exit_code);
 }
 
 
+void Shell::Quit(const v8::FunctionCallbackInfo<v8::Value>& args) {
+  base::CallOnce(&quit_once_, &QuitOnce,
+                 const_cast<v8::FunctionCallbackInfo<v8::Value>*>(&args));
+}
+
+
 void Shell::Version(const v8::FunctionCallbackInfo<v8::Value>& args) {
   args.GetReturnValue().Set(
       String::NewFromUtf8(args.GetIsolate(), V8::GetVersion()));
index 6c632c9..f126dd2 100644 (file)
--- a/src/d8.h
+++ b/src/d8.h
@@ -15,6 +15,9 @@
 #include "src/base/compiler-specific.h"
 #endif  // !V8_SHARED
 
+#include "src/base/once.h"
+
+
 namespace v8 {
 
 
@@ -411,6 +414,7 @@ class Shell : public i::AllStatic {
 
   static void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
   static void Write(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void QuitOnce(v8::FunctionCallbackInfo<v8::Value>* args);
   static void Quit(const v8::FunctionCallbackInfo<v8::Value>& args);
   static void Version(const v8::FunctionCallbackInfo<v8::Value>& args);
   static void Read(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -468,6 +472,7 @@ class Shell : public i::AllStatic {
 
  private:
   static Persistent<Context> evaluation_context_;
+  static base::OnceType quit_once_;
 #ifndef V8_SHARED
   static Persistent<Context> utility_context_;
   static CounterMap* counter_map_;
index 864cd3e..0b25f4c 100644 (file)
   # BUG(chromium:508074). Remove this once the issue is fixed.
   'harmony/arrow-rest-params': [PASS, NO_VARIANTS],
   'harmony/rest-params': [PASS, ['no_snap == True', NO_VARIANTS]],
-
-  # BUG(v8:4279).
-  'regress/regress-4279': [PASS, ['isolates', SKIP]],
 }],  # ALWAYS
 
 ['novfp3 == True', {