d8: Leak context_mutex_ so it will never be destroyed while locked
Calling quit() from d8 will call exit(), which will run static destructors. If context_mutex_ is statically allocated, pthread_mutex_destroy will be called. When running d8 in "isolates" mode, another thread may be running. If it calls CreateEvaluationContext, it will lock the context_mutex_. If the mutex is destroyed while it is locked, it will return an error. This CL changes the Mutex to a LazyMutex, which will leak instead of being destroyed. BUG=v8:4279 R=jarin@chromium.org R=machenbach@chromium.org LOG=n Review URL: https://codereview.chromium.org/1240553003 Cr-Commit-Position: refs/heads/master@{#29709}
This commit is contained in:
parent
1251d02e7b
commit
162f116a91
12
src/d8.cc
12
src/d8.cc
@ -202,11 +202,11 @@ CounterMap* Shell::counter_map_;
|
|||||||
base::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
|
base::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
|
||||||
CounterCollection Shell::local_counters_;
|
CounterCollection Shell::local_counters_;
|
||||||
CounterCollection* Shell::counters_ = &local_counters_;
|
CounterCollection* Shell::counters_ = &local_counters_;
|
||||||
base::Mutex Shell::context_mutex_;
|
base::LazyMutex Shell::context_mutex_;
|
||||||
const base::TimeTicks Shell::kInitialTicks =
|
const base::TimeTicks Shell::kInitialTicks =
|
||||||
base::TimeTicks::HighResolutionNow();
|
base::TimeTicks::HighResolutionNow();
|
||||||
Persistent<Context> Shell::utility_context_;
|
Persistent<Context> Shell::utility_context_;
|
||||||
base::Mutex Shell::workers_mutex_;
|
base::LazyMutex Shell::workers_mutex_;
|
||||||
bool Shell::allow_new_workers_ = true;
|
bool Shell::allow_new_workers_ = true;
|
||||||
i::List<Worker*> Shell::workers_;
|
i::List<Worker*> Shell::workers_;
|
||||||
i::List<SharedArrayBuffer::Contents> Shell::externalized_shared_contents_;
|
i::List<SharedArrayBuffer::Contents> Shell::externalized_shared_contents_;
|
||||||
@ -699,7 +699,7 @@ void Shell::WorkerNew(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
base::LockGuard<base::Mutex> lock_guard(&workers_mutex_);
|
base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer());
|
||||||
if (!allow_new_workers_) return;
|
if (!allow_new_workers_) return;
|
||||||
|
|
||||||
Worker* worker = new Worker;
|
Worker* worker = new Worker;
|
||||||
@ -1203,7 +1203,7 @@ void Shell::InitializeDebugger(Isolate* isolate) {
|
|||||||
Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
|
Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
|
||||||
#ifndef V8_SHARED
|
#ifndef V8_SHARED
|
||||||
// This needs to be a critical section since this is not thread-safe
|
// This needs to be a critical section since this is not thread-safe
|
||||||
base::LockGuard<base::Mutex> lock_guard(&context_mutex_);
|
base::LockGuard<base::Mutex> lock_guard(context_mutex_.Pointer());
|
||||||
#endif // !V8_SHARED
|
#endif // !V8_SHARED
|
||||||
// Initialize the global objects
|
// Initialize the global objects
|
||||||
Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
|
Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
|
||||||
@ -2252,7 +2252,7 @@ void Shell::CleanupWorkers() {
|
|||||||
// create a new Worker, it would deadlock.
|
// create a new Worker, it would deadlock.
|
||||||
i::List<Worker*> workers_copy;
|
i::List<Worker*> workers_copy;
|
||||||
{
|
{
|
||||||
base::LockGuard<base::Mutex> lock_guard(&workers_mutex_);
|
base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer());
|
||||||
allow_new_workers_ = false;
|
allow_new_workers_ = false;
|
||||||
workers_copy.AddAll(workers_);
|
workers_copy.AddAll(workers_);
|
||||||
workers_.Clear();
|
workers_.Clear();
|
||||||
@ -2266,7 +2266,7 @@ void Shell::CleanupWorkers() {
|
|||||||
|
|
||||||
// Now that all workers are terminated, we can re-enable Worker creation.
|
// Now that all workers are terminated, we can re-enable Worker creation.
|
||||||
{
|
{
|
||||||
base::LockGuard<base::Mutex> lock_guard(&workers_mutex_);
|
base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer());
|
||||||
allow_new_workers_ = true;
|
allow_new_workers_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
src/d8.h
4
src/d8.h
@ -481,10 +481,10 @@ class Shell : public i::AllStatic {
|
|||||||
static CounterCollection local_counters_;
|
static CounterCollection local_counters_;
|
||||||
static CounterCollection* counters_;
|
static CounterCollection* counters_;
|
||||||
static base::OS::MemoryMappedFile* counters_file_;
|
static base::OS::MemoryMappedFile* counters_file_;
|
||||||
static base::Mutex context_mutex_;
|
static base::LazyMutex context_mutex_;
|
||||||
static const base::TimeTicks kInitialTicks;
|
static const base::TimeTicks kInitialTicks;
|
||||||
|
|
||||||
static base::Mutex workers_mutex_;
|
static base::LazyMutex workers_mutex_;
|
||||||
static bool allow_new_workers_;
|
static bool allow_new_workers_;
|
||||||
static i::List<Worker*> workers_;
|
static i::List<Worker*> workers_;
|
||||||
static i::List<SharedArrayBuffer::Contents> externalized_shared_contents_;
|
static i::List<SharedArrayBuffer::Contents> externalized_shared_contents_;
|
||||||
|
Loading…
Reference in New Issue
Block a user