Support base::OnceCallback on base::OneShotTimer
This moves task management logic of base::internal::TimerBase to its
subclasses, so that subclasses can hold user tasks as different types
for each.
Specifically, OneShotTimer's task type is converted to OnceClosure after
this CL, and it gets supporting OnceCallback.
Bug: 850247
Change-Id: Ie017c2ed6e0fb1fe44937a497576d16e5c3dab68
Reviewed-on: https://chromium-review.googlesource.com/1127215
Reviewed-by: Matt Menke <[email protected]>
Reviewed-by: Gabriel Charette <[email protected]>
Commit-Queue: Taiju Tsuiki <[email protected]>
Cr-Commit-Position: refs/heads/master@{#577784}
diff --git a/base/timer/timer.cc b/base/timer/timer.cc
index aa2e0d4..973aae89 100644
--- a/base/timer/timer.cc
+++ b/base/timer/timer.cc
@@ -58,17 +58,10 @@
DISALLOW_COPY_AND_ASSIGN(BaseTimerTaskInternal);
};
-TimerBase::TimerBase(bool retain_user_task, bool is_repeating)
- : TimerBase(retain_user_task, is_repeating, nullptr) {}
+TimerBase::TimerBase() : TimerBase(nullptr) {}
-TimerBase::TimerBase(bool retain_user_task,
- bool is_repeating,
- const TickClock* tick_clock)
- : scheduled_task_(nullptr),
- is_repeating_(is_repeating),
- retain_user_task_(retain_user_task),
- tick_clock_(tick_clock),
- is_running_(false) {
+TimerBase::TimerBase(const TickClock* tick_clock)
+ : scheduled_task_(nullptr), tick_clock_(tick_clock), is_running_(false) {
// It is safe for the timer to be created on a different thread/sequence than
// the one from which the timer APIs are called. The first call to the
// checker's CalledOnValidSequence() method will re-bind the checker, and
@@ -76,23 +69,15 @@
origin_sequence_checker_.DetachFromSequence();
}
-TimerBase::TimerBase(const Location& posted_from,
- TimeDelta delay,
- const base::Closure& user_task,
- bool is_repeating)
- : TimerBase(posted_from, delay, user_task, is_repeating, nullptr) {}
+TimerBase::TimerBase(const Location& posted_from, TimeDelta delay)
+ : TimerBase(posted_from, delay, nullptr) {}
TimerBase::TimerBase(const Location& posted_from,
TimeDelta delay,
- const base::Closure& user_task,
- bool is_repeating,
const TickClock* tick_clock)
: scheduled_task_(nullptr),
posted_from_(posted_from),
delay_(delay),
- user_task_(user_task),
- is_repeating_(is_repeating),
- retain_user_task_(true),
tick_clock_(tick_clock),
is_running_(false) {
// See comment in other constructor.
@@ -101,7 +86,7 @@
TimerBase::~TimerBase() {
DCHECK(origin_sequence_checker_.CalledOnValidSequence());
- AbandonAndStop();
+ AbandonScheduledTask();
}
bool TimerBase::IsRunning() const {
@@ -126,14 +111,11 @@
task_runner_.swap(task_runner);
}
-void TimerBase::Start(const Location& posted_from,
- TimeDelta delay,
- const base::Closure& user_task) {
+void TimerBase::StartInternal(const Location& posted_from, TimeDelta delay) {
DCHECK(origin_sequence_checker_.CalledOnValidSequence());
posted_from_ = posted_from;
delay_ = delay;
- user_task_ = user_task;
Reset();
}
@@ -148,15 +130,12 @@
// It's safe to destroy or restart Timer on another sequence after Stop().
origin_sequence_checker_.DetachFromSequence();
- if (!retain_user_task_)
- user_task_.Reset();
- // No more member accesses here: |this| could be deleted after freeing
- // |user_task_|.
+ OnStop();
+ // No more member accesses here: |this| could be deleted after Stop() call.
}
void TimerBase::Reset() {
DCHECK(origin_sequence_checker_.CalledOnValidSequence());
- DCHECK(!user_task_.is_null());
// If there's no pending task, start one up and return.
if (!scheduled_task_) {
@@ -201,14 +180,12 @@
// this code racy. https://crbug.com/587199
GetTaskRunner()->PostDelayedTask(
posted_from_,
- base::BindOnce(&BaseTimerTaskInternal::Run,
- base::Owned(scheduled_task_)),
- delay);
+ BindOnce(&BaseTimerTaskInternal::Run, Owned(scheduled_task_)), delay);
scheduled_run_time_ = desired_run_time_ = Now() + delay;
} else {
- GetTaskRunner()->PostTask(posted_from_,
- base::BindOnce(&BaseTimerTaskInternal::Run,
- base::Owned(scheduled_task_)));
+ GetTaskRunner()->PostTask(
+ posted_from_,
+ BindOnce(&BaseTimerTaskInternal::Run, Owned(scheduled_task_)));
scheduled_run_time_ = desired_run_time_ = TimeTicks();
}
}
@@ -250,31 +227,114 @@
}
}
- // Make a local copy of the task to run. The Stop method will reset the
- // |user_task_| member if |retain_user_task_| is false.
- base::Closure task = user_task_;
-
- if (is_repeating_)
- PostNewScheduledTask(delay_);
- else
- Stop();
-
- task.Run();
-
+ RunUserTask();
// No more member accesses here: |this| could be deleted at this point.
}
} // namespace internal
+OneShotTimer::OneShotTimer() = default;
+OneShotTimer::OneShotTimer(const TickClock* tick_clock)
+ : internal::TimerBase(tick_clock) {}
+OneShotTimer::~OneShotTimer() = default;
+
+void OneShotTimer::Start(const Location& posted_from,
+ TimeDelta delay,
+ OnceClosure user_task) {
+ user_task_ = std::move(user_task);
+ StartInternal(posted_from, delay);
+}
+
void OneShotTimer::FireNow() {
DCHECK(origin_sequence_checker_.CalledOnValidSequence());
DCHECK(!task_runner_) << "FireNow() is incompatible with SetTaskRunner()";
DCHECK(IsRunning());
- OnceClosure task = user_task();
+ RunUserTask();
+}
+
+void OneShotTimer::OnStop() {
+ user_task_.Reset();
+ // No more member accesses here: |this| could be deleted after freeing
+ // |user_task_|.
+}
+
+void OneShotTimer::RunUserTask() {
+ // Make a local copy of the task to run. The Stop method will reset the
+ // |user_task_| member.
+ OnceClosure task = std::move(user_task_);
Stop();
- DCHECK(!user_task());
+ DCHECK(task);
std::move(task).Run();
+ // No more member accesses here: |this| could be deleted at this point.
+}
+
+RepeatingTimer::RepeatingTimer() = default;
+RepeatingTimer::RepeatingTimer(const TickClock* tick_clock)
+ : internal::TimerBase(tick_clock) {}
+RepeatingTimer::~RepeatingTimer() = default;
+
+RepeatingTimer::RepeatingTimer(const Location& posted_from,
+ TimeDelta delay,
+ RepeatingClosure user_task)
+ : internal::TimerBase(posted_from, delay),
+ user_task_(std::move(user_task)) {}
+RepeatingTimer::RepeatingTimer(const Location& posted_from,
+ TimeDelta delay,
+ RepeatingClosure user_task,
+ const TickClock* tick_clock)
+ : internal::TimerBase(posted_from, delay, tick_clock),
+ user_task_(std::move(user_task)) {}
+
+void RepeatingTimer::Start(const Location& posted_from,
+ TimeDelta delay,
+ RepeatingClosure user_task) {
+ user_task_ = std::move(user_task);
+ StartInternal(posted_from, delay);
+}
+
+void RepeatingTimer::OnStop() {}
+void RepeatingTimer::RunUserTask() {
+ // Make a local copy of the task to run in case the task destroy the timer
+ // instance.
+ RepeatingClosure task = user_task_;
+ PostNewScheduledTask(GetCurrentDelay());
+ task.Run();
+ // No more member accesses here: |this| could be deleted at this point.
+}
+
+RetainingOneShotTimer::RetainingOneShotTimer() = default;
+RetainingOneShotTimer::RetainingOneShotTimer(const TickClock* tick_clock)
+ : internal::TimerBase(tick_clock) {}
+RetainingOneShotTimer::~RetainingOneShotTimer() = default;
+
+RetainingOneShotTimer::RetainingOneShotTimer(const Location& posted_from,
+ TimeDelta delay,
+ RepeatingClosure user_task)
+ : internal::TimerBase(posted_from, delay),
+ user_task_(std::move(user_task)) {}
+RetainingOneShotTimer::RetainingOneShotTimer(const Location& posted_from,
+ TimeDelta delay,
+ RepeatingClosure user_task,
+ const TickClock* tick_clock)
+ : internal::TimerBase(posted_from, delay, tick_clock),
+ user_task_(std::move(user_task)) {}
+
+void RetainingOneShotTimer::Start(const Location& posted_from,
+ TimeDelta delay,
+ RepeatingClosure user_task) {
+ user_task_ = std::move(user_task);
+ StartInternal(posted_from, delay);
+}
+
+void RetainingOneShotTimer::OnStop() {}
+void RetainingOneShotTimer::RunUserTask() {
+ // Make a local copy of the task to run in case the task destroys the timer
+ // instance.
+ RepeatingClosure task = user_task_;
+ Stop();
+ task.Run();
+ // No more member accesses here: |this| could be deleted at this point.
}
} // namespace base
diff --git a/base/timer/timer.h b/base/timer/timer.h
index 3f666b6..6f7b450 100644
--- a/base/timer/timer.h
+++ b/base/timer/timer.h
@@ -92,25 +92,18 @@
//
class BASE_EXPORT TimerBase {
public:
- // Construct a timer in repeating or one-shot mode. Start must be called later
- // to set task info. |retain_user_task| determines whether the user_task is
- // retained or reset when it runs or stops. If |tick_clock| is provided, it is
- // used instead of TimeTicks::Now() to get TimeTicks when scheduling tasks.
- TimerBase(bool retain_user_task, bool is_repeating);
- TimerBase(bool retain_user_task,
- bool is_repeating,
- const TickClock* tick_clock);
+ // Constructs a timer. Start must be called later to set task info.
+ // If |tick_clock| is provided, it is used instead of TimeTicks::Now() to get
+ // TimeTicks when scheduling tasks.
+ TimerBase();
+ explicit TimerBase(const TickClock* tick_clock);
- // Construct a timer with retained task info. If |tick_clock| is provided, it
- // is used instead of TimeTicks::Now() to get TimeTicks when scheduling tasks.
+ // Construct a timer with task info.
+ // If |tick_clock| is provided, it is used instead of TimeTicks::Now() to get
+ // TimeTicks when scheduling tasks.
+ TimerBase(const Location& posted_from, TimeDelta delay);
TimerBase(const Location& posted_from,
TimeDelta delay,
- const base::Closure& user_task,
- bool is_repeating);
- TimerBase(const Location& posted_from,
- TimeDelta delay,
- const base::Closure& user_task,
- bool is_repeating,
const TickClock* tick_clock);
virtual ~TimerBase();
@@ -123,29 +116,11 @@
// Set the task runner on which the task should be scheduled. This method can
// only be called before any tasks have been scheduled. If |task_runner| runs
- // tasks on a different sequence than the sequence owning this Timer,
- // |user_task_| will be posted to it when the Timer fires (note that this
- // means |user_task_| can run after ~Timer() and should support that).
+ // tasks on a different sequence than the sequence owning this Timer, the user
+ // task will be posted to it when the Timer fires (note that this means the
+ // user task can run after ~Timer() and should support that).
virtual void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner);
- // Start the timer to run at the given |delay| from now. If the timer is
- // already running, it will be replaced to call the given |user_task|.
- virtual void Start(const Location& posted_from,
- TimeDelta delay,
- const base::Closure& user_task);
-
- // Start the timer to run at the given |delay| from now. If the timer is
- // already running, it will be replaced to call a task formed from
- // |reviewer->*method|.
- template <class Receiver>
- void Start(const Location& posted_from,
- TimeDelta delay,
- Receiver* receiver,
- void (Receiver::*method)()) {
- Start(posted_from, delay,
- base::BindRepeating(method, base::Unretained(receiver)));
- }
-
// Call this method to stop and cancel the timer. It is a no-op if the timer
// is not running.
virtual void Stop();
@@ -158,18 +133,19 @@
// No more member accesses here: |this| could be deleted at this point.
}
- // Call this method to reset the timer delay. The |user_task_| must be set. If
+ // Call this method to reset the timer delay. The user task must be set. If
// the timer is not running, this will start it by posting a task.
virtual void Reset();
- const base::Closure& user_task() const { return user_task_; }
const TimeTicks& desired_run_time() const { return desired_run_time_; }
protected:
+ virtual void OnStop() = 0;
+ virtual void RunUserTask() = 0;
+
// Returns the current tick count.
TimeTicks Now() const;
- void set_user_task(const Closure& task) { user_task_ = task; }
void set_desired_run_time(TimeTicks desired) { desired_run_time_ = desired; }
void set_is_running(bool running) { is_running_ = running; }
@@ -184,14 +160,16 @@
// destroyed or restarted on another sequence.
SequenceChecker origin_sequence_checker_;
- private:
- friend class BaseTimerTaskInternal;
-
// Allocates a new |scheduled_task_| and posts it on the current sequence with
// the given |delay|. |scheduled_task_| must be null. |scheduled_run_time_|
// and |desired_run_time_| are reset to Now() + delay.
void PostNewScheduledTask(TimeDelta delay);
+ void StartInternal(const Location& posted_from, TimeDelta delay);
+
+ private:
+ friend class BaseTimerTaskInternal;
+
// Returns the task runner on which the task should be scheduled. If the
// corresponding |task_runner_| field is null, the task runner for the current
// sequence is returned.
@@ -212,8 +190,6 @@
Location posted_from_;
// Delay requested by user.
TimeDelta delay_;
- // |user_task_| is what the user wants to be run at |desired_run_time_|.
- base::Closure user_task_;
// The time at which |scheduled_task_| is expected to fire. This time can be a
// "zero" TimeTicks if the task must be run immediately.
@@ -228,13 +204,6 @@
// if the task must be run immediately.
TimeTicks desired_run_time_;
- // Repeating timers automatically post the task again before calling the task
- // callback.
- const bool is_repeating_;
-
- // If true, hold on to the |user_task_| closure object for reuse.
- const bool retain_user_task_;
-
// The tick clock used to calculate the run time for scheduled tasks.
const TickClock* const tick_clock_;
@@ -250,60 +219,134 @@
// A simple, one-shot timer. See usage notes at the top of the file.
class BASE_EXPORT OneShotTimer : public internal::TimerBase {
public:
- OneShotTimer() : OneShotTimer(nullptr) {}
- explicit OneShotTimer(const TickClock* tick_clock)
- : internal::TimerBase(false, false, tick_clock) {}
+ OneShotTimer();
+ explicit OneShotTimer(const TickClock* tick_clock);
+ ~OneShotTimer() override;
+
+ // Start the timer to run at the given |delay| from now. If the timer is
+ // already running, it will be replaced to call the given |user_task|.
+ virtual void Start(const Location& posted_from,
+ TimeDelta delay,
+ OnceClosure user_task);
+
+ // Start the timer to run at the given |delay| from now. If the timer is
+ // already running, it will be replaced to call a task formed from
+ // |reviewer->*method|.
+ template <class Receiver>
+ void Start(const Location& posted_from,
+ TimeDelta delay,
+ Receiver* receiver,
+ void (Receiver::*method)()) {
+ Start(posted_from, delay, BindOnce(method, Unretained(receiver)));
+ }
// Run the scheduled task immediately, and stop the timer. The timer needs to
// be running.
void FireNow();
+
+ private:
+ void OnStop() final;
+ void RunUserTask() final;
+
+ OnceClosure user_task_;
+
+ DISALLOW_COPY_AND_ASSIGN(OneShotTimer);
};
//-----------------------------------------------------------------------------
// A simple, repeating timer. See usage notes at the top of the file.
-class RepeatingTimer : public internal::TimerBase {
+class BASE_EXPORT RepeatingTimer : public internal::TimerBase {
public:
- RepeatingTimer() : RepeatingTimer(nullptr) {}
- explicit RepeatingTimer(const TickClock* tick_clock)
- : internal::TimerBase(true, true, tick_clock) {}
+ RepeatingTimer();
+ explicit RepeatingTimer(const TickClock* tick_clock);
+ ~RepeatingTimer() override;
RepeatingTimer(const Location& posted_from,
TimeDelta delay,
- RepeatingClosure user_task)
- : internal::TimerBase(posted_from, delay, std::move(user_task), true) {}
+ RepeatingClosure user_task);
RepeatingTimer(const Location& posted_from,
TimeDelta delay,
RepeatingClosure user_task,
- const TickClock* tick_clock)
- : internal::TimerBase(posted_from,
- delay,
- std::move(user_task),
- true,
- tick_clock) {}
+ const TickClock* tick_clock);
+
+ // Start the timer to run at the given |delay| from now. If the timer is
+ // already running, it will be replaced to call the given |user_task|.
+ virtual void Start(const Location& posted_from,
+ TimeDelta delay,
+ RepeatingClosure user_task);
+
+ // Start the timer to run at the given |delay| from now. If the timer is
+ // already running, it will be replaced to call a task formed from
+ // |reviewer->*method|.
+ template <class Receiver>
+ void Start(const Location& posted_from,
+ TimeDelta delay,
+ Receiver* receiver,
+ void (Receiver::*method)()) {
+ Start(posted_from, delay, BindRepeating(method, Unretained(receiver)));
+ }
+
+ const RepeatingClosure& user_task() const { return user_task_; }
+
+ private:
+ // Mark this final, so that the destructor can call this safely.
+ void OnStop() final;
+
+ void RunUserTask() override;
+
+ RepeatingClosure user_task_;
+
+ DISALLOW_COPY_AND_ASSIGN(RepeatingTimer);
};
//-----------------------------------------------------------------------------
// A simple, one-shot timer with the retained user task. See usage notes at the
// top of the file.
-class RetainingOneShotTimer : public internal::TimerBase {
+class BASE_EXPORT RetainingOneShotTimer : public internal::TimerBase {
public:
- RetainingOneShotTimer() : RetainingOneShotTimer(nullptr) {}
- explicit RetainingOneShotTimer(const TickClock* tick_clock)
- : internal::TimerBase(true, false, tick_clock) {}
+ RetainingOneShotTimer();
+ explicit RetainingOneShotTimer(const TickClock* tick_clock);
+ ~RetainingOneShotTimer() override;
RetainingOneShotTimer(const Location& posted_from,
TimeDelta delay,
- RepeatingClosure user_task)
- : internal::TimerBase(posted_from, delay, std::move(user_task), false) {}
+ RepeatingClosure user_task);
RetainingOneShotTimer(const Location& posted_from,
TimeDelta delay,
RepeatingClosure user_task,
- const TickClock* tick_clock)
- : internal::TimerBase(posted_from,
- delay,
- std::move(user_task),
- false,
- tick_clock) {}
+ const TickClock* tick_clock);
+
+ // Start the timer to run at the given |delay| from now. If the timer is
+ // already running, it will be replaced to call the given |user_task|.
+ virtual void Start(const Location& posted_from,
+ TimeDelta delay,
+ RepeatingClosure user_task);
+
+ // Start the timer to run at the given |delay| from now. If the timer is
+ // already running, it will be replaced to call a task formed from
+ // |reviewer->*method|.
+ template <class Receiver>
+ void Start(const Location& posted_from,
+ TimeDelta delay,
+ Receiver* receiver,
+ void (Receiver::*method)()) {
+ Start(posted_from, delay, BindRepeating(method, Unretained(receiver)));
+ }
+
+ const RepeatingClosure& user_task() const { return user_task_; }
+
+ protected:
+ void set_user_task(const RepeatingClosure& task) { user_task_ = task; }
+
+ private:
+ // Mark this final, so that the destructor can call this safely.
+ void OnStop() final;
+
+ void RunUserTask() override;
+
+ RepeatingClosure user_task_;
+
+ DISALLOW_COPY_AND_ASSIGN(RetainingOneShotTimer);
};
//-----------------------------------------------------------------------------
diff --git a/base/timer/timer_unittest.cc b/base/timer/timer_unittest.cc
index 3ebf301..3f74779d 100644
--- a/base/timer/timer_unittest.cc
+++ b/base/timer/timer_unittest.cc
@@ -112,9 +112,9 @@
// Run() will be invoked on |task_runner| but |run_loop_|'s QuitClosure
// needs to run on this thread (where the MessageLoop lives).
- quit_closure_ = Bind(IgnoreResult(&SequencedTaskRunner::PostTask),
- SequencedTaskRunnerHandle::Get(), FROM_HERE,
- run_loop_.QuitClosure());
+ quit_closure_ = BindOnce(IgnoreResult(&SequencedTaskRunner::PostTask),
+ SequencedTaskRunnerHandle::Get(), FROM_HERE,
+ run_loop_.QuitClosure());
}
// Blocks until Run() executes and confirms that Run() didn't fire before
@@ -135,11 +135,11 @@
void Run() override {
OnRun();
OneShotTimerTesterBase::Run();
- quit_closure_.Run();
+ std::move(quit_closure_).Run();
}
RunLoop run_loop_;
- Closure quit_closure_;
+ OnceClosure quit_closure_;
DISALLOW_COPY_AND_ASSIGN(OneShotTimerTester);
};
@@ -440,7 +440,7 @@
Receiver receiver;
OneShotTimer timer(task_runner->GetMockTickClock());
timer.Start(FROM_HERE, TimeDelta::FromSeconds(1),
- Bind(&Receiver::OnCalled, Unretained(&receiver)));
+ BindOnce(&Receiver::OnCalled, Unretained(&receiver)));
task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
EXPECT_TRUE(receiver.WasCalled());
}
@@ -482,7 +482,7 @@
const int expected_times_called = 10;
RepeatingTimer timer(task_runner->GetMockTickClock());
timer.Start(FROM_HERE, TimeDelta::FromSeconds(1),
- Bind(&Receiver::OnCalled, Unretained(&receiver)));
+ BindRepeating(&Receiver::OnCalled, Unretained(&receiver)));
task_runner->FastForwardBy(TimeDelta::FromSeconds(expected_times_called));
timer.Stop();
EXPECT_EQ(expected_times_called, receiver.TimesCalled());
@@ -565,7 +565,7 @@
// Start timer with long delay in order to test the timer getting destroyed
// while a timer task is still pending.
timer_.Start(FROM_HERE, TimeDelta::FromDays(1),
- base::Bind(&OneShotSelfOwningTimerTester::Run, this));
+ BindOnce(&OneShotSelfOwningTimerTester::Run, this));
}
private:
@@ -605,18 +605,19 @@
MessageLoop loop;
OneShotTimer timer;
EXPECT_FALSE(timer.IsRunning());
- timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
+ timer.Start(FROM_HERE, TimeDelta::FromDays(1),
+ BindOnce(&TimerTestCallback));
EXPECT_TRUE(timer.IsRunning());
timer.Stop();
EXPECT_FALSE(timer.IsRunning());
- EXPECT_TRUE(timer.user_task().is_null());
}
{
RetainingOneShotTimer timer;
MessageLoop loop;
EXPECT_FALSE(timer.IsRunning());
- timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
+ timer.Start(FROM_HERE, TimeDelta::FromDays(1),
+ BindRepeating(&TimerTestCallback));
EXPECT_TRUE(timer.IsRunning());
timer.Stop();
EXPECT_FALSE(timer.IsRunning());
@@ -631,17 +632,17 @@
{
MessageLoop loop;
EXPECT_FALSE(timer.IsRunning());
- timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
+ timer.Start(FROM_HERE, TimeDelta::FromDays(1),
+ BindOnce(&TimerTestCallback));
EXPECT_TRUE(timer.IsRunning());
}
EXPECT_FALSE(timer.IsRunning());
- EXPECT_TRUE(timer.user_task().is_null());
}
TEST(TimerTest, RetainRepeatIsRunning) {
MessageLoop loop;
RepeatingTimer timer(FROM_HERE, TimeDelta::FromDays(1),
- Bind(&TimerTestCallback));
+ BindRepeating(&TimerTestCallback));
EXPECT_FALSE(timer.IsRunning());
timer.Reset();
EXPECT_TRUE(timer.IsRunning());
@@ -654,7 +655,7 @@
TEST(TimerTest, RetainNonRepeatIsRunning) {
MessageLoop loop;
RetainingOneShotTimer timer(FROM_HERE, TimeDelta::FromDays(1),
- Bind(&TimerTestCallback));
+ BindRepeating(&TimerTestCallback));
EXPECT_FALSE(timer.IsRunning());
timer.Reset();
EXPECT_TRUE(timer.IsRunning());
@@ -694,10 +695,10 @@
MessageLoop loop;
OneShotTimer timer;
timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
- Bind(&SetCallbackHappened1));
+ BindOnce(&SetCallbackHappened1));
timer.Stop();
timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(40),
- Bind(&SetCallbackHappened2));
+ BindOnce(&SetCallbackHappened2));
RunLoop().Run();
EXPECT_FALSE(g_callback_happened1);
EXPECT_TRUE(g_callback_happened2);
@@ -710,10 +711,10 @@
MessageLoop loop;
OneShotTimer timer;
timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
- Bind(&SetCallbackHappened1));
+ BindOnce(&SetCallbackHappened1));
timer.Reset();
- // Since Reset happened before task ran, the user_task must not be cleared:
- ASSERT_FALSE(timer.user_task().is_null());
+ // // Since Reset happened before task ran, the user_task must not be
+ // cleared: ASSERT_FALSE(timer.user_task().is_null());
RunLoop().Run();
EXPECT_TRUE(g_callback_happened1);
}
@@ -736,16 +737,17 @@
void Signal() { event_.Signal(); }
// Helper to augment a task with a subsequent call to Signal().
- Closure TaskWithSignal(const Closure& task) {
- return Bind(&TimerSequenceTest::RunTaskAndSignal, Unretained(this), task);
+ OnceClosure TaskWithSignal(OnceClosure task) {
+ return BindOnce(&TimerSequenceTest::RunTaskAndSignal, Unretained(this),
+ std::move(task));
}
// Create the timer.
void CreateTimer() { timer_.reset(new OneShotTimer); }
// Schedule an event on the timer.
- void StartTimer(TimeDelta delay, const Closure& task) {
- timer_->Start(FROM_HERE, delay, task);
+ void StartTimer(TimeDelta delay, OnceClosure task) {
+ timer_->Start(FROM_HERE, delay, std::move(task));
}
void SetTaskRunnerForTimer(scoped_refptr<SequencedTaskRunner> task_runner) {
@@ -770,8 +772,8 @@
void DeleteTimer() { timer_.reset(); }
private:
- void RunTaskAndSignal(const Closure& task) {
- task.Run();
+ void RunTaskAndSignal(OnceClosure task) {
+ std::move(task).Run();
Signal();
}
@@ -796,9 +798,9 @@
// Task will execute on a pool thread.
SetTaskRunnerForTimer(task_runner);
StartTimer(TimeDelta::FromMilliseconds(1),
- Bind(IgnoreResult(&SequencedTaskRunner::PostTask),
- SequencedTaskRunnerHandle::Get(), FROM_HERE,
- run_loop_.QuitClosure()));
+ BindOnce(IgnoreResult(&SequencedTaskRunner::PostTask),
+ SequencedTaskRunnerHandle::Get(), FROM_HERE,
+ run_loop_.QuitClosure()));
// Spin the loop so that the delayed task fires on it, which will forward it
// to |task_runner|. And since the Timer's task is one that posts back to this
@@ -818,15 +820,16 @@
// Task will be scheduled from a pool thread.
task_runner->PostTask(
- FROM_HERE, BindOnce(&TimerSequenceTest::StartTimer, Unretained(this),
- TimeDelta::FromMilliseconds(1),
- Bind(&TimerSequenceTest::Signal, Unretained(this))));
+ FROM_HERE,
+ BindOnce(&TimerSequenceTest::StartTimer, Unretained(this),
+ TimeDelta::FromMilliseconds(1),
+ BindOnce(&TimerSequenceTest::Signal, Unretained(this))));
Wait();
// Timer must be destroyed on pool thread, too.
- task_runner->PostTask(
- FROM_HERE,
- TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
+ task_runner->PostTask(FROM_HERE,
+ TaskWithSignal(BindOnce(&TimerSequenceTest::DeleteTimer,
+ Unretained(this))));
Wait();
}
@@ -838,31 +841,32 @@
// Create timer on sequence #1.
task_runner1->PostTask(
- FROM_HERE,
- TaskWithSignal(Bind(&TimerSequenceTest::CreateTimer, Unretained(this))));
+ FROM_HERE, TaskWithSignal(BindOnce(&TimerSequenceTest::CreateTimer,
+ Unretained(this))));
Wait();
// And tell it to execute on a different sequence (#2).
task_runner1->PostTask(
- FROM_HERE, TaskWithSignal(Bind(&TimerSequenceTest::SetTaskRunnerForTimer,
- Unretained(this), task_runner2)));
+ FROM_HERE,
+ TaskWithSignal(BindOnce(&TimerSequenceTest::SetTaskRunnerForTimer,
+ Unretained(this), task_runner2)));
Wait();
// Task will be scheduled from sequence #1.
task_runner1->PostTask(
FROM_HERE, BindOnce(&TimerSequenceTest::StartTimer, Unretained(this),
- TimeDelta::FromHours(1), DoNothing()));
+ TimeDelta::FromHours(1), DoNothing().Once()));
// Abandon task - must be called from scheduling sequence (#1).
task_runner1->PostTask(
- FROM_HERE,
- TaskWithSignal(Bind(&TimerSequenceTest::AbandonTask, Unretained(this))));
+ FROM_HERE, TaskWithSignal(BindOnce(&TimerSequenceTest::AbandonTask,
+ Unretained(this))));
Wait();
// Timer must be destroyed on the sequence it was scheduled from (#1).
task_runner1->PostTask(
- FROM_HERE,
- TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
+ FROM_HERE, TaskWithSignal(BindOnce(&TimerSequenceTest::DeleteTimer,
+ Unretained(this))));
Wait();
}
@@ -874,14 +878,15 @@
// Create timer on sequence #1.
task_runner1->PostTask(
- FROM_HERE,
- TaskWithSignal(Bind(&TimerSequenceTest::CreateTimer, Unretained(this))));
+ FROM_HERE, TaskWithSignal(BindOnce(&TimerSequenceTest::CreateTimer,
+ Unretained(this))));
Wait();
// And tell it to execute on a different sequence (#2).
task_runner1->PostTask(
- FROM_HERE, TaskWithSignal(Bind(&TimerSequenceTest::SetTaskRunnerForTimer,
- Unretained(this), task_runner2)));
+ FROM_HERE,
+ TaskWithSignal(BindOnce(&TimerSequenceTest::SetTaskRunnerForTimer,
+ Unretained(this), task_runner2)));
Wait();
// Task will be scheduled from sequence #1.
@@ -889,15 +894,15 @@
FROM_HERE,
BindOnce(&TimerSequenceTest::StartTimer, Unretained(this),
TimeDelta::FromMilliseconds(1),
- TaskWithSignal(Bind(&TimerSequenceTest::VerifyAffinity,
- Unretained(task_runner2.get())))));
+ TaskWithSignal(BindOnce(&TimerSequenceTest::VerifyAffinity,
+ Unretained(task_runner2.get())))));
Wait();
// Timer must be destroyed on the sequence it was scheduled from (#1).
task_runner1->PostTask(
- FROM_HERE,
- TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
+ FROM_HERE, TaskWithSignal(BindOnce(&TimerSequenceTest::DeleteTimer,
+ Unretained(this))));
Wait();
}
diff --git a/net/dns/mdns_client_unittest.cc b/net/dns/mdns_client_unittest.cc
index ef8a7e93..4bc0e43 100644
--- a/net/dns/mdns_client_unittest.cc
+++ b/net/dns/mdns_client_unittest.cc
@@ -381,17 +381,15 @@
void Start(const base::Location& posted_from,
base::TimeDelta delay,
- const base::Closure& user_task) override {
- StartObserver(posted_from, delay, user_task);
- base::MockOneShotTimer::Start(posted_from, delay, user_task);
+ base::OnceClosure user_task) override {
+ StartObserver(posted_from, delay);
+ base::MockOneShotTimer::Start(posted_from, delay, std::move(user_task));
}
// StartObserver is invoked when MockTimer::Start() is called.
// Does not replace the behavior of MockTimer::Start().
- MOCK_METHOD3(StartObserver,
- void(const base::Location& posted_from,
- base::TimeDelta delay,
- const base::Closure& user_task));
+ MOCK_METHOD2(StartObserver,
+ void(const base::Location& posted_from, base::TimeDelta delay));
private:
DISALLOW_COPY_AND_ASSIGN(MockTimer);
@@ -565,7 +563,7 @@
test_client_.reset(new MDnsClientImpl(&clock, base::WrapUnique(timer)));
test_client_->StartListening(&socket_factory_);
- EXPECT_CALL(*timer, StartObserver(_, _, _)).Times(1);
+ EXPECT_CALL(*timer, StartObserver(_, _)).Times(1);
EXPECT_CALL(clock, Now())
.Times(3)
.WillRepeatedly(Return(start_time))
@@ -608,7 +606,7 @@
.WillOnce(Return(start_time + base::TimeDelta::FromSeconds(2)))
.RetiresOnSaturation();
- EXPECT_CALL(*timer, StartObserver(_, base::TimeDelta(), _));
+ EXPECT_CALL(*timer, StartObserver(_, base::TimeDelta()));
timer->Fire();
}
diff --git a/net/http/bidirectional_stream_unittest.cc b/net/http/bidirectional_stream_unittest.cc
index 8e46dab..42ed8b91 100644
--- a/net/http/bidirectional_stream_unittest.cc
+++ b/net/http/bidirectional_stream_unittest.cc
@@ -384,10 +384,11 @@
void Start(const base::Location& posted_from,
base::TimeDelta delay,
- const base::Closure& user_task) override {
+ base::OnceClosure user_task) override {
// Sets a maximum delay, so the timer does not fire unless it is told to.
base::TimeDelta infinite_delay = base::TimeDelta::Max();
- base::MockOneShotTimer::Start(posted_from, infinite_delay, user_task);
+ base::MockOneShotTimer::Start(posted_from, infinite_delay,
+ std::move(user_task));
}
private: