summaryrefslogtreecommitdiffstats
path: root/cc/raster_worker_pool.cc
diff options
context:
space:
mode:
authorreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-29 12:31:48 +0000
committerreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-29 12:31:48 +0000
commit1471e7c35209d1ee00a5ffaa3ebd9bfff626589d (patch)
tree87e73bbab8726993e9dc15c401db640559c0d7ad /cc/raster_worker_pool.cc
parentc90c1fcdccefb22f50dc3b8a04e2786f6c507c8d (diff)
downloadchromium_src-1471e7c35209d1ee00a5ffaa3ebd9bfff626589d.zip
chromium_src-1471e7c35209d1ee00a5ffaa3ebd9bfff626589d.tar.gz
chromium_src-1471e7c35209d1ee00a5ffaa3ebd9bfff626589d.tar.bz2
cc: Fix RasterWorkerPool shutdown crash.
Avoid calling sort on the raster thread vector while deleting its elements. This also adds a "IsRunning" state that is used to check that that the worker pool is not used incorrectly during shutdown. BUG=172059 R=nduca@chromium.org NOTRY=true Review URL: https://chromiumcodereview.appspot.com/12079028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@179321 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/raster_worker_pool.cc')
-rw-r--r--cc/raster_worker_pool.cc52
1 files changed, 46 insertions, 6 deletions
diff --git a/cc/raster_worker_pool.cc b/cc/raster_worker_pool.cc
index cc10956..8eb92c2 100644
--- a/cc/raster_worker_pool.cc
+++ b/cc/raster_worker_pool.cc
@@ -75,11 +75,11 @@ RasterWorkerPool::Thread::Task::~Task() {
RasterWorkerPool::Thread::Thread(const std::string name)
: base::Thread(name.c_str()),
num_pending_tasks_(0) {
- Start();
}
RasterWorkerPool::Thread::~Thread() {
Stop();
+ DCHECK_EQ(num_pending_tasks_, 0);
}
void RasterWorkerPool::Thread::Init() {
@@ -90,7 +90,9 @@ void RasterWorkerPool::Thread::Init() {
#endif
}
-RasterWorkerPool::RasterWorkerPool(size_t num_raster_threads) {
+RasterWorkerPool::RasterWorkerPool(size_t num_raster_threads)
+ : is_running_(false),
+ raster_threads_need_sorting_(false) {
const std::string thread_name_prefix = kRasterThreadNamePrefix;
while (raster_threads_.size() < num_raster_threads) {
int thread_number = raster_threads_.size() + 1;
@@ -101,10 +103,39 @@ RasterWorkerPool::RasterWorkerPool(size_t num_raster_threads) {
}
RasterWorkerPool::~RasterWorkerPool() {
+ Stop();
STLDeleteElements(&raster_threads_);
}
+bool RasterWorkerPool::Start() {
+ for (ThreadVector::iterator it = raster_threads_.begin();
+ it != raster_threads_.end(); it++) {
+ Thread* thread = *it;
+ if (!thread->Start())
+ return false;
+ }
+
+ is_running_ = true;
+ return true;
+}
+
+void RasterWorkerPool::Stop() {
+ if (!is_running_)
+ return;
+
+ for (ThreadVector::iterator it = raster_threads_.begin();
+ it != raster_threads_.end(); it++) {
+ Thread* thread = *it;
+ thread->Stop();
+ }
+
+ is_running_ = false;
+}
+
bool RasterWorkerPool::IsBusy() {
+ DCHECK(is_running_);
+ SortRasterThreadsIfNeeded();
+
Thread* thread = raster_threads_.front();
return thread->num_pending_tasks() >= kNumPendingRasterTasksPerThread;
}
@@ -114,6 +145,7 @@ void RasterWorkerPool::PostRasterTaskAndReply(PicturePileImpl* picture_pile,
const gfx::Rect& rect,
float contents_scale,
const base::Closure& reply) {
+ CHECK(is_running_);
Thread::Task* task = CreateTask();
scoped_refptr<PicturePileImpl> picture_pile_clone =
@@ -137,6 +169,7 @@ void RasterWorkerPool::PostRasterTaskAndReply(PicturePileImpl* picture_pile,
void RasterWorkerPool::PostImageDecodeTaskAndReply(
skia::LazyPixelRef* pixel_ref,
const base::Closure& reply) {
+ CHECK(is_running_);
Thread::Task* task = CreateTask();
task->thread_->message_loop_proxy()->PostTaskAndReply(
@@ -172,15 +205,13 @@ RasterWorkerPool::Thread::Task* RasterWorkerPool::CreateTask() {
DCHECK(thread->num_pending_tasks() < kNumPendingRasterTasksPerThread);
scoped_ptr<Thread::Task> task(new Thread::Task(thread));
- std::sort(raster_threads_.begin(), raster_threads_.end(),
- PendingTaskComparator());
+ raster_threads_need_sorting_ = true;
return task.release();
}
void RasterWorkerPool::DestroyTask(Thread::Task* task) {
delete task;
- std::sort(raster_threads_.begin(), raster_threads_.end(),
- PendingTaskComparator());
+ raster_threads_need_sorting_ = true;
}
void RasterWorkerPool::OnTaskCompleted(
@@ -196,4 +227,13 @@ void RasterWorkerPool::OnRasterTaskCompleted(
OnTaskCompleted(task, reply);
}
+void RasterWorkerPool::SortRasterThreadsIfNeeded() {
+ if (!raster_threads_need_sorting_)
+ return;
+
+ std::sort(raster_threads_.begin(), raster_threads_.end(),
+ PendingTaskComparator());
+ raster_threads_need_sorting_ = false;
+}
+
} // namespace cc