Bug 919638 - Followup: unbreak compiling without NSPR. (r=pnkfelix)

This commit is contained in:
Shu-yu Guo 2014-01-10 17:12:17 -08:00
parent 8da7a3e86b
commit 46d12098d4
3 changed files with 46 additions and 32 deletions

View File

@ -33,9 +33,8 @@ class Monitor
PRLock *lock_;
PRCondVar *condVar_;
void assertIsHoldingLock() const {
PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(lock_);
bool isFor(Monitor &monitor) const {
return lock_ == monitor.lock_;
}
public:
@ -80,23 +79,43 @@ class AutoLockMonitor
#endif
}
void wait() {
void wait(PRCondVar *condVar) {
#ifdef JS_THREADSAFE
mozilla::DebugOnly<PRStatus> status =
PR_WaitCondVar(monitor.condVar_, PR_INTERVAL_NO_TIMEOUT);
JS_ASSERT(status == PR_SUCCESS);
PR_WaitCondVar(condVar, PR_INTERVAL_NO_TIMEOUT);
MOZ_ASSERT(status == PR_SUCCESS);
#endif
}
void wait() {
#ifdef JS_THREADSAFE
wait(monitor.condVar_);
#endif
}
void notify(PRCondVar *condVar) {
#ifdef JS_THREADSAFE
mozilla::DebugOnly<PRStatus> status = PR_NotifyCondVar(condVar);
MOZ_ASSERT(status == PR_SUCCESS);
#endif
}
void notify() {
#ifdef JS_THREADSAFE
PR_NotifyCondVar(monitor.condVar_);
notify(monitor.condVar_);
#endif
}
void notifyAll(PRCondVar *condVar) {
#ifdef JS_THREADSAFE
mozilla::DebugOnly<PRStatus> status = PR_NotifyAllCondVar(monitor.condVar_);
MOZ_ASSERT(status == PR_SUCCESS);
#endif
}
void notifyAll() {
#ifdef JS_THREADSAFE
PR_NotifyAllCondVar(monitor.condVar_);
notifyAll(monitor.condVar_);
#endif
}
};

View File

@ -112,7 +112,7 @@ class js::ThreadPoolWorker : public ThreadPoolBaseWorker
bool start();
// Invoked from main thread; signals the worker loop to return.
void terminate();
void terminate(AutoLockMonitor &lock);
};
// ThreadPoolMainWorker
@ -280,7 +280,7 @@ ThreadPoolWorker::run()
lock.wait();
if (state_ == TERMINATED) {
pool_->join();
pool_->join(lock);
return;
}
@ -299,16 +299,16 @@ ThreadPoolWorker::run()
// Join the pool.
{
AutoLockMonitor lock(*pool_);
pool_->join();
pool_->join(lock);
}
}
}
void
ThreadPoolWorker::terminate()
ThreadPoolWorker::terminate(AutoLockMonitor &lock)
{
MOZ_ASSERT(lock.isFor(*this));
MOZ_ASSERT(state_ != TERMINATED);
pool_->assertIsHoldingLock();
state_ = TERMINATED;
}
@ -369,8 +369,10 @@ ThreadPool::ThreadPool(JSRuntime *rt)
ThreadPool::~ThreadPool()
{
terminateWorkers();
#ifdef JS_THREADSAFE
if (joinBarrier_)
PR_DestroyCondVar(joinBarrier_);
#endif
}
bool
@ -467,7 +469,7 @@ ThreadPool::terminateWorkers()
// Signal to the workers they should quit.
for (uint32_t i = 0; i < workers_.length(); i++)
workers_[i]->terminate();
workers_[i]->terminate(lock);
// Wake up all the workers. Set the number of active workers to the
// current number of workers so we can make sure they all join.
@ -475,7 +477,7 @@ ThreadPool::terminateWorkers()
lock.notifyAll();
// Wait for all workers to join.
waitForWorkers();
waitForWorkers(lock);
while (workers_.length() > 0)
js_delete(workers_.popCopy());
@ -491,27 +493,20 @@ ThreadPool::terminate()
}
void
ThreadPool::join()
ThreadPool::join(AutoLockMonitor &lock)
{
#ifdef JS_THREADSAFE
assertIsHoldingLock();
MOZ_ASSERT(lock.isFor(*this));
if (--activeWorkers_ == 0)
PR_NotifyCondVar(joinBarrier_);
#endif
lock.notify(joinBarrier_);
}
void
ThreadPool::waitForWorkers()
ThreadPool::waitForWorkers(AutoLockMonitor &lock)
{
#ifdef JS_THREADSAFE
assertIsHoldingLock();
while (activeWorkers_ > 0) {
mozilla::DebugOnly<PRStatus> status =
PR_WaitCondVar(joinBarrier_, PR_INTERVAL_NO_TIMEOUT);
MOZ_ASSERT(status == PR_SUCCESS);
}
MOZ_ASSERT(lock.isFor(*this));
while (activeWorkers_ > 0)
lock.wait(joinBarrier_);
job_ = nullptr;
#endif
}
ParallelResult
@ -571,7 +566,7 @@ ThreadPool::executeJob(JSContext *cx, ParallelJob *job, uint16_t numSlices)
// point, the slices themselves may not be finished processing.
{
AutoLockMonitor lock(*this);
waitForWorkers();
waitForWorkers(lock);
}
// Everything went swimmingly. Give yourself a pat on the back.

View File

@ -108,8 +108,8 @@ class ThreadPool : public Monitor
bool lazyStartWorkers(JSContext *cx);
void terminateWorkers();
void terminateWorkersAndReportOOM(JSContext *cx);
void join();
void waitForWorkers();
void join(AutoLockMonitor &lock);
void waitForWorkers(AutoLockMonitor &lock);
public:
ThreadPool(JSRuntime *rt);