From 1b40a9a8afe0d7b2244ad8dea19e8222fec3c207 Mon Sep 17 00:00:00 2001 From: Magnus Jedvert Date: Mon, 12 Oct 2015 15:50:43 +0200 Subject: [PATCH] RefCountInterface: Make AddRef() and Release() const This CL makes AddRef() and Release() const member methods and the refcount integer mutable. This is reasonable, because they only manage the lifetime of the object, and this is also how it's done in Chromium. The purpose is to be able to capture a const pointer in a scoped_refptr, which is currenty impossible. The practial problem this CL solves is this: void Foo::Bar() const {} rtc::Callback0 Foo::MakeClosure() const { return rtc::Bind(&Foo::Bar, this); } We currently capture |this| as const Foo*. With this CL, |this| will be captured as scoped_refptr. A test is also added in bind_unittest to check this behaviour. BUG=webrtc:5065 R=perkj@webrtc.org, tommi@webrtc.org Review URL: https://codereview.webrtc.org/1403683004 . Cr-Commit-Position: refs/heads/master@{#10253} --- talk/app/webrtc/dtmfsender_unittest.cc | 3 ++- talk/media/webrtc/fakewebrtcvideocapturemodule.h | 4 ++-- webrtc/base/bind_unittest.cc | 1 + webrtc/base/refcount.h | 10 +++++----- .../modules/audio_device/include/fake_audio_device.h | 4 ++-- webrtc/modules/interface/module.h | 4 ++-- .../video_capture/include/mock/mock_video_capture.h | 4 ++-- webrtc/system_wrappers/interface/ref_count.h | 6 +++--- 8 files changed, 19 insertions(+), 17 deletions(-) diff --git a/talk/app/webrtc/dtmfsender_unittest.cc b/talk/app/webrtc/dtmfsender_unittest.cc index f686aa2ccc..ba2e163f13 100644 --- a/talk/app/webrtc/dtmfsender_unittest.cc +++ b/talk/app/webrtc/dtmfsender_unittest.cc @@ -34,6 +34,7 @@ #include "talk/app/webrtc/audiotrack.h" #include "webrtc/base/gunit.h" #include "webrtc/base/logging.h" +#include "webrtc/base/refcount.h" #include "webrtc/base/timeutils.h" using webrtc::AudioTrackInterface; @@ -45,7 +46,7 @@ using webrtc::DtmfSenderObserverInterface; static const char kTestAudioLabel[] = "test_audio_track"; static const int kMaxWaitMs = 3000; -class FakeDtmfObserver : public DtmfSenderObserverInterface { +class FakeDtmfObserver : public DtmfSenderObserverInterface, RefCountInterface { public: FakeDtmfObserver() : completed_(false) {} diff --git a/talk/media/webrtc/fakewebrtcvideocapturemodule.h b/talk/media/webrtc/fakewebrtcvideocapturemodule.h index 3c515555e7..7540fcf1d4 100644 --- a/talk/media/webrtc/fakewebrtcvideocapturemodule.h +++ b/talk/media/webrtc/fakewebrtcvideocapturemodule.h @@ -101,8 +101,8 @@ class FakeWebRtcVideoCaptureModule : public webrtc::VideoCaptureModule { const webrtc::VideoCodec& codec) override { return NULL; // not implemented } - int32_t AddRef() override { return 0; } - int32_t Release() override { + int32_t AddRef() const override { return 0; } + int32_t Release() const override { delete this; return 0; } diff --git a/webrtc/base/bind_unittest.cc b/webrtc/base/bind_unittest.cc index d38729d9df..fa47d279f5 100644 --- a/webrtc/base/bind_unittest.cc +++ b/webrtc/base/bind_unittest.cc @@ -108,6 +108,7 @@ EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(F); EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(RefCountedObject); EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(RefCountedObject); EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(RefCountedObject); +EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(const RefCountedObject); TEST(BindTest, BindToMethod) { MethodBindTester object = {0}; diff --git a/webrtc/base/refcount.h b/webrtc/base/refcount.h index 49f3777bea..dbad2eba76 100644 --- a/webrtc/base/refcount.h +++ b/webrtc/base/refcount.h @@ -20,8 +20,8 @@ namespace rtc { // Reference count interface. class RefCountInterface { public: - virtual int AddRef() = 0; - virtual int Release() = 0; + virtual int AddRef() const = 0; + virtual int Release() const = 0; protected: virtual ~RefCountInterface() {} }; @@ -95,11 +95,11 @@ class RefCountedObject : public T { : T(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), ref_count_(0) { } - virtual int AddRef() { + int AddRef() const override { return AtomicOps::Increment(&ref_count_); } - virtual int Release() { + int Release() const override { int count = AtomicOps::Decrement(&ref_count_); if (!count) { delete this; @@ -121,7 +121,7 @@ class RefCountedObject : public T { virtual ~RefCountedObject() { } - volatile int ref_count_; + mutable volatile int ref_count_; }; } // namespace rtc diff --git a/webrtc/modules/audio_device/include/fake_audio_device.h b/webrtc/modules/audio_device/include/fake_audio_device.h index 4c0739a003..8b154794c7 100644 --- a/webrtc/modules/audio_device/include/fake_audio_device.h +++ b/webrtc/modules/audio_device/include/fake_audio_device.h @@ -16,8 +16,8 @@ class FakeAudioDeviceModule : public AudioDeviceModule { public: FakeAudioDeviceModule() {} virtual ~FakeAudioDeviceModule() {} - virtual int32_t AddRef() { return 0; } - virtual int32_t Release() { return 0; } + virtual int32_t AddRef() const { return 0; } + virtual int32_t Release() const { return 0; } virtual int32_t RegisterEventObserver(AudioDeviceObserver* eventCallback) { return 0; } diff --git a/webrtc/modules/interface/module.h b/webrtc/modules/interface/module.h index 529138de42..ffd3065a5c 100644 --- a/webrtc/modules/interface/module.h +++ b/webrtc/modules/interface/module.h @@ -64,13 +64,13 @@ class RefCountedModule : public Module { public: // Increase the reference count by one. // Returns the incremented reference count. - virtual int32_t AddRef() = 0; + virtual int32_t AddRef() const = 0; // Decrease the reference count by one. // Returns the decreased reference count. // Returns 0 if the last reference was just released. // When the reference count reaches 0 the object will self-destruct. - virtual int32_t Release() = 0; + virtual int32_t Release() const = 0; protected: ~RefCountedModule() override = default; diff --git a/webrtc/modules/video_capture/include/mock/mock_video_capture.h b/webrtc/modules/video_capture/include/mock/mock_video_capture.h index 0a15c445ed..c030c02aee 100644 --- a/webrtc/modules/video_capture/include/mock/mock_video_capture.h +++ b/webrtc/modules/video_capture/include/mock/mock_video_capture.h @@ -22,8 +22,8 @@ class MockVideoCaptureModule : public VideoCaptureModule { MOCK_METHOD0(Process, int32_t()); // from RefCountedModule - MOCK_METHOD0(AddRef, int32_t()); - MOCK_METHOD0(Release, int32_t()); + MOCK_CONST_METHOD0(AddRef, int32_t()); + MOCK_CONST_METHOD0(Release, int32_t()); // from VideoCaptureModule MOCK_METHOD1(RegisterCaptureDataCallback, diff --git a/webrtc/system_wrappers/interface/ref_count.h b/webrtc/system_wrappers/interface/ref_count.h index 68616662e9..bbf2c605e8 100644 --- a/webrtc/system_wrappers/interface/ref_count.h +++ b/webrtc/system_wrappers/interface/ref_count.h @@ -61,11 +61,11 @@ class RefCountImpl : public T { RefCountImpl(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : T(p1, p2, p3, p4, p5), ref_count_(0) {} - virtual int32_t AddRef() { + int32_t AddRef() const override { return ++ref_count_; } - virtual int32_t Release() { + int32_t Release() const override { int32_t ref_count; ref_count = --ref_count_; if (ref_count == 0) @@ -74,7 +74,7 @@ class RefCountImpl : public T { } protected: - Atomic32 ref_count_; + mutable Atomic32 ref_count_; }; } // namespace webrtc