Loading system/common/timer.cc +6 −3 Original line number Original line Diff line number Diff line Loading @@ -66,6 +66,9 @@ bool Timer::ScheduleTaskHelper(const base::WeakPtr<MessageLoopThread>& thread, expected_time_next_task_us_ = time_next_task_us; expected_time_next_task_us_ = time_next_task_us; task_ = std::move(task); task_ = std::move(task); task_wrapper_.Reset(base::Bind(&Timer::RunTask, base::Unretained(this))); task_wrapper_.Reset(base::Bind(&Timer::RunTask, base::Unretained(this))); message_loop_thread_ = thread; period_ = delay; is_periodic_ = is_periodic; uint64_t time_until_next_us = time_next_task_us - time_get_os_boottime_us(); uint64_t time_until_next_us = time_next_task_us - time_get_os_boottime_us(); if (!thread->DoInThreadDelayed( if (!thread->DoInThreadDelayed( from_here, task_wrapper_.callback(), from_here, task_wrapper_.callback(), Loading @@ -75,11 +78,11 @@ bool Timer::ScheduleTaskHelper(const base::WeakPtr<MessageLoopThread>& thread, << ", from " << from_here.ToString(); << ", from " << from_here.ToString(); expected_time_next_task_us_ = 0; expected_time_next_task_us_ = 0; task_wrapper_.Cancel(); task_wrapper_.Cancel(); message_loop_thread_ = nullptr; period_ = {}; is_periodic_ = false; return false; return false; } } message_loop_thread_ = thread; period_ = delay; is_periodic_ = is_periodic; return true; return true; } } Loading system/common/timer_unittest.cc +26 −35 Original line number Original line Diff line number Diff line Loading @@ -134,6 +134,7 @@ TEST_F(TimerTest, schedule_task) { EXPECT_TRUE(timer_->IsScheduled()); EXPECT_TRUE(timer_->IsScheduled()); future.get(); future.get(); ASSERT_EQ(name, my_name); ASSERT_EQ(name, my_name); std::this_thread::sleep_for(std::chrono::milliseconds(delay_error_ms)); EXPECT_FALSE(timer_->IsScheduled()); EXPECT_FALSE(timer_->IsScheduled()); } } Loading Loading @@ -173,7 +174,7 @@ TEST_F(TimerTest, periodic_run) { num_tasks, promise_), num_tasks, promise_), base::TimeDelta::FromMilliseconds(delay_ms)); base::TimeDelta::FromMilliseconds(delay_ms)); future.get(); future.get(); ASSERT_EQ(counter_, num_tasks); ASSERT_GE(counter_, num_tasks); timer_->CancelAndWait(); timer_->CancelAndWait(); } } Loading Loading @@ -288,43 +289,28 @@ TEST_F(TimerTest, schedule_multiple_delayed_slow_tasks_stress) { VerifyMultipleDelayedTasks(100, 10, 20); VerifyMultipleDelayedTasks(100, 10, 20); } } // Verify that when MessageLoopThread is shutdown, the pending task will be TEST_F(TimerTest, message_loop_thread_down_cancel_scheduled_periodic_task) { // cancelled TEST_F(TimerTest, message_loop_thread_down_cancel_pending_task) { std::string name = "test_thread"; std::string name = "test_thread"; MessageLoopThread message_loop_thread(name); MessageLoopThread message_loop_thread(name); message_loop_thread.StartUp(); message_loop_thread.StartUp(); std::string my_name; std::string my_name; auto future = promise_->get_future(); uint32_t delay_ms = 5; uint32_t delay_ms = 5; int num_tasks = 5; timer_->Schedule( timer_->SchedulePeriodic( message_loop_thread.GetWeakPtr(), FROM_HERE, base::Bind(&TimerTest::ShouldNotHappen, base::Unretained(this)), base::TimeDelta::FromMilliseconds(delay_ms)); EXPECT_TRUE(timer_->IsScheduled()); std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms - 3)); message_loop_thread.ShutDown(); std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms)); } // Verify that when MessageLoopThread is shutdown, the pending periodic task // will be cancelled TEST_F(TimerTest, message_loop_thread_down_cancel_pending_periodic_task) { std::string name = "test_thread"; MessageLoopThread message_loop_thread(name); message_loop_thread.StartUp(); uint32_t delay_ms = 5; timer_->Schedule( message_loop_thread.GetWeakPtr(), FROM_HERE, message_loop_thread.GetWeakPtr(), FROM_HERE, base::Bind(&TimerTest::ShouldNotHappen, base::Unretained(this)), base::Bind(&TimerTest::IncreaseTaskCounter, base::Unretained(this), num_tasks, promise_), base::TimeDelta::FromMilliseconds(delay_ms)); base::TimeDelta::FromMilliseconds(delay_ms)); EXPECT_TRUE(timer_->IsScheduled()); future.wait(); std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms - 2)); message_loop_thread.ShutDown(); message_loop_thread.ShutDown(); timer_->CancelAndWait(); std::this_thread::sleep_for( EXPECT_FALSE(timer_->IsScheduled()); std::chrono::milliseconds(delay_ms + delay_error_ms)); std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms)); int counter = counter_; std::this_thread::sleep_for( std::chrono::milliseconds(delay_ms + delay_error_ms)); ASSERT_EQ(counter, counter_); } } TEST_F(TimerTest, schedule_task_cancel_previous_task) { TEST_F(TimerTest, schedule_task_cancel_previous_task) { Loading @@ -334,18 +320,23 @@ TEST_F(TimerTest, schedule_task_cancel_previous_task) { std::string my_name; std::string my_name; auto future = promise_->get_future(); auto future = promise_->get_future(); uint32_t delay_ms = 5; uint32_t delay_ms = 5; int num_tasks = 5; timer_->SchedulePeriodic( timer_->SchedulePeriodic( message_loop_thread.GetWeakPtr(), FROM_HERE, message_loop_thread.GetWeakPtr(), FROM_HERE, base::Bind(&TimerTest::ShouldNotHappen, base::Unretained(this)), base::Bind(&TimerTest::IncreaseTaskCounter, base::Unretained(this), num_tasks, promise_), base::TimeDelta::FromMilliseconds(delay_ms)); base::TimeDelta::FromMilliseconds(delay_ms)); std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms - 2)); future.wait(); timer_->Schedule(message_loop_thread.GetWeakPtr(), FROM_HERE, timer_->Schedule(message_loop_thread.GetWeakPtr(), FROM_HERE, base::Bind(&TimerTest::GetName, base::Unretained(this), base::Bind([]() {}), &my_name, promise_), base::TimeDelta::FromMilliseconds(delay_ms)); base::TimeDelta::FromMilliseconds(delay_ms)); future.wait(); std::this_thread::sleep_for( ASSERT_EQ(name, my_name); std::chrono::milliseconds(delay_ms + delay_error_ms)); int counter = counter_; std::this_thread::sleep_for( std::chrono::milliseconds(delay_ms + delay_error_ms)); ASSERT_EQ(counter, counter_); } } TEST_F(TimerTest, reschedule_task_dont_invoke_new_task_early) { TEST_F(TimerTest, reschedule_task_dont_invoke_new_task_early) { Loading Loading
system/common/timer.cc +6 −3 Original line number Original line Diff line number Diff line Loading @@ -66,6 +66,9 @@ bool Timer::ScheduleTaskHelper(const base::WeakPtr<MessageLoopThread>& thread, expected_time_next_task_us_ = time_next_task_us; expected_time_next_task_us_ = time_next_task_us; task_ = std::move(task); task_ = std::move(task); task_wrapper_.Reset(base::Bind(&Timer::RunTask, base::Unretained(this))); task_wrapper_.Reset(base::Bind(&Timer::RunTask, base::Unretained(this))); message_loop_thread_ = thread; period_ = delay; is_periodic_ = is_periodic; uint64_t time_until_next_us = time_next_task_us - time_get_os_boottime_us(); uint64_t time_until_next_us = time_next_task_us - time_get_os_boottime_us(); if (!thread->DoInThreadDelayed( if (!thread->DoInThreadDelayed( from_here, task_wrapper_.callback(), from_here, task_wrapper_.callback(), Loading @@ -75,11 +78,11 @@ bool Timer::ScheduleTaskHelper(const base::WeakPtr<MessageLoopThread>& thread, << ", from " << from_here.ToString(); << ", from " << from_here.ToString(); expected_time_next_task_us_ = 0; expected_time_next_task_us_ = 0; task_wrapper_.Cancel(); task_wrapper_.Cancel(); message_loop_thread_ = nullptr; period_ = {}; is_periodic_ = false; return false; return false; } } message_loop_thread_ = thread; period_ = delay; is_periodic_ = is_periodic; return true; return true; } } Loading
system/common/timer_unittest.cc +26 −35 Original line number Original line Diff line number Diff line Loading @@ -134,6 +134,7 @@ TEST_F(TimerTest, schedule_task) { EXPECT_TRUE(timer_->IsScheduled()); EXPECT_TRUE(timer_->IsScheduled()); future.get(); future.get(); ASSERT_EQ(name, my_name); ASSERT_EQ(name, my_name); std::this_thread::sleep_for(std::chrono::milliseconds(delay_error_ms)); EXPECT_FALSE(timer_->IsScheduled()); EXPECT_FALSE(timer_->IsScheduled()); } } Loading Loading @@ -173,7 +174,7 @@ TEST_F(TimerTest, periodic_run) { num_tasks, promise_), num_tasks, promise_), base::TimeDelta::FromMilliseconds(delay_ms)); base::TimeDelta::FromMilliseconds(delay_ms)); future.get(); future.get(); ASSERT_EQ(counter_, num_tasks); ASSERT_GE(counter_, num_tasks); timer_->CancelAndWait(); timer_->CancelAndWait(); } } Loading Loading @@ -288,43 +289,28 @@ TEST_F(TimerTest, schedule_multiple_delayed_slow_tasks_stress) { VerifyMultipleDelayedTasks(100, 10, 20); VerifyMultipleDelayedTasks(100, 10, 20); } } // Verify that when MessageLoopThread is shutdown, the pending task will be TEST_F(TimerTest, message_loop_thread_down_cancel_scheduled_periodic_task) { // cancelled TEST_F(TimerTest, message_loop_thread_down_cancel_pending_task) { std::string name = "test_thread"; std::string name = "test_thread"; MessageLoopThread message_loop_thread(name); MessageLoopThread message_loop_thread(name); message_loop_thread.StartUp(); message_loop_thread.StartUp(); std::string my_name; std::string my_name; auto future = promise_->get_future(); uint32_t delay_ms = 5; uint32_t delay_ms = 5; int num_tasks = 5; timer_->Schedule( timer_->SchedulePeriodic( message_loop_thread.GetWeakPtr(), FROM_HERE, base::Bind(&TimerTest::ShouldNotHappen, base::Unretained(this)), base::TimeDelta::FromMilliseconds(delay_ms)); EXPECT_TRUE(timer_->IsScheduled()); std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms - 3)); message_loop_thread.ShutDown(); std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms)); } // Verify that when MessageLoopThread is shutdown, the pending periodic task // will be cancelled TEST_F(TimerTest, message_loop_thread_down_cancel_pending_periodic_task) { std::string name = "test_thread"; MessageLoopThread message_loop_thread(name); message_loop_thread.StartUp(); uint32_t delay_ms = 5; timer_->Schedule( message_loop_thread.GetWeakPtr(), FROM_HERE, message_loop_thread.GetWeakPtr(), FROM_HERE, base::Bind(&TimerTest::ShouldNotHappen, base::Unretained(this)), base::Bind(&TimerTest::IncreaseTaskCounter, base::Unretained(this), num_tasks, promise_), base::TimeDelta::FromMilliseconds(delay_ms)); base::TimeDelta::FromMilliseconds(delay_ms)); EXPECT_TRUE(timer_->IsScheduled()); future.wait(); std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms - 2)); message_loop_thread.ShutDown(); message_loop_thread.ShutDown(); timer_->CancelAndWait(); std::this_thread::sleep_for( EXPECT_FALSE(timer_->IsScheduled()); std::chrono::milliseconds(delay_ms + delay_error_ms)); std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms)); int counter = counter_; std::this_thread::sleep_for( std::chrono::milliseconds(delay_ms + delay_error_ms)); ASSERT_EQ(counter, counter_); } } TEST_F(TimerTest, schedule_task_cancel_previous_task) { TEST_F(TimerTest, schedule_task_cancel_previous_task) { Loading @@ -334,18 +320,23 @@ TEST_F(TimerTest, schedule_task_cancel_previous_task) { std::string my_name; std::string my_name; auto future = promise_->get_future(); auto future = promise_->get_future(); uint32_t delay_ms = 5; uint32_t delay_ms = 5; int num_tasks = 5; timer_->SchedulePeriodic( timer_->SchedulePeriodic( message_loop_thread.GetWeakPtr(), FROM_HERE, message_loop_thread.GetWeakPtr(), FROM_HERE, base::Bind(&TimerTest::ShouldNotHappen, base::Unretained(this)), base::Bind(&TimerTest::IncreaseTaskCounter, base::Unretained(this), num_tasks, promise_), base::TimeDelta::FromMilliseconds(delay_ms)); base::TimeDelta::FromMilliseconds(delay_ms)); std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms - 2)); future.wait(); timer_->Schedule(message_loop_thread.GetWeakPtr(), FROM_HERE, timer_->Schedule(message_loop_thread.GetWeakPtr(), FROM_HERE, base::Bind(&TimerTest::GetName, base::Unretained(this), base::Bind([]() {}), &my_name, promise_), base::TimeDelta::FromMilliseconds(delay_ms)); base::TimeDelta::FromMilliseconds(delay_ms)); future.wait(); std::this_thread::sleep_for( ASSERT_EQ(name, my_name); std::chrono::milliseconds(delay_ms + delay_error_ms)); int counter = counter_; std::this_thread::sleep_for( std::chrono::milliseconds(delay_ms + delay_error_ms)); ASSERT_EQ(counter, counter_); } } TEST_F(TimerTest, reschedule_task_dont_invoke_new_task_early) { TEST_F(TimerTest, reschedule_task_dont_invoke_new_task_early) { Loading