diff --git a/js/src/vm/ForkJoin.cpp b/js/src/vm/ForkJoin.cpp index d5ac9ef6539..2e354176ec8 100644 --- a/js/src/vm/ForkJoin.cpp +++ b/js/src/vm/ForkJoin.cpp @@ -1505,7 +1505,10 @@ ForkJoinShared::check(ForkJoinSlice &slice) if (abort_) return false; - if (slice.isMainThread()) { + // Note: We must check if the main thread has exited successfully here, as + // without a main thread the worker threads which are tripping on the + // interrupt flag would never exit. + if (slice.isMainThread() || !threadPool_->isMainThreadActive()) { JS_ASSERT(!cx_->runtime()->gcIsNeeded); if (cx_->runtime()->interrupt) { diff --git a/js/src/vm/ThreadPool.cpp b/js/src/vm/ThreadPool.cpp index 440ba7e0ba7..51f17eeb878 100644 --- a/js/src/vm/ThreadPool.cpp +++ b/js/src/vm/ThreadPool.cpp @@ -128,8 +128,11 @@ class js::ThreadPoolMainWorker : public ThreadPoolBaseWorker bool getSlice(uint16_t *sliceId); public: + bool isActive; + ThreadPoolMainWorker(ThreadPool *pool) - : ThreadPoolBaseWorker(0, pool) + : ThreadPoolBaseWorker(0, pool), + isActive(false) { } // Execute a job on the main thread. @@ -401,6 +404,12 @@ ThreadPool::workStealing() const return true; } +bool +ThreadPool::isMainThreadActive() const +{ + return mainWorker_ && mainWorker_->isActive; +} + bool ThreadPool::lazyStartWorkers(JSContext *cx) { @@ -554,7 +563,9 @@ ThreadPool::executeJob(JSContext *cx, ParallelJob *job, uint16_t numSlices) } // Do work on the main thread. + mainWorker_->isActive = true; mainWorker_->executeJob(); + mainWorker_->isActive = false; // Wait for all threads to join. While there are no pending slices at this // point, the slices themselves may not be finished processing. diff --git a/js/src/vm/ThreadPool.h b/js/src/vm/ThreadPool.h index da798bc657d..563fb518c3e 100644 --- a/js/src/vm/ThreadPool.h +++ b/js/src/vm/ThreadPool.h @@ -132,6 +132,9 @@ class ThreadPool : public Monitor // Returns whether or not the scheduler should perform work stealing. bool workStealing() const; + // Returns whether or not the main thread is working. + bool isMainThreadActive() const; + #ifdef DEBUG // Return the number of stolen slices in the last parallel job. uint16_t stolenSlices() { return stolenSlices_; }