Adding R/W lock to SimulatedClock

This change makes the SimulatedClock class thread safe.

R=mflodman@webrtc.org, stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/15569004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6251 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/system_wrappers/interface/clock.h b/webrtc/system_wrappers/interface/clock.h
index ce32691..38ce0d5 100644
--- a/webrtc/system_wrappers/interface/clock.h
+++ b/webrtc/system_wrappers/interface/clock.h
@@ -11,10 +11,14 @@
 #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CLOCK_H_
 #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CLOCK_H_
 
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+#include "webrtc/system_wrappers/interface/thread_annotations.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
 
+class RWLockWrapper;
+
 // January 1970, in NTP seconds.
 const uint32_t kNtpJan1970 = 2208988800UL;
 
@@ -51,7 +55,7 @@
  public:
   explicit SimulatedClock(int64_t initial_time_us);
 
-  virtual ~SimulatedClock() {}
+  virtual ~SimulatedClock();
 
   // Return a timestamp in milliseconds relative to some arbitrary source; the
   // source is fixed for this clock.
@@ -73,7 +77,8 @@
   void AdvanceTimeMicroseconds(int64_t microseconds);
 
  private:
-  int64_t time_us_;
+  int64_t time_us_ GUARDED_BY(lock_);
+  scoped_ptr<RWLockWrapper> lock_;
 };
 
 };  // namespace webrtc
diff --git a/webrtc/system_wrappers/source/clock.cc b/webrtc/system_wrappers/source/clock.cc
index b101e05..b341a5f 100644
--- a/webrtc/system_wrappers/source/clock.cc
+++ b/webrtc/system_wrappers/source/clock.cc
@@ -20,6 +20,7 @@
 #include <time.h>
 #endif
 
+#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
 #include "webrtc/system_wrappers/interface/tick_util.h"
 
 namespace webrtc {
@@ -143,20 +144,27 @@
 }
 
 SimulatedClock::SimulatedClock(int64_t initial_time_us)
-    : time_us_(initial_time_us) {}
+    : time_us_(initial_time_us), lock_(RWLockWrapper::CreateRWLock()) {
+}
+
+SimulatedClock::~SimulatedClock() {
+}
 
 int64_t SimulatedClock::TimeInMilliseconds() {
+  ReadLockScoped synchronize(*lock_);
   return (time_us_ + 500) / 1000;
 }
 
 int64_t SimulatedClock::TimeInMicroseconds() {
+  ReadLockScoped synchronize(*lock_);
   return time_us_;
 }
 
 void SimulatedClock::CurrentNtp(uint32_t& seconds, uint32_t& fractions) {
-  seconds = (TimeInMilliseconds() / 1000) + kNtpJan1970;
-  fractions = (uint32_t)((TimeInMilliseconds() % 1000) *
-      kMagicNtpFractionalUnit / 1000);
+  int64_t now_ms = TimeInMilliseconds();
+  seconds = (now_ms / 1000) + kNtpJan1970;
+  fractions =
+      static_cast<uint32_t>((now_ms % 1000) * kMagicNtpFractionalUnit / 1000);
 }
 
 int64_t SimulatedClock::CurrentNtpInMilliseconds() {
@@ -168,6 +176,7 @@
 }
 
 void SimulatedClock::AdvanceTimeMicroseconds(int64_t microseconds) {
+  WriteLockScoped synchronize(*lock_);
   time_us_ += microseconds;
 }