Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd8767c0 authored by Hansong Zhang's avatar Hansong Zhang Committed by android-build-merger
Browse files

Timer: Set data member before scheduling task

am: 9c64d966

Change-Id: I6c6c82ec7a58e429778116d064cc1ac4d825fd6b
parents 7ebafaac 9c64d966
Loading
Loading
Loading
Loading
+6 −3
Original line number Original line Diff line number Diff line
@@ -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(),
@@ -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;
}
}


+26 −35
Original line number Original line Diff line number Diff line
@@ -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());
}
}


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


@@ -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) {
@@ -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) {