From 76184292b392d107609f21662a949b58bb1e258c Mon Sep 17 00:00:00 2001 From: binji Date: Tue, 14 Jul 2015 10:42:03 -0700 Subject: [PATCH] d8 workers: make sure Shell::Quit is only called once 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 | 13 ++++++++++--- src/d8.h | 5 +++++ test/mjsunit/mjsunit.status | 3 --- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/d8.cc b/src/d8.cc index 2b1832a..d882e45 100644 --- a/src/d8.cc +++ b/src/d8.cc @@ -216,6 +216,7 @@ Persistent 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& args) { #endif // !V8_SHARED -void Shell::Quit(const v8::FunctionCallbackInfo& args) { - int exit_code = args[0]->Int32Value(); +void Shell::QuitOnce(v8::FunctionCallbackInfo* 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& args) { + base::CallOnce(&quit_once_, &QuitOnce, + const_cast*>(&args)); +} + + void Shell::Version(const v8::FunctionCallbackInfo& args) { args.GetReturnValue().Set( String::NewFromUtf8(args.GetIsolate(), V8::GetVersion())); diff --git a/src/d8.h b/src/d8.h index 6c632c9..f126dd2 100644 --- 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& args); static void Write(const v8::FunctionCallbackInfo& args); + static void QuitOnce(v8::FunctionCallbackInfo* args); static void Quit(const v8::FunctionCallbackInfo& args); static void Version(const v8::FunctionCallbackInfo& args); static void Read(const v8::FunctionCallbackInfo& args); @@ -468,6 +472,7 @@ class Shell : public i::AllStatic { private: static Persistent evaluation_context_; + static base::OnceType quit_once_; #ifndef V8_SHARED static Persistent utility_context_; static CounterMap* counter_map_; diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status index 864cd3e..0b25f4c 100644 --- a/test/mjsunit/mjsunit.status +++ b/test/mjsunit/mjsunit.status @@ -248,9 +248,6 @@ # 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', { -- 2.7.4