diff --git a/webrtc/base/criticalsection.h b/webrtc/base/criticalsection.h index 1c582b89c..0fa91bb99 100644 --- a/webrtc/base/criticalsection.h +++ b/webrtc/base/criticalsection.h @@ -152,19 +152,26 @@ class AtomicOps { public: #if defined(WEBRTC_WIN) // Assumes sizeof(int) == sizeof(LONG), which it is on Win32 and Win64. - static int Increment(int* i) { - return ::InterlockedIncrement(reinterpret_cast(i)); + static int Increment(volatile int* i) { + return ::InterlockedIncrement(reinterpret_cast(i)); } - static int Decrement(int* i) { - return ::InterlockedDecrement(reinterpret_cast(i)); + static int Decrement(volatile int* i) { + return ::InterlockedDecrement(reinterpret_cast(i)); + } + static int Load(volatile const int* i) { + return *i; } #else - static int Increment(int* i) { + static int Increment(volatile int* i) { return __sync_add_and_fetch(i, 1); } - static int Decrement(int* i) { + static int Decrement(volatile int* i) { return __sync_sub_and_fetch(i, 1); } + static int Load(volatile const int* i) { + // Adding 0 is a no-op, so const_cast is fine. + return __sync_add_and_fetch(const_cast(i), 0); + } #endif }; diff --git a/webrtc/base/refcount.h b/webrtc/base/refcount.h index 7bb6da36a..eb097334f 100644 --- a/webrtc/base/refcount.h +++ b/webrtc/base/refcount.h @@ -66,11 +66,21 @@ class RefCountedObject : public T { return count; } + // Return whether the reference count is one. If the reference count is used + // in the conventional way, a reference count of 1 implies that the current + // thread owns the reference and no other thread shares it. This call + // performs the test for a reference count of one, and performs the memory + // barrier needed for the owning thread to act on the object, knowing that it + // has exclusive access to the object. + virtual bool HasOneRef() const { + return rtc::AtomicOps::Load(&ref_count_) == 1; + } + protected: virtual ~RefCountedObject() { } - int ref_count_; + volatile int ref_count_; }; } // namespace rtc