Index: runtime/vm/thread_pool_test.cc |
diff --git a/runtime/vm/thread_pool_test.cc b/runtime/vm/thread_pool_test.cc |
index 35a61273736c8e80c45f957263f596c289421dcd..14c934011bda77d41b27bf1e79b9525c12d85006 100644 |
--- a/runtime/vm/thread_pool_test.cc |
+++ b/runtime/vm/thread_pool_test.cc |
@@ -11,24 +11,6 @@ namespace dart { |
DECLARE_FLAG(int, worker_timeout_millis); |
- |
-class ThreadPoolTestPeer { |
- public: |
- // When the pool has an exit monitor, workers notify a monitor just |
- // before they exit. This is only used in tests to make sure that |
- // Shutdown works. |
- static void SetExitMonitor(Monitor* exit_monitor, int* exit_count) { |
- ThreadPool::exit_monitor_ = exit_monitor; |
- ThreadPool::exit_count_ = exit_count; |
- } |
-}; |
- |
- |
-UNIT_TEST_CASE(ThreadPool_Create) { |
- ThreadPool thread_pool; |
-} |
- |
- |
class TestTask : public ThreadPool::Task { |
public: |
TestTask(Monitor* sync, bool* done) |
@@ -48,10 +30,10 @@ class TestTask : public ThreadPool::Task { |
UNIT_TEST_CASE(ThreadPool_RunOne) { |
- ThreadPool thread_pool; |
+ ThreadPool::set_shutdown_timeout_fatal(false); |
Monitor sync; |
bool done = false; |
- thread_pool.Run(new TestTask(&sync, &done)); |
+ ThreadPool::Run(new TestTask(&sync, &done)); |
{ |
MonitorLocker ml(&sync); |
while (!done) { |
@@ -61,20 +43,21 @@ UNIT_TEST_CASE(ThreadPool_RunOne) { |
EXPECT(done); |
// Do a sanity test on the worker stats. |
- EXPECT_EQ(1U, thread_pool.workers_started()); |
- EXPECT_EQ(0U, thread_pool.workers_stopped()); |
+ EXPECT_LE(1U, ThreadPool::workers_started()); |
+ EXPECT_EQ(0U, ThreadPool::workers_stopped()); |
+ EXPECT(ThreadPool::Shutdown()); |
} |
UNIT_TEST_CASE(ThreadPool_RunMany) { |
+ ThreadPool::set_shutdown_timeout_fatal(false); |
const int kTaskCount = 100; |
- ThreadPool thread_pool; |
Monitor sync[kTaskCount]; |
bool done[kTaskCount]; |
for (int i = 0; i < kTaskCount; i++) { |
done[i] = false; |
- thread_pool.Run(new TestTask(&sync[i], &done[i])); |
+ ThreadPool::Run(new TestTask(&sync[i], &done[i])); |
} |
for (int i = 0; i < kTaskCount; i++) { |
MonitorLocker ml(&sync[i]); |
@@ -83,45 +66,7 @@ UNIT_TEST_CASE(ThreadPool_RunMany) { |
} |
EXPECT(done[i]); |
} |
-} |
- |
- |
-class SleepTask : public ThreadPool::Task { |
- public: |
- explicit SleepTask(int millis) |
- : millis_(millis) { |
- } |
- |
- virtual void Run() { |
- OS::Sleep(millis_); |
- } |
- |
- private: |
- int millis_; |
-}; |
- |
- |
-UNIT_TEST_CASE(ThreadPool_WorkerShutdown) { |
- Monitor exit_sync; |
- int exit_count = 0; |
- MonitorLocker ml(&exit_sync); |
- |
- // Set up the ThreadPool so that workers notify before they exit. |
- ThreadPool* thread_pool = new ThreadPool(); |
- ThreadPoolTestPeer::SetExitMonitor(&exit_sync, &exit_count); |
- |
- // Run a single task. |
- thread_pool->Run(new SleepTask(2)); |
- |
- // Kill the thread pool. |
- delete thread_pool; |
- thread_pool = NULL; |
- |
- // Wait for the workers to terminate. |
- while (exit_count == 0) { |
- ml.Wait(); |
- } |
- EXPECT_EQ(1, exit_count); |
+ EXPECT(ThreadPool::Shutdown()); |
} |
@@ -130,16 +75,16 @@ UNIT_TEST_CASE(ThreadPool_WorkerTimeout) { |
int saved_timeout = FLAG_worker_timeout_millis; |
FLAG_worker_timeout_millis = 1; |
- ThreadPool thread_pool; |
- EXPECT_EQ(0U, thread_pool.workers_started()); |
- EXPECT_EQ(0U, thread_pool.workers_stopped()); |
+ ThreadPool::set_shutdown_timeout_fatal(false); |
+ EXPECT_LE(0U, ThreadPool::workers_started()); |
+ EXPECT_EQ(0U, ThreadPool::workers_stopped()); |
// Run a worker. |
Monitor sync; |
bool done = false; |
- thread_pool.Run(new TestTask(&sync, &done)); |
- EXPECT_EQ(1U, thread_pool.workers_started()); |
- EXPECT_EQ(0U, thread_pool.workers_stopped()); |
+ ThreadPool::Run(new TestTask(&sync, &done)); |
+ EXPECT_LE(1U, ThreadPool::workers_started()); |
+ EXPECT_EQ(0U, ThreadPool::workers_stopped()); |
{ |
MonitorLocker ml(&sync); |
while (!done) { |
@@ -151,19 +96,21 @@ UNIT_TEST_CASE(ThreadPool_WorkerTimeout) { |
// Wait up to 5 seconds to see if a worker times out. |
const int kMaxWait = 5000; |
int waited = 0; |
- while (thread_pool.workers_stopped() == 0 && waited < kMaxWait) { |
+ while (ThreadPool::workers_stopped() == 0 && waited < kMaxWait) { |
OS::Sleep(1); |
waited += 1; |
} |
- EXPECT_EQ(1U, thread_pool.workers_stopped()); |
+ EXPECT_LE(1U, ThreadPool::workers_stopped()); |
FLAG_worker_timeout_millis = saved_timeout; |
+ |
+ EXPECT(ThreadPool::Shutdown()); |
} |
class SpawnTask : public ThreadPool::Task { |
public: |
- SpawnTask(ThreadPool* pool, Monitor* sync, int todo, int total, int* done) |
- : pool_(pool), sync_(sync), todo_(todo), total_(total), done_(done) { |
+ SpawnTask(Monitor* sync, int todo, int total, int* done) |
+ : sync_(sync), todo_(todo), total_(total), done_(done) { |
} |
virtual void Run() { |
@@ -172,12 +119,12 @@ class SpawnTask : public ThreadPool::Task { |
// Spawn 0-2 children. |
if (todo_ > 0) { |
- pool_->Run( |
- new SpawnTask(pool_, sync_, todo_ - child_todo, total_, done_)); |
+ ThreadPool::Run( |
+ new SpawnTask(sync_, todo_ - child_todo, total_, done_)); |
} |
if (todo_ > 1) { |
- pool_->Run( |
- new SpawnTask(pool_, sync_, child_todo, total_, done_)); |
+ ThreadPool::Run( |
+ new SpawnTask(sync_, child_todo, total_, done_)); |
} |
{ |
@@ -190,7 +137,6 @@ class SpawnTask : public ThreadPool::Task { |
} |
private: |
- ThreadPool* pool_; |
Monitor* sync_; |
int todo_; |
int total_; |
@@ -199,12 +145,12 @@ class SpawnTask : public ThreadPool::Task { |
UNIT_TEST_CASE(ThreadPool_RecursiveSpawn) { |
- ThreadPool thread_pool; |
+ ThreadPool::set_shutdown_timeout_fatal(false); |
Monitor sync; |
const int kTotalTasks = 500; |
int done = 0; |
- thread_pool.Run( |
- new SpawnTask(&thread_pool, &sync, kTotalTasks, kTotalTasks, &done)); |
+ ThreadPool::Run( |
+ new SpawnTask(&sync, kTotalTasks, kTotalTasks, &done)); |
{ |
MonitorLocker ml(&sync); |
while (done < kTotalTasks) { |
@@ -212,6 +158,39 @@ UNIT_TEST_CASE(ThreadPool_RecursiveSpawn) { |
} |
} |
EXPECT_EQ(kTotalTasks, done); |
+ EXPECT(ThreadPool::Shutdown()); |
+} |
+ |
+ |
+class SleepTask : public ThreadPool::Task { |
+ public: |
+ SleepTask(Monitor* sync, int millis) |
+ : sync_(sync), millis_(millis) { |
+ } |
+ |
+ virtual void Run() { |
+ { |
+ MonitorLocker ml(sync_); |
+ ml.Notify(); |
+ } |
+ OS::Sleep(millis_); |
+ } |
+ |
+ private: |
+ Monitor* sync_; |
+ int millis_; |
+}; |
+ |
+ |
+UNIT_TEST_CASE(ThreadPool_ShutdownTimeout) { |
+ ThreadPool::set_shutdown_timeout_fatal(false); |
+ Monitor sync; |
+ ThreadPool::Run(new SleepTask(&sync, 15000)); |
+ { |
+ MonitorLocker ml(&sync); |
+ ml.Wait(); |
+ } |
+ EXPECT(!ThreadPool::Shutdown()); |
} |