Bug 951542 - PJS: Fix race between interrupt check and main thread finishing. (r=nmatsakis)

This commit is contained in:
Shu-yu Guo 2014-01-10 02:25:34 -08:00
parent d1e62d2d8a
commit db50f09e1c
3 changed files with 19 additions and 2 deletions

View File

@ -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) {

View File

@ -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.

View File

@ -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_; }