Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(451)

Unified Diff: src/utils/SkThreadPool.cpp

Issue 26389005: SkThreadPool: allow for Runnables that add other Runnables to the pool. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/utils/SkThreadPool.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/utils/SkThreadPool.cpp
diff --git a/src/utils/SkThreadPool.cpp b/src/utils/SkThreadPool.cpp
index e078af3ba3e914add1428460b66c24f6dafe9bb6..125a5d9b6ad78674e057af791b8859e7159bd36e 100644
--- a/src/utils/SkThreadPool.cpp
+++ b/src/utils/SkThreadPool.cpp
@@ -28,7 +28,7 @@ static int num_cores() {
}
SkThreadPool::SkThreadPool(int count)
-: fDone(false) {
+: fState(kRunning_State), fBusyThreads(0) {
if (count < 0) count = num_cores();
// Create count threads, all running SkThreadPool::Loop.
for (int i = 0; i < count; i++) {
@@ -39,14 +39,14 @@ SkThreadPool::SkThreadPool(int count)
}
SkThreadPool::~SkThreadPool() {
- if (!fDone) {
+ if (kRunning_State == fState) {
this->wait();
}
}
void SkThreadPool::wait() {
fReady.lock();
- fDone = true;
+ fState = kWaiting_State;
fReady.broadcast();
fReady.unlock();
@@ -55,6 +55,7 @@ void SkThreadPool::wait() {
fThreads[i]->join();
SkDELETE(fThreads[i]);
}
+ SkASSERT(fQueue.isEmpty());
}
/*static*/ void SkThreadPool::Loop(void* arg) {
@@ -65,8 +66,14 @@ void SkThreadPool::wait() {
// We have to be holding the lock to read the queue and to call wait.
pool->fReady.lock();
while(pool->fQueue.isEmpty()) {
- // Is it time to die?
- if (pool->fDone) {
+ // Does the client want to stop and are all the threads ready to stop?
+ // If so, we move into the halting state, and whack all the threads so they notice.
+ if (kWaiting_State == pool->fState && pool->fBusyThreads == 0) {
+ pool->fState = kHalting_State;
+ pool->fReady.broadcast();
+ }
+ // Any time we find ourselves in the halting state, it's quitting time.
+ if (kHalting_State == pool->fState) {
pool->fReady.unlock();
return;
}
@@ -83,14 +90,20 @@ void SkThreadPool::wait() {
// Having claimed our SkRunnable, we now give up the lock while we run it.
// Otherwise, we'd only ever do work on one thread at a time, which rather
// defeats the point of this code.
+ pool->fBusyThreads++;
pool->fReady.unlock();
// OK, now really do the work.
r->fRunnable->run();
SkDELETE(r);
+
+ // Let everyone know we're not busy.
+ pool->fReady.lock();
+ pool->fBusyThreads--;
+ pool->fReady.unlock();
}
- SkASSERT(false); // Unreachable. The only exit happens when pool->fDone.
+ SkASSERT(false); // Unreachable. The only exit happens when pool->fState is kHalting_State.
}
void SkThreadPool::add(SkRunnable* r) {
@@ -105,7 +118,7 @@ void SkThreadPool::add(SkRunnable* r) {
// We have some threads. Queue it up!
fReady.lock();
- SkASSERT(!fDone); // We shouldn't be adding work to a pool that's shut down.
+ SkASSERT(fState != kHalting_State); // Shouldn't be able to add work when we're halting.
LinkedRunnable* linkedRunnable = SkNEW(LinkedRunnable);
linkedRunnable->fRunnable = r;
fQueue.addToHead(linkedRunnable);
« no previous file with comments | « include/utils/SkThreadPool.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698