Makes Clock interface fully mutable.

Calls to the time functions in Clock can have side effects in some
circumstances. It's also questionable if it's a good idea to allow
repeated calls to a const method return different values without
any changed to the class instance.

Bug: webrtc:10270
Change-Id: I316f9788adac954c52b0f9230881b872c54a7ac9
Reviewed-on: https://webrtc-review.googlesource.com/c/120348
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26482}
This commit is contained in:
Sebastian Jansson 2019-01-30 20:44:45 +01:00 committed by Commit Bot
parent 7e0ae16c73
commit 2a96ab20b2
4 changed files with 32 additions and 33 deletions

View File

@ -32,17 +32,17 @@ class Clock {
// Return a timestamp in milliseconds relative to some arbitrary source; the // Return a timestamp in milliseconds relative to some arbitrary source; the
// source is fixed for this clock. // source is fixed for this clock.
virtual int64_t TimeInMilliseconds() const = 0; virtual int64_t TimeInMilliseconds() = 0;
// Return a timestamp in microseconds relative to some arbitrary source; the // Return a timestamp in microseconds relative to some arbitrary source; the
// source is fixed for this clock. // source is fixed for this clock.
virtual int64_t TimeInMicroseconds() const = 0; virtual int64_t TimeInMicroseconds() = 0;
// Retrieve an NTP absolute timestamp. // Retrieve an NTP absolute timestamp.
virtual NtpTime CurrentNtpTime() const = 0; virtual NtpTime CurrentNtpTime() = 0;
// Retrieve an NTP absolute timestamp in milliseconds. // Retrieve an NTP absolute timestamp in milliseconds.
virtual int64_t CurrentNtpInMilliseconds() const = 0; virtual int64_t CurrentNtpInMilliseconds() = 0;
// Converts an NTP timestamp to a millisecond timestamp. // Converts an NTP timestamp to a millisecond timestamp.
static int64_t NtpToMs(uint32_t seconds, uint32_t fractions) { static int64_t NtpToMs(uint32_t seconds, uint32_t fractions) {
@ -61,17 +61,17 @@ class SimulatedClock : public Clock {
// Return a timestamp in milliseconds relative to some arbitrary source; the // Return a timestamp in milliseconds relative to some arbitrary source; the
// source is fixed for this clock. // source is fixed for this clock.
int64_t TimeInMilliseconds() const override; int64_t TimeInMilliseconds() override;
// Return a timestamp in microseconds relative to some arbitrary source; the // Return a timestamp in microseconds relative to some arbitrary source; the
// source is fixed for this clock. // source is fixed for this clock.
int64_t TimeInMicroseconds() const override; int64_t TimeInMicroseconds() override;
// Retrieve an NTP absolute timestamp. // Retrieve an NTP absolute timestamp.
NtpTime CurrentNtpTime() const override; NtpTime CurrentNtpTime() override;
// Converts an NTP timestamp to a millisecond timestamp. // Converts an NTP timestamp to a millisecond timestamp.
int64_t CurrentNtpInMilliseconds() const override; int64_t CurrentNtpInMilliseconds() override;
// Advance the simulated clock with a given number of milliseconds or // Advance the simulated clock with a given number of milliseconds or
// microseconds. // microseconds.

View File

@ -34,14 +34,14 @@ namespace webrtc {
class RealTimeClock : public Clock { class RealTimeClock : public Clock {
// Return a timestamp in milliseconds relative to some arbitrary source; the // Return a timestamp in milliseconds relative to some arbitrary source; the
// source is fixed for this clock. // source is fixed for this clock.
int64_t TimeInMilliseconds() const override { return rtc::TimeMillis(); } int64_t TimeInMilliseconds() override { return rtc::TimeMillis(); }
// Return a timestamp in microseconds relative to some arbitrary source; the // Return a timestamp in microseconds relative to some arbitrary source; the
// source is fixed for this clock. // source is fixed for this clock.
int64_t TimeInMicroseconds() const override { return rtc::TimeMicros(); } int64_t TimeInMicroseconds() override { return rtc::TimeMicros(); }
// Retrieve an NTP absolute timestamp. // Retrieve an NTP absolute timestamp.
NtpTime CurrentNtpTime() const override { NtpTime CurrentNtpTime() override {
timeval tv = CurrentTimeVal(); timeval tv = CurrentTimeVal();
double microseconds_in_seconds; double microseconds_in_seconds;
uint32_t seconds; uint32_t seconds;
@ -52,7 +52,7 @@ class RealTimeClock : public Clock {
} }
// Retrieve an NTP absolute timestamp in milliseconds. // Retrieve an NTP absolute timestamp in milliseconds.
int64_t CurrentNtpInMilliseconds() const override { int64_t CurrentNtpInMilliseconds() override {
timeval tv = CurrentTimeVal(); timeval tv = CurrentTimeVal();
uint32_t seconds; uint32_t seconds;
double microseconds_in_seconds; double microseconds_in_seconds;
@ -62,7 +62,7 @@ class RealTimeClock : public Clock {
} }
protected: protected:
virtual timeval CurrentTimeVal() const = 0; virtual timeval CurrentTimeVal() = 0;
static void Adjust(const timeval& tv, static void Adjust(const timeval& tv,
uint32_t* adjusted_s, uint32_t* adjusted_s,
@ -87,7 +87,7 @@ class WinUwpRealTimeClock final : public RealTimeClock {
~WinUwpRealTimeClock() override {} ~WinUwpRealTimeClock() override {}
protected: protected:
timeval CurrentTimeVal() const override { timeval CurrentTimeVal() override {
// The rtc::SystemTimeNanos() method is already time offset from a base // The rtc::SystemTimeNanos() method is already time offset from a base
// epoch value and might as be synchronized against an NTP time server as // epoch value and might as be synchronized against an NTP time server as
// an added bonus. // an added bonus.
@ -104,7 +104,7 @@ class WinUwpRealTimeClock final : public RealTimeClock {
#elif defined(WEBRTC_WIN) #elif defined(WEBRTC_WIN)
// TODO(pbos): Consider modifying the implementation to synchronize itself // TODO(pbos): Consider modifying the implementation to synchronize itself
// against system time (update ref_point_, make it non-const) periodically to // against system time (update ref_point_) periodically to
// prevent clock drift. // prevent clock drift.
class WindowsRealTimeClock : public RealTimeClock { class WindowsRealTimeClock : public RealTimeClock {
public: public:
@ -121,7 +121,7 @@ class WindowsRealTimeClock : public RealTimeClock {
LARGE_INTEGER counter_ms; LARGE_INTEGER counter_ms;
}; };
timeval CurrentTimeVal() const override { timeval CurrentTimeVal() override {
const uint64_t FILETIME_1970 = 0x019db1ded53e8000; const uint64_t FILETIME_1970 = 0x019db1ded53e8000;
FILETIME StartTime; FILETIME StartTime;
@ -143,7 +143,7 @@ class WindowsRealTimeClock : public RealTimeClock {
return tv; return tv;
} }
void GetTime(FILETIME* current_time) const { void GetTime(FILETIME* current_time) {
DWORD t; DWORD t;
LARGE_INTEGER elapsed_ms; LARGE_INTEGER elapsed_ms;
{ {
@ -197,10 +197,9 @@ class WindowsRealTimeClock : public RealTimeClock {
return ref; return ref;
} }
// mutable as time-accessing functions are const.
rtc::CriticalSection crit_; rtc::CriticalSection crit_;
mutable DWORD last_time_ms_; DWORD last_time_ms_;
mutable LONG num_timer_wraps_; LONG num_timer_wraps_;
const ReferencePoint ref_point_; const ReferencePoint ref_point_;
}; };
@ -212,7 +211,7 @@ class UnixRealTimeClock : public RealTimeClock {
~UnixRealTimeClock() override {} ~UnixRealTimeClock() override {}
protected: protected:
timeval CurrentTimeVal() const override { timeval CurrentTimeVal() override {
struct timeval tv; struct timeval tv;
struct timezone tz; struct timezone tz;
tz.tz_minuteswest = 0; tz.tz_minuteswest = 0;
@ -241,17 +240,17 @@ SimulatedClock::SimulatedClock(int64_t initial_time_us)
SimulatedClock::~SimulatedClock() {} SimulatedClock::~SimulatedClock() {}
int64_t SimulatedClock::TimeInMilliseconds() const { int64_t SimulatedClock::TimeInMilliseconds() {
ReadLockScoped synchronize(*lock_); ReadLockScoped synchronize(*lock_);
return (time_us_ + 500) / 1000; return (time_us_ + 500) / 1000;
} }
int64_t SimulatedClock::TimeInMicroseconds() const { int64_t SimulatedClock::TimeInMicroseconds() {
ReadLockScoped synchronize(*lock_); ReadLockScoped synchronize(*lock_);
return time_us_; return time_us_;
} }
NtpTime SimulatedClock::CurrentNtpTime() const { NtpTime SimulatedClock::CurrentNtpTime() {
int64_t now_ms = TimeInMilliseconds(); int64_t now_ms = TimeInMilliseconds();
uint32_t seconds = (now_ms / 1000) + kNtpJan1970; uint32_t seconds = (now_ms / 1000) + kNtpJan1970;
uint32_t fractions = uint32_t fractions =
@ -259,7 +258,7 @@ NtpTime SimulatedClock::CurrentNtpTime() const {
return NtpTime(seconds, fractions); return NtpTime(seconds, fractions);
} }
int64_t SimulatedClock::CurrentNtpInMilliseconds() const { int64_t SimulatedClock::CurrentNtpInMilliseconds() {
return TimeInMilliseconds() + 1000 * static_cast<int64_t>(kNtpJan1970); return TimeInMilliseconds() + 1000 * static_cast<int64_t>(kNtpJan1970);
} }

View File

@ -31,15 +31,15 @@ float DriftingClock::Drift() const {
return (now - start_time_) * drift_; return (now - start_time_) * drift_;
} }
int64_t DriftingClock::TimeInMilliseconds() const { int64_t DriftingClock::TimeInMilliseconds() {
return clock_->TimeInMilliseconds() + Drift() / 1000.; return clock_->TimeInMilliseconds() + Drift() / 1000.;
} }
int64_t DriftingClock::TimeInMicroseconds() const { int64_t DriftingClock::TimeInMicroseconds() {
return clock_->TimeInMicroseconds() + Drift(); return clock_->TimeInMicroseconds() + Drift();
} }
NtpTime DriftingClock::CurrentNtpTime() const { NtpTime DriftingClock::CurrentNtpTime() {
// NTP precision is 1/2^32 seconds, i.e. 2^32 ntp fractions = 1 second. // NTP precision is 1/2^32 seconds, i.e. 2^32 ntp fractions = 1 second.
const double kNtpFracPerMicroSecond = 4294.967296; // = 2^32 / 10^6 const double kNtpFracPerMicroSecond = 4294.967296; // = 2^32 / 10^6
@ -49,7 +49,7 @@ NtpTime DriftingClock::CurrentNtpTime() const {
return NtpTime(total_fractions); return NtpTime(total_fractions);
} }
int64_t DriftingClock::CurrentNtpInMilliseconds() const { int64_t DriftingClock::CurrentNtpInMilliseconds() {
return clock_->CurrentNtpInMilliseconds() + Drift() / 1000.; return clock_->CurrentNtpInMilliseconds() + Drift() / 1000.;
} }
} // namespace test } // namespace test

View File

@ -30,10 +30,10 @@ class DriftingClock : public Clock {
static float PercentsFaster(float percent) { return 1.0f + percent / 100.0f; } static float PercentsFaster(float percent) { return 1.0f + percent / 100.0f; }
static float PercentsSlower(float percent) { return 1.0f - percent / 100.0f; } static float PercentsSlower(float percent) { return 1.0f - percent / 100.0f; }
int64_t TimeInMilliseconds() const override; int64_t TimeInMilliseconds() override;
int64_t TimeInMicroseconds() const override; int64_t TimeInMicroseconds() override;
NtpTime CurrentNtpTime() const override; NtpTime CurrentNtpTime() override;
int64_t CurrentNtpInMilliseconds() const override; int64_t CurrentNtpInMilliseconds() override;
private: private:
float Drift() const; float Drift() const;