| 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());
|
| }
|
|
|
|
|
|
|