Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
52
TMessagesProj/jni/voip/webrtc/base/timer/elapsed_timer.cc
Normal file
52
TMessagesProj/jni/voip/webrtc/base/timer/elapsed_timer.cc
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/timer/elapsed_timer.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
namespace {
|
||||
bool g_mock_elapsed_timers_for_test = false;
|
||||
} // namespace
|
||||
|
||||
ElapsedTimer::ElapsedTimer() : begin_(TimeTicks::Now()) {}
|
||||
|
||||
ElapsedTimer::ElapsedTimer(ElapsedTimer&& other) : begin_(other.begin_) {}
|
||||
|
||||
void ElapsedTimer::operator=(ElapsedTimer&& other) {
|
||||
begin_ = other.begin_;
|
||||
}
|
||||
|
||||
TimeDelta ElapsedTimer::Elapsed() const {
|
||||
if (g_mock_elapsed_timers_for_test)
|
||||
return ScopedMockElapsedTimersForTest::kMockElapsedTime;
|
||||
return TimeTicks::Now() - begin_;
|
||||
}
|
||||
|
||||
ElapsedThreadTimer::ElapsedThreadTimer()
|
||||
: is_supported_(ThreadTicks::IsSupported()),
|
||||
begin_(is_supported_ ? ThreadTicks::Now() : ThreadTicks()) {}
|
||||
|
||||
TimeDelta ElapsedThreadTimer::Elapsed() const {
|
||||
if (!is_supported_)
|
||||
return TimeDelta();
|
||||
if (g_mock_elapsed_timers_for_test)
|
||||
return ScopedMockElapsedTimersForTest::kMockElapsedTime;
|
||||
return ThreadTicks::Now() - begin_;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr TimeDelta ScopedMockElapsedTimersForTest::kMockElapsedTime;
|
||||
|
||||
ScopedMockElapsedTimersForTest::ScopedMockElapsedTimersForTest() {
|
||||
DCHECK(!g_mock_elapsed_timers_for_test);
|
||||
g_mock_elapsed_timers_for_test = true;
|
||||
}
|
||||
|
||||
ScopedMockElapsedTimersForTest::~ScopedMockElapsedTimersForTest() {
|
||||
DCHECK(g_mock_elapsed_timers_for_test);
|
||||
g_mock_elapsed_timers_for_test = false;
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
73
TMessagesProj/jni/voip/webrtc/base/timer/elapsed_timer.h
Normal file
73
TMessagesProj/jni/voip/webrtc/base/timer/elapsed_timer.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright 2013 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef BASE_TIMER_ELAPSED_TIMER_H_
|
||||
#define BASE_TIMER_ELAPSED_TIMER_H_
|
||||
|
||||
#include "base/base_export.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/time/time.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
// A simple wrapper around TimeTicks::Now().
|
||||
class BASE_EXPORT ElapsedTimer {
|
||||
public:
|
||||
ElapsedTimer();
|
||||
ElapsedTimer(ElapsedTimer&& other);
|
||||
|
||||
void operator=(ElapsedTimer&& other);
|
||||
|
||||
// Returns the time elapsed since object construction.
|
||||
TimeDelta Elapsed() const;
|
||||
|
||||
// Returns the timestamp of the creation of this timer.
|
||||
TimeTicks Begin() const { return begin_; }
|
||||
|
||||
private:
|
||||
TimeTicks begin_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ElapsedTimer);
|
||||
};
|
||||
|
||||
// A simple wrapper around ThreadTicks::Now().
|
||||
class BASE_EXPORT ElapsedThreadTimer {
|
||||
public:
|
||||
ElapsedThreadTimer();
|
||||
|
||||
// Returns the ThreadTicks time elapsed since object construction.
|
||||
// Only valid if |is_supported()| returns true, otherwise returns TimeDelta().
|
||||
TimeDelta Elapsed() const;
|
||||
|
||||
bool is_supported() const { return is_supported_; }
|
||||
|
||||
private:
|
||||
const bool is_supported_;
|
||||
const ThreadTicks begin_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ElapsedThreadTimer);
|
||||
};
|
||||
|
||||
// Whenever there's a ScopedMockElapsedTimersForTest in scope,
|
||||
// Elapsed(Thread)Timers will always return kMockElapsedTime from Elapsed().
|
||||
// This is useful, for example, in unit tests that verify that their impl
|
||||
// records timing histograms. It enables such tests to observe reliable timings.
|
||||
class BASE_EXPORT ScopedMockElapsedTimersForTest {
|
||||
public:
|
||||
static constexpr TimeDelta kMockElapsedTime =
|
||||
TimeDelta::FromMilliseconds(1337);
|
||||
|
||||
// ScopedMockElapsedTimersForTest is not thread-safe (it must be instantiated
|
||||
// in a test before other threads begin using ElapsedTimers; and it must
|
||||
// conversely outlive any usage of ElapsedTimer in that test).
|
||||
ScopedMockElapsedTimersForTest();
|
||||
~ScopedMockElapsedTimersForTest();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedMockElapsedTimersForTest);
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_TIMER_ELAPSED_TIMER_H_
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef BASE_TIMER_HI_RES_TIMER_MANAGER_H_
|
||||
#define BASE_TIMER_HI_RES_TIMER_MANAGER_H_
|
||||
|
||||
#include "base/base_export.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/power_monitor/power_observer.h"
|
||||
#include "base/timer/timer.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
// Ensures that the Windows high resolution timer is only used
|
||||
// when not running on battery power.
|
||||
class BASE_EXPORT HighResolutionTimerManager : public base::PowerObserver {
|
||||
public:
|
||||
HighResolutionTimerManager();
|
||||
~HighResolutionTimerManager() override;
|
||||
|
||||
// base::PowerObserver methods.
|
||||
void OnPowerStateChange(bool on_battery_power) override;
|
||||
void OnSuspend() override;
|
||||
void OnResume() override;
|
||||
|
||||
// Returns true if the hi resolution clock could be used right now.
|
||||
bool hi_res_clock_available() const { return hi_res_clock_available_; }
|
||||
|
||||
private:
|
||||
// Enable or disable the faster multimedia timer.
|
||||
void UseHiResClock(bool use);
|
||||
|
||||
bool hi_res_clock_available_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Timer for polling the high resolution timer usage.
|
||||
base::RepeatingTimer timer_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(HighResolutionTimerManager);
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_TIMER_HI_RES_TIMER_MANAGER_H_
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/timer/hi_res_timer_manager.h"
|
||||
|
||||
// On POSIX we don't need to do anything special with the system timer.
|
||||
|
||||
namespace base {
|
||||
|
||||
HighResolutionTimerManager::HighResolutionTimerManager()
|
||||
: hi_res_clock_available_(false) {
|
||||
}
|
||||
|
||||
HighResolutionTimerManager::~HighResolutionTimerManager() = default;
|
||||
|
||||
void HighResolutionTimerManager::OnPowerStateChange(bool on_battery_power) {
|
||||
}
|
||||
|
||||
void HighResolutionTimerManager::OnSuspend() {}
|
||||
|
||||
void HighResolutionTimerManager::OnResume() {}
|
||||
|
||||
void HighResolutionTimerManager::UseHiResClock(bool use) {
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/timer/hi_res_timer_manager.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/atomicops.h"
|
||||
#include "base/base_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/metrics/histogram_macros.h"
|
||||
#include "base/power_monitor/power_monitor.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/time/time.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr TimeDelta kUsageSampleInterval = TimeDelta::FromMinutes(10);
|
||||
|
||||
void ReportHighResolutionTimerUsage() {
|
||||
UMA_HISTOGRAM_PERCENTAGE("Windows.HighResolutionTimerUsage",
|
||||
Time::GetHighResolutionTimerUsage());
|
||||
// Reset usage for the next interval.
|
||||
Time::ResetHighResolutionTimerUsage();
|
||||
}
|
||||
|
||||
bool HighResolutionTimerAllowed() {
|
||||
return !CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kDisableHighResTimer);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
HighResolutionTimerManager::HighResolutionTimerManager()
|
||||
: hi_res_clock_available_(false) {
|
||||
// Register for PowerMonitor callbacks only if high-resolution
|
||||
// timers are allowed. If high-resolution timers are disabled
|
||||
// we won't receive power state change callbacks and
|
||||
// hi_res_clock_available_ will remain at its initial value.
|
||||
if (HighResolutionTimerAllowed()) {
|
||||
DCHECK(PowerMonitor::IsInitialized());
|
||||
PowerMonitor::AddObserver(this);
|
||||
UseHiResClock(!PowerMonitor::IsOnBatteryPower());
|
||||
|
||||
// Start polling the high resolution timer usage.
|
||||
Time::ResetHighResolutionTimerUsage();
|
||||
timer_.Start(FROM_HERE, kUsageSampleInterval,
|
||||
BindRepeating(&ReportHighResolutionTimerUsage));
|
||||
}
|
||||
}
|
||||
|
||||
HighResolutionTimerManager::~HighResolutionTimerManager() {
|
||||
if (HighResolutionTimerAllowed()) {
|
||||
PowerMonitor::RemoveObserver(this);
|
||||
UseHiResClock(false);
|
||||
}
|
||||
}
|
||||
|
||||
void HighResolutionTimerManager::OnPowerStateChange(bool on_battery_power) {
|
||||
DCHECK(HighResolutionTimerAllowed());
|
||||
UseHiResClock(!on_battery_power);
|
||||
}
|
||||
|
||||
void HighResolutionTimerManager::OnSuspend() {
|
||||
DCHECK(HighResolutionTimerAllowed());
|
||||
// Stop polling the usage to avoid including the standby time.
|
||||
timer_.Stop();
|
||||
}
|
||||
|
||||
void HighResolutionTimerManager::OnResume() {
|
||||
DCHECK(HighResolutionTimerAllowed());
|
||||
// Resume polling the usage.
|
||||
Time::ResetHighResolutionTimerUsage();
|
||||
timer_.Reset();
|
||||
}
|
||||
|
||||
void HighResolutionTimerManager::UseHiResClock(bool use) {
|
||||
DCHECK(HighResolutionTimerAllowed());
|
||||
if (use == hi_res_clock_available_)
|
||||
return;
|
||||
hi_res_clock_available_ = use;
|
||||
Time::EnableHighResolutionTimer(use);
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
118
TMessagesProj/jni/voip/webrtc/base/timer/lap_timer.cc
Normal file
118
TMessagesProj/jni/voip/webrtc/base/timer/lap_timer.cc
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/timer/lap_timer.h"
|
||||
#include "base/logging.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
namespace {
|
||||
|
||||
// Default values.
|
||||
constexpr TimeDelta kDefaultTimeLimit = TimeDelta::FromSeconds(3);
|
||||
constexpr int kDefaultWarmupRuns = 5;
|
||||
constexpr int kDefaultTimeCheckInterval = 10;
|
||||
|
||||
} // namespace
|
||||
|
||||
LapTimer::LapTimer(int warmup_laps,
|
||||
TimeDelta time_limit,
|
||||
int check_interval,
|
||||
LapTimer::TimerMethod method)
|
||||
: warmup_laps_(warmup_laps),
|
||||
time_limit_(time_limit),
|
||||
check_interval_(check_interval),
|
||||
method_(method) {
|
||||
DETACH_FROM_SEQUENCE(sequence_checker_);
|
||||
DCHECK_GT(check_interval, 0);
|
||||
Reset();
|
||||
}
|
||||
|
||||
LapTimer::LapTimer(LapTimer::TimerMethod method)
|
||||
: LapTimer(kDefaultWarmupRuns,
|
||||
kDefaultTimeLimit,
|
||||
kDefaultTimeCheckInterval,
|
||||
method) {}
|
||||
|
||||
void LapTimer::Reset() {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
if (ThreadTicks::IsSupported() && method_ == TimerMethod::kUseThreadTicks)
|
||||
ThreadTicks::WaitUntilInitialized();
|
||||
num_laps_ = 0;
|
||||
remaining_warmups_ = warmup_laps_;
|
||||
remaining_no_check_laps_ = check_interval_;
|
||||
Start();
|
||||
}
|
||||
|
||||
void LapTimer::Start() {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
DCHECK_EQ(num_laps_, 0);
|
||||
// last_timed_ variables are initialized here (instead of in the constructor)
|
||||
// because not all platforms support ThreadTicks.
|
||||
if (method_ == TimerMethod::kUseThreadTicks) {
|
||||
start_thread_ticks_ = ThreadTicks::Now();
|
||||
last_timed_lap_end_thread_ticks_ = ThreadTicks::Now();
|
||||
} else {
|
||||
start_time_ticks_ = TimeTicks::Now();
|
||||
last_timed_lap_end_ticks_ = TimeTicks::Now();
|
||||
}
|
||||
}
|
||||
|
||||
bool LapTimer::IsWarmedUp() const {
|
||||
return remaining_warmups_ <= 0;
|
||||
}
|
||||
|
||||
void LapTimer::NextLap() {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
DCHECK(!start_thread_ticks_.is_null() || !start_time_ticks_.is_null());
|
||||
if (!IsWarmedUp()) {
|
||||
--remaining_warmups_;
|
||||
if (IsWarmedUp()) {
|
||||
Start();
|
||||
}
|
||||
return;
|
||||
}
|
||||
++num_laps_;
|
||||
--remaining_no_check_laps_;
|
||||
if (!remaining_no_check_laps_) {
|
||||
if (method_ == TimerMethod::kUseTimeTicks) {
|
||||
last_timed_lap_end_ticks_ = TimeTicks::Now();
|
||||
} else {
|
||||
last_timed_lap_end_thread_ticks_ = ThreadTicks::Now();
|
||||
}
|
||||
remaining_no_check_laps_ = check_interval_;
|
||||
}
|
||||
}
|
||||
|
||||
TimeDelta LapTimer::GetAccumulatedTime() const {
|
||||
if (method_ == TimerMethod::kUseTimeTicks) {
|
||||
return last_timed_lap_end_ticks_ - start_time_ticks_;
|
||||
}
|
||||
return last_timed_lap_end_thread_ticks_ - start_thread_ticks_;
|
||||
}
|
||||
|
||||
bool LapTimer::HasTimeLimitExpired() const {
|
||||
return GetAccumulatedTime() >= time_limit_;
|
||||
}
|
||||
|
||||
bool LapTimer::HasTimedAllLaps() const {
|
||||
return num_laps_ && !(num_laps_ % check_interval_);
|
||||
}
|
||||
|
||||
TimeDelta LapTimer::TimePerLap() const {
|
||||
DCHECK(HasTimedAllLaps());
|
||||
DCHECK_GT(num_laps_, 0);
|
||||
return GetAccumulatedTime() / num_laps_;
|
||||
}
|
||||
|
||||
float LapTimer::LapsPerSecond() const {
|
||||
DCHECK(HasTimedAllLaps());
|
||||
DCHECK_GT(num_laps_, 0);
|
||||
return num_laps_ / GetAccumulatedTime().InSecondsF();
|
||||
}
|
||||
|
||||
int LapTimer::NumLaps() const {
|
||||
return num_laps_;
|
||||
}
|
||||
} // namespace base
|
||||
83
TMessagesProj/jni/voip/webrtc/base/timer/mock_timer.cc
Normal file
83
TMessagesProj/jni/voip/webrtc/base/timer/mock_timer.cc
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/timer/mock_timer.h"
|
||||
|
||||
#include "base/test/test_simple_task_runner.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
namespace {
|
||||
|
||||
void FlushPendingTasks(TestSimpleTaskRunner* task_runner) {
|
||||
// Do not use TestSimpleTaskRunner::RunPendingTasks() here. As RunPendingTasks
|
||||
// overrides ThreadTaskRunnerHandle when it runs tasks, tasks posted by timer
|
||||
// tasks to TTRH go to |test_task_runner_|, though they should be posted to
|
||||
// the original task runner.
|
||||
// Do not use TestSimpleTaskRunner::RunPendingTasks(), as its overridden
|
||||
// ThreadTaskRunnerHandle causes unexpected side effects.
|
||||
for (TestPendingTask& task : task_runner->TakePendingTasks())
|
||||
std::move(task.task).Run();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MockOneShotTimer::MockOneShotTimer()
|
||||
: OneShotTimer(&clock_),
|
||||
test_task_runner_(MakeRefCounted<TestSimpleTaskRunner>()) {
|
||||
OneShotTimer::SetTaskRunner(test_task_runner_);
|
||||
}
|
||||
|
||||
MockOneShotTimer::~MockOneShotTimer() = default;
|
||||
|
||||
void MockOneShotTimer::SetTaskRunner(
|
||||
scoped_refptr<SequencedTaskRunner> task_runner) {
|
||||
NOTREACHED() << "MockOneShotTimer doesn't support SetTaskRunner().";
|
||||
}
|
||||
|
||||
void MockOneShotTimer::Fire() {
|
||||
DCHECK(IsRunning());
|
||||
clock_.Advance(std::max(TimeDelta(), desired_run_time() - clock_.NowTicks()));
|
||||
FlushPendingTasks(test_task_runner_.get());
|
||||
}
|
||||
|
||||
MockRepeatingTimer::MockRepeatingTimer()
|
||||
: RepeatingTimer(&clock_),
|
||||
test_task_runner_(MakeRefCounted<TestSimpleTaskRunner>()) {
|
||||
RepeatingTimer::SetTaskRunner(test_task_runner_);
|
||||
}
|
||||
|
||||
MockRepeatingTimer::~MockRepeatingTimer() = default;
|
||||
|
||||
void MockRepeatingTimer::SetTaskRunner(
|
||||
scoped_refptr<SequencedTaskRunner> task_runner) {
|
||||
NOTREACHED() << "MockRepeatingTimer doesn't support SetTaskRunner().";
|
||||
}
|
||||
|
||||
void MockRepeatingTimer::Fire() {
|
||||
DCHECK(IsRunning());
|
||||
clock_.Advance(std::max(TimeDelta(), desired_run_time() - clock_.NowTicks()));
|
||||
FlushPendingTasks(test_task_runner_.get());
|
||||
}
|
||||
|
||||
MockRetainingOneShotTimer::MockRetainingOneShotTimer()
|
||||
: RetainingOneShotTimer(&clock_),
|
||||
test_task_runner_(MakeRefCounted<TestSimpleTaskRunner>()) {
|
||||
RetainingOneShotTimer::SetTaskRunner(test_task_runner_);
|
||||
}
|
||||
|
||||
MockRetainingOneShotTimer::~MockRetainingOneShotTimer() = default;
|
||||
|
||||
void MockRetainingOneShotTimer::SetTaskRunner(
|
||||
scoped_refptr<SequencedTaskRunner> task_runner) {
|
||||
NOTREACHED() << "MockRetainingOneShotTimer doesn't support SetTaskRunner().";
|
||||
}
|
||||
|
||||
void MockRetainingOneShotTimer::Fire() {
|
||||
DCHECK(IsRunning());
|
||||
clock_.Advance(std::max(TimeDelta(), desired_run_time() - clock_.NowTicks()));
|
||||
FlushPendingTasks(test_task_runner_.get());
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
76
TMessagesProj/jni/voip/webrtc/base/timer/mock_timer.h
Normal file
76
TMessagesProj/jni/voip/webrtc/base/timer/mock_timer.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef BASE_TIMER_MOCK_TIMER_H_
|
||||
#define BASE_TIMER_MOCK_TIMER_H_
|
||||
|
||||
#include "base/test/simple_test_tick_clock.h"
|
||||
#include "base/timer/timer.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
class TestSimpleTaskRunner;
|
||||
|
||||
// A mock implementation of base::OneShotTimer which requires being explicitly
|
||||
// Fire()'d.
|
||||
// Prefer using TaskEnvironment::MOCK_TIME + FastForward*() to this when
|
||||
// possible.
|
||||
class MockOneShotTimer : public OneShotTimer {
|
||||
public:
|
||||
MockOneShotTimer();
|
||||
~MockOneShotTimer() override;
|
||||
|
||||
// Testing method.
|
||||
void Fire();
|
||||
|
||||
private:
|
||||
// Timer implementation.
|
||||
// MockOneShotTimer doesn't support SetTaskRunner. Do not use this.
|
||||
void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) override;
|
||||
|
||||
SimpleTestTickClock clock_;
|
||||
scoped_refptr<TestSimpleTaskRunner> test_task_runner_;
|
||||
};
|
||||
|
||||
// See MockOneShotTimer's comment. Prefer using
|
||||
// TaskEnvironment::MOCK_TIME.
|
||||
class MockRepeatingTimer : public RepeatingTimer {
|
||||
public:
|
||||
MockRepeatingTimer();
|
||||
~MockRepeatingTimer() override;
|
||||
|
||||
// Testing method.
|
||||
void Fire();
|
||||
|
||||
private:
|
||||
// Timer implementation.
|
||||
// MockRepeatingTimer doesn't support SetTaskRunner. Do not use this.
|
||||
void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) override;
|
||||
|
||||
SimpleTestTickClock clock_;
|
||||
scoped_refptr<TestSimpleTaskRunner> test_task_runner_;
|
||||
};
|
||||
|
||||
// See MockOneShotTimer's comment. Prefer using
|
||||
// TaskEnvironment::MOCK_TIME.
|
||||
class MockRetainingOneShotTimer : public RetainingOneShotTimer {
|
||||
public:
|
||||
MockRetainingOneShotTimer();
|
||||
~MockRetainingOneShotTimer() override;
|
||||
|
||||
// Testing method.
|
||||
void Fire();
|
||||
|
||||
private:
|
||||
// Timer implementation.
|
||||
// MockRetainingOneShotTimer doesn't support SetTaskRunner. Do not use this.
|
||||
void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) override;
|
||||
|
||||
SimpleTestTickClock clock_;
|
||||
scoped_refptr<TestSimpleTaskRunner> test_task_runner_;
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_TIMER_MOCK_TIMER_H_
|
||||
335
TMessagesProj/jni/voip/webrtc/base/timer/timer.cc
Normal file
335
TMessagesProj/jni/voip/webrtc/base/timer/timer.cc
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/timer/timer.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/threading/platform_thread.h"
|
||||
#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "base/time/tick_clock.h"
|
||||
|
||||
namespace base {
|
||||
namespace internal {
|
||||
|
||||
// BaseTimerTaskInternal is a simple delegate for scheduling a callback to Timer
|
||||
// on the current sequence. It also handles the following edge cases:
|
||||
// - deleted by the task runner.
|
||||
// - abandoned (orphaned) by Timer.
|
||||
class BaseTimerTaskInternal {
|
||||
public:
|
||||
explicit BaseTimerTaskInternal(TimerBase* timer) : timer_(timer) {}
|
||||
|
||||
~BaseTimerTaskInternal() {
|
||||
// This task may be getting cleared because the task runner has been
|
||||
// destructed. If so, don't leave Timer with a dangling pointer
|
||||
// to this.
|
||||
if (timer_)
|
||||
timer_->AbandonAndStop();
|
||||
}
|
||||
|
||||
void Run() {
|
||||
// |timer_| is nullptr if we were abandoned.
|
||||
if (!timer_)
|
||||
return;
|
||||
|
||||
// |this| will be deleted by the task runner, so Timer needs to forget us:
|
||||
timer_->scheduled_task_ = nullptr;
|
||||
|
||||
// Although Timer should not call back into |this|, let's clear |timer_|
|
||||
// first to be pedantic.
|
||||
TimerBase* timer = timer_;
|
||||
timer_ = nullptr;
|
||||
timer->RunScheduledTask();
|
||||
}
|
||||
|
||||
// The task remains in the queue, but nothing will happen when it runs.
|
||||
void Abandon() { timer_ = nullptr; }
|
||||
|
||||
private:
|
||||
TimerBase* timer_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BaseTimerTaskInternal);
|
||||
};
|
||||
|
||||
TimerBase::TimerBase() : TimerBase(nullptr) {}
|
||||
|
||||
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
|
||||
// later calls will verify that the same task runner is used.
|
||||
origin_sequence_checker_.DetachFromSequence();
|
||||
}
|
||||
|
||||
TimerBase::TimerBase(const Location& posted_from, TimeDelta delay)
|
||||
: TimerBase(posted_from, delay, nullptr) {}
|
||||
|
||||
TimerBase::TimerBase(const Location& posted_from,
|
||||
TimeDelta delay,
|
||||
const TickClock* tick_clock)
|
||||
: scheduled_task_(nullptr),
|
||||
posted_from_(posted_from),
|
||||
delay_(delay),
|
||||
tick_clock_(tick_clock),
|
||||
is_running_(false) {
|
||||
// See comment in other constructor.
|
||||
origin_sequence_checker_.DetachFromSequence();
|
||||
}
|
||||
|
||||
TimerBase::~TimerBase() {
|
||||
DCHECK(origin_sequence_checker_.CalledOnValidSequence());
|
||||
AbandonScheduledTask();
|
||||
}
|
||||
|
||||
bool TimerBase::IsRunning() const {
|
||||
DCHECK(origin_sequence_checker_.CalledOnValidSequence());
|
||||
return is_running_;
|
||||
}
|
||||
|
||||
TimeDelta TimerBase::GetCurrentDelay() const {
|
||||
DCHECK(origin_sequence_checker_.CalledOnValidSequence());
|
||||
return delay_;
|
||||
}
|
||||
|
||||
void TimerBase::SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) {
|
||||
DCHECK(origin_sequence_checker_.CalledOnValidSequence());
|
||||
DCHECK(task_runner->RunsTasksInCurrentSequence());
|
||||
DCHECK(!IsRunning());
|
||||
task_runner_.swap(task_runner);
|
||||
}
|
||||
|
||||
void TimerBase::StartInternal(const Location& posted_from, TimeDelta delay) {
|
||||
DCHECK(origin_sequence_checker_.CalledOnValidSequence());
|
||||
|
||||
posted_from_ = posted_from;
|
||||
delay_ = delay;
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void TimerBase::Stop() {
|
||||
// TODO(gab): Enable this when it's no longer called racily from
|
||||
// RunScheduledTask(): https://crbug.com/587199.
|
||||
// DCHECK(origin_sequence_checker_.CalledOnValidSequence());
|
||||
|
||||
is_running_ = false;
|
||||
|
||||
// It's safe to destroy or restart Timer on another sequence after Stop().
|
||||
origin_sequence_checker_.DetachFromSequence();
|
||||
|
||||
OnStop();
|
||||
// No more member accesses here: |this| could be deleted after Stop() call.
|
||||
}
|
||||
|
||||
void TimerBase::Reset() {
|
||||
DCHECK(origin_sequence_checker_.CalledOnValidSequence());
|
||||
|
||||
// If there's no pending task, start one up and return.
|
||||
if (!scheduled_task_) {
|
||||
PostNewScheduledTask(delay_);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the new |desired_run_time_|.
|
||||
if (delay_ > TimeDelta::FromMicroseconds(0))
|
||||
desired_run_time_ = Now() + delay_;
|
||||
else
|
||||
desired_run_time_ = TimeTicks();
|
||||
|
||||
// We can use the existing scheduled task if it arrives before the new
|
||||
// |desired_run_time_|.
|
||||
if (desired_run_time_ >= scheduled_run_time_) {
|
||||
is_running_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// We can't reuse the |scheduled_task_|, so abandon it and post a new one.
|
||||
AbandonScheduledTask();
|
||||
PostNewScheduledTask(delay_);
|
||||
}
|
||||
|
||||
TimeTicks TimerBase::Now() const {
|
||||
// TODO(gab): Enable this when it's no longer called racily from
|
||||
// RunScheduledTask(): https://crbug.com/587199.
|
||||
// DCHECK(origin_sequence_checker_.CalledOnValidSequence());
|
||||
return tick_clock_ ? tick_clock_->NowTicks() : TimeTicks::Now();
|
||||
}
|
||||
|
||||
void TimerBase::PostNewScheduledTask(TimeDelta delay) {
|
||||
// TODO(gab): Enable this when it's no longer called racily from
|
||||
// RunScheduledTask(): https://crbug.com/587199.
|
||||
// DCHECK(origin_sequence_checker_.CalledOnValidSequence());
|
||||
DCHECK(!scheduled_task_);
|
||||
is_running_ = true;
|
||||
scheduled_task_ = new BaseTimerTaskInternal(this);
|
||||
if (delay > TimeDelta::FromMicroseconds(0)) {
|
||||
// TODO(gab): Posting BaseTimerTaskInternal::Run to another sequence makes
|
||||
// this code racy. https://crbug.com/587199
|
||||
GetTaskRunner()->PostDelayedTask(
|
||||
posted_from_,
|
||||
BindOnce(&BaseTimerTaskInternal::Run, Owned(scheduled_task_)), delay);
|
||||
scheduled_run_time_ = desired_run_time_ = Now() + delay;
|
||||
} else {
|
||||
GetTaskRunner()->PostTask(
|
||||
posted_from_,
|
||||
BindOnce(&BaseTimerTaskInternal::Run, Owned(scheduled_task_)));
|
||||
scheduled_run_time_ = desired_run_time_ = TimeTicks();
|
||||
}
|
||||
}
|
||||
|
||||
scoped_refptr<SequencedTaskRunner> TimerBase::GetTaskRunner() {
|
||||
return task_runner_.get() ? task_runner_ : SequencedTaskRunnerHandle::Get();
|
||||
}
|
||||
|
||||
void TimerBase::AbandonScheduledTask() {
|
||||
// TODO(gab): Enable this when it's no longer called racily from
|
||||
// RunScheduledTask() -> Stop(): https://crbug.com/587199.
|
||||
// DCHECK(origin_sequence_checker_.CalledOnValidSequence());
|
||||
if (scheduled_task_) {
|
||||
scheduled_task_->Abandon();
|
||||
scheduled_task_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerBase::RunScheduledTask() {
|
||||
// TODO(gab): Enable this when it's no longer called racily:
|
||||
// https://crbug.com/587199.
|
||||
// DCHECK(origin_sequence_checker_.CalledOnValidSequence());
|
||||
|
||||
// Task may have been disabled.
|
||||
if (!is_running_)
|
||||
return;
|
||||
|
||||
// First check if we need to delay the task because of a new target time.
|
||||
if (desired_run_time_ > scheduled_run_time_) {
|
||||
// Now() can be expensive, so only call it if we know the user has changed
|
||||
// the |desired_run_time_|.
|
||||
TimeTicks now = Now();
|
||||
// Task runner may have called us late anyway, so only post a continuation
|
||||
// task if the |desired_run_time_| is in the future.
|
||||
if (desired_run_time_ > now) {
|
||||
// Post a new task to span the remaining time.
|
||||
PostNewScheduledTask(desired_run_time_ - now);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
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(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
|
||||
Loading…
Add table
Add a link
Reference in a new issue