summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authormichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-30 22:33:46 +0000
committermichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-30 22:33:46 +0000
commitf6f074d0afc477add1bf6ec36b9848df747d175c (patch)
treedd7a629564259f2bf7223edf27b19c7827544ba8 /base
parentda99b4e1d68bca6c208614ca9be23e47bd082eda (diff)
downloadchromium_src-f6f074d0afc477add1bf6ec36b9848df747d175c.zip
chromium_src-f6f074d0afc477add1bf6ec36b9848df747d175c.tar.gz
chromium_src-f6f074d0afc477add1bf6ec36b9848df747d175c.tar.bz2
Add SequencedWorkerPool.IsRunningSequenceOnCurrentThread so callers can make stronger assertions about where methods are being called.
Review URL: https://chromiumcodereview.appspot.com/9845037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@129979 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/threading/sequenced_worker_pool.cc30
-rw-r--r--base/threading/sequenced_worker_pool.h4
-rw-r--r--base/threading/sequenced_worker_pool_unittest.cc52
3 files changed, 86 insertions, 0 deletions
diff --git a/base/threading/sequenced_worker_pool.cc b/base/threading/sequenced_worker_pool.cc
index be8f463..7054fba 100644
--- a/base/threading/sequenced_worker_pool.cc
+++ b/base/threading/sequenced_worker_pool.cc
@@ -63,8 +63,17 @@ class SequencedWorkerPool::Worker : public SimpleThread {
// SimpleThread implementation. This actually runs the background thread.
virtual void Run() OVERRIDE;
+ void set_running_sequence(SequenceToken token) {
+ running_sequence_ = token;
+ }
+
+ SequenceToken running_sequence() const {
+ return running_sequence_;
+ }
+
private:
scoped_refptr<SequencedWorkerPool> worker_pool_;
+ SequenceToken running_sequence_;
DISALLOW_COPY_AND_ASSIGN(Worker);
};
@@ -96,6 +105,8 @@ class SequencedWorkerPool::Inner {
bool RunsTasksOnCurrentThread() const;
+ bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const;
+
void FlushForTesting();
void SignalHasWorkForTesting();
@@ -354,6 +365,15 @@ bool SequencedWorkerPool::Inner::RunsTasksOnCurrentThread() const {
return ContainsKey(threads_, PlatformThread::CurrentId());
}
+bool SequencedWorkerPool::Inner::IsRunningSequenceOnCurrentThread(
+ SequenceToken sequence_token) const {
+ AutoLock lock(lock_);
+ ThreadMap::const_iterator found = threads_.find(PlatformThread::CurrentId());
+ if (found == threads_.end())
+ return false;
+ return found->second->running_sequence().Equals(sequence_token);
+}
+
void SequencedWorkerPool::Inner::FlushForTesting() {
AutoLock lock(lock_);
while (!IsIdle())
@@ -435,8 +455,13 @@ void SequencedWorkerPool::Inner::ThreadLoop(Worker* this_worker) {
if (new_thread_id)
FinishStartingAdditionalThread(new_thread_id);
+ this_worker->set_running_sequence(
+ SequenceToken(task.sequence_token_id));
+
task.task.Run();
+ this_worker->set_running_sequence(SequenceToken());
+
// Make sure our task is erased outside the lock for the same reason
// we do this with delete_these_oustide_lock.
task.task = Closure();
@@ -796,6 +821,11 @@ bool SequencedWorkerPool::RunsTasksOnCurrentThread() const {
return inner_->RunsTasksOnCurrentThread();
}
+bool SequencedWorkerPool::IsRunningSequenceOnCurrentThread(
+ SequenceToken sequence_token) const {
+ return inner_->IsRunningSequenceOnCurrentThread(sequence_token);
+}
+
void SequencedWorkerPool::FlushForTesting() {
inner_->FlushForTesting();
}
diff --git a/base/threading/sequenced_worker_pool.h b/base/threading/sequenced_worker_pool.h
index 83d677a..99d7bb9 100644
--- a/base/threading/sequenced_worker_pool.h
+++ b/base/threading/sequenced_worker_pool.h
@@ -219,6 +219,10 @@ class BASE_EXPORT SequencedWorkerPool : public TaskRunner {
TimeDelta delay) OVERRIDE;
virtual bool RunsTasksOnCurrentThread() const OVERRIDE;
+ // Returns true if the current thread is processing a task with the given
+ // sequence_token.
+ bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const;
+
// Blocks until all pending tasks are complete. This should only be called in
// unit tests when you want to validate something that should have happened.
//
diff --git a/base/threading/sequenced_worker_pool_unittest.cc b/base/threading/sequenced_worker_pool_unittest.cc
index e44599f..8a3508d 100644
--- a/base/threading/sequenced_worker_pool_unittest.cc
+++ b/base/threading/sequenced_worker_pool_unittest.cc
@@ -510,6 +510,58 @@ TEST_F(SequencedWorkerPoolTest, SpuriousWorkSignal) {
EXPECT_EQ(old_has_work_call_count + 1, has_work_call_count());
}
+void IsRunningOnCurrentThreadTask(
+ SequencedWorkerPool::SequenceToken test_positive_token,
+ SequencedWorkerPool::SequenceToken test_negative_token,
+ SequencedWorkerPool* pool,
+ SequencedWorkerPool* unused_pool) {
+ EXPECT_TRUE(pool->RunsTasksOnCurrentThread());
+ EXPECT_TRUE(pool->IsRunningSequenceOnCurrentThread(test_positive_token));
+ EXPECT_FALSE(pool->IsRunningSequenceOnCurrentThread(test_negative_token));
+ EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread());
+ EXPECT_FALSE(
+ unused_pool->IsRunningSequenceOnCurrentThread(test_positive_token));
+ EXPECT_FALSE(
+ unused_pool->IsRunningSequenceOnCurrentThread(test_negative_token));
+}
+
+// Verify correctness of the IsRunningSequenceOnCurrentThread method.
+TEST_F(SequencedWorkerPoolTest, IsRunningOnCurrentThread) {
+ SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken();
+ SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken();
+ SequencedWorkerPool::SequenceToken unsequenced_token;
+
+ scoped_refptr<SequencedWorkerPool> unused_pool =
+ new SequencedWorkerPool(2, "unused_pool");
+ EXPECT_TRUE(token1.Equals(unused_pool->GetSequenceToken()));
+ EXPECT_TRUE(token2.Equals(unused_pool->GetSequenceToken()));
+
+ EXPECT_FALSE(pool()->RunsTasksOnCurrentThread());
+ EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(token1));
+ EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(token2));
+ EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(unsequenced_token));
+ EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread());
+ EXPECT_FALSE(unused_pool->IsRunningSequenceOnCurrentThread(token1));
+ EXPECT_FALSE(unused_pool->IsRunningSequenceOnCurrentThread(token2));
+ EXPECT_FALSE(
+ unused_pool->IsRunningSequenceOnCurrentThread(unsequenced_token));
+
+ pool()->PostSequencedWorkerTask(
+ token1, FROM_HERE,
+ base::Bind(&IsRunningOnCurrentThreadTask,
+ token1, token2, pool(), unused_pool));
+ pool()->PostSequencedWorkerTask(
+ token2, FROM_HERE,
+ base::Bind(&IsRunningOnCurrentThreadTask,
+ token2, unsequenced_token, pool(), unused_pool));
+ pool()->PostWorkerTask(
+ FROM_HERE,
+ base::Bind(&IsRunningOnCurrentThreadTask,
+ unsequenced_token, token1, pool(), unused_pool));
+ pool()->Shutdown();
+ unused_pool->Shutdown();
+}
+
class SequencedWorkerPoolTaskRunnerTestDelegate {
public:
SequencedWorkerPoolTaskRunnerTestDelegate() {}