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<void> 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<const Foo>.

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}
This commit is contained in:
Magnus Jedvert 2015-10-12 15:50:43 +02:00
parent 7a975f75e7
commit 1b40a9a8af
8 changed files with 19 additions and 17 deletions

View File

@ -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) {}

View File

@ -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;
}

View File

@ -108,6 +108,7 @@ EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(F);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(RefCountedObject<RefCountInterface>);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(RefCountedObject<B>);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(RefCountedObject<C>);
EXPECT_IS_CAPTURED_AS_SCOPED_REFPTR(const RefCountedObject<RefCountInterface>);
TEST(BindTest, BindToMethod) {
MethodBindTester object = {0};

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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