New classes RefCounter and RefCountedBase.

Bug: webrtc:8270
Change-Id: Ibdab81b3fcbe6cba9ae24033f56c84b13c868b21
Reviewed-on: https://webrtc-review.googlesource.com/2684
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20386}
This commit is contained in:
Niels Möller
2017-10-23 11:22:30 +02:00
committed by Commit Bot
parent ccdfccaa6f
commit 9155e4986d
13 changed files with 135 additions and 45 deletions

View File

@ -262,6 +262,15 @@ rtc_source_set("optional") {
] ]
} }
rtc_source_set("refcountedbase") {
sources = [
"refcountedbase.h",
]
deps = [
"../rtc_base:rtc_base_approved",
]
}
rtc_source_set("libjingle_peerconnection_test_api") { rtc_source_set("libjingle_peerconnection_test_api") {
testonly = true testonly = true
sources = [ sources = [

43
api/refcountedbase.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright 2017 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef API_REFCOUNTEDBASE_H_
#define API_REFCOUNTEDBASE_H_
#include "rtc_base/constructormagic.h"
#include "rtc_base/refcount.h"
#include "rtc_base/refcounter.h"
namespace rtc {
class RefCountedBase {
public:
RefCountedBase() = default;
void AddRef() const { ref_count_.IncRef(); }
RefCountReleaseStatus Release() const {
const auto status = ref_count_.DecRef();
if (status == RefCountReleaseStatus::kDroppedLastRef) {
delete this;
}
return status;
}
protected:
virtual ~RefCountedBase() = default;
private:
mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
RTC_DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
};
} // namespace rtc
#endif // API_REFCOUNTEDBASE_H_

View File

@ -50,6 +50,7 @@ class AudioState final : public webrtc::AudioState {
ScopedVoEInterface<VoEBase> voe_base_; ScopedVoEInterface<VoEBase> voe_base_;
// Reference count; implementation copied from rtc::RefCountedObject. // Reference count; implementation copied from rtc::RefCountedObject.
// TODO(nisse): Use RefCountedObject or RefCountedBase instead.
mutable volatile int ref_count_ = 0; mutable volatile int ref_count_ = 0;
// Transports mixed audio from the mixer to the audio device and // Transports mixed audio from the mixer to the audio device and

View File

@ -337,6 +337,7 @@ rtc_static_library("desktop_capture_generic") {
deps = [ deps = [
":primitives", ":primitives",
"../..:webrtc_common", "../..:webrtc_common",
"../../api:refcountedbase",
"../../rtc_base:rtc_base", # TODO(kjellander): Cleanup in bugs.webrtc.org/3806. "../../rtc_base:rtc_base", # TODO(kjellander): Cleanup in bugs.webrtc.org/3806.
"../../system_wrappers", "../../system_wrappers",
"//third_party/libyuv", "//third_party/libyuv",

View File

@ -20,8 +20,7 @@ namespace webrtc {
static const int64_t kDisplayConfigurationEventTimeoutMs = 10 * 1000; static const int64_t kDisplayConfigurationEventTimeoutMs = 10 * 1000;
DesktopConfigurationMonitor::DesktopConfigurationMonitor() DesktopConfigurationMonitor::DesktopConfigurationMonitor()
: ref_count_(0), : display_configuration_capture_event_(EventWrapper::Create()) {
display_configuration_capture_event_(EventWrapper::Create()) {
CGError err = CGDisplayRegisterReconfigurationCallback( CGError err = CGDisplayRegisterReconfigurationCallback(
DesktopConfigurationMonitor::DisplaysReconfiguredCallback, this); DesktopConfigurationMonitor::DisplaysReconfiguredCallback, this);
if (err != kCGErrorSuccess) { if (err != kCGErrorSuccess) {

View File

@ -16,9 +16,9 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include "api/refcountedbase.h"
#include "modules/desktop_capture/mac/desktop_configuration.h" #include "modules/desktop_capture/mac/desktop_configuration.h"
#include "rtc_base/constructormagic.h" #include "rtc_base/constructormagic.h"
#include "system_wrappers/include/atomic32.h"
namespace webrtc { namespace webrtc {
@ -26,7 +26,7 @@ class EventWrapper;
// The class provides functions to synchronize capturing and display // The class provides functions to synchronize capturing and display
// reconfiguring across threads, and the up-to-date MacDesktopConfiguration. // reconfiguring across threads, and the up-to-date MacDesktopConfiguration.
class DesktopConfigurationMonitor { class DesktopConfigurationMonitor : public rtc::RefCountedBase {
public: public:
DesktopConfigurationMonitor(); DesktopConfigurationMonitor();
// Acquires a lock on the current configuration. // Acquires a lock on the current configuration.
@ -39,22 +39,16 @@ class DesktopConfigurationMonitor {
return desktop_configuration_; return desktop_configuration_;
} }
void AddRef() { ++ref_count_; } protected:
void Release() { ~DesktopConfigurationMonitor() override;
if (--ref_count_ == 0)
delete this;
}
private: private:
static void DisplaysReconfiguredCallback(CGDirectDisplayID display, static void DisplaysReconfiguredCallback(CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags, CGDisplayChangeSummaryFlags flags,
void *user_parameter); void *user_parameter);
~DesktopConfigurationMonitor();
void DisplaysReconfigured(CGDirectDisplayID display, void DisplaysReconfigured(CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags); CGDisplayChangeSummaryFlags flags);
Atomic32 ref_count_;
std::set<CGDirectDisplayID> reconfiguring_displays_; std::set<CGDirectDisplayID> reconfiguring_displays_;
MacDesktopConfiguration desktop_configuration_; MacDesktopConfiguration desktop_configuration_;
std::unique_ptr<EventWrapper> display_configuration_capture_event_; std::unique_ptr<EventWrapper> display_configuration_capture_event_;

View File

@ -141,7 +141,7 @@ bool IsChromeWindow(CGWindowID id) {
} // namespace } // namespace
FullScreenChromeWindowDetector::FullScreenChromeWindowDetector() FullScreenChromeWindowDetector::FullScreenChromeWindowDetector()
: ref_count_(0), last_update_time_ns_(0) {} : last_update_time_ns_(0) {}
FullScreenChromeWindowDetector::~FullScreenChromeWindowDetector() {} FullScreenChromeWindowDetector::~FullScreenChromeWindowDetector() {}

View File

@ -13,9 +13,9 @@
#include <ApplicationServices/ApplicationServices.h> #include <ApplicationServices/ApplicationServices.h>
#include "api/refcountedbase.h"
#include "modules/desktop_capture/desktop_capturer.h" #include "modules/desktop_capture/desktop_capturer.h"
#include "rtc_base/constructormagic.h" #include "rtc_base/constructormagic.h"
#include "system_wrappers/include/atomic32.h"
namespace webrtc { namespace webrtc {
@ -30,16 +30,10 @@ namespace webrtc {
// 3. The new window is full-screen. // 3. The new window is full-screen.
// 4. The new window didn't exist at least 500 millisecond ago. // 4. The new window didn't exist at least 500 millisecond ago.
class FullScreenChromeWindowDetector { class FullScreenChromeWindowDetector : public rtc::RefCountedBase {
public: public:
FullScreenChromeWindowDetector(); FullScreenChromeWindowDetector();
void AddRef() { ++ref_count_; }
void Release() {
if (--ref_count_ == 0)
delete this;
}
// Returns the full-screen window in place of the original window if all the // Returns the full-screen window in place of the original window if all the
// criteria are met, or kCGNullWindowID if no such window found. // criteria are met, or kCGNullWindowID if no such window found.
CGWindowID FindFullScreenWindow(CGWindowID original_window); CGWindowID FindFullScreenWindow(CGWindowID original_window);
@ -48,11 +42,10 @@ class FullScreenChromeWindowDetector {
// second. // second.
void UpdateWindowListIfNeeded(CGWindowID original_window); void UpdateWindowListIfNeeded(CGWindowID original_window);
protected:
~FullScreenChromeWindowDetector() override;
private: private:
~FullScreenChromeWindowDetector();
Atomic32 ref_count_;
// We cache the last two results of the window list, so // We cache the last two results of the window list, so
// |previous_window_list_| is taken at least 500ms before the next Capture() // |previous_window_list_| is taken at least 500ms before the next Capture()
// call. If we only save the last result, we may get false positive (i.e. // call. If we only save the last result, we may get false positive (i.e.

View File

@ -8,6 +8,8 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include <string.h>
#include <X11/extensions/Xcomposite.h> #include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xrender.h> #include <X11/extensions/Xrender.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>

View File

@ -16,9 +16,9 @@
#include <string> #include <string>
#include "api/refcountedbase.h"
#include "rtc_base/constructormagic.h" #include "rtc_base/constructormagic.h"
#include "rtc_base/scoped_ref_ptr.h" #include "rtc_base/scoped_ref_ptr.h"
#include "system_wrappers/include/atomic32.h"
// Including Xlib.h will involve evil defines (Bool, Status, True, False), which // Including Xlib.h will involve evil defines (Bool, Status, True, False), which
// easily conflict with other headers. // easily conflict with other headers.
@ -28,7 +28,7 @@ typedef union _XEvent XEvent;
namespace webrtc { namespace webrtc {
// A ref-counted object to store XDisplay connection. // A ref-counted object to store XDisplay connection.
class SharedXDisplay { class SharedXDisplay : public rtc::RefCountedBase {
public: public:
class XEventHandler { class XEventHandler {
public: public:
@ -51,12 +51,6 @@ class SharedXDisplay {
// DISPLAY). NULL is returned if X11 connection failed. // DISPLAY). NULL is returned if X11 connection failed.
static rtc::scoped_refptr<SharedXDisplay> CreateDefault(); static rtc::scoped_refptr<SharedXDisplay> CreateDefault();
void AddRef() { ++ref_count_; }
void Release() {
if (--ref_count_ == 0)
delete this;
}
Display* display() { return display_; } Display* display() { return display_; }
// Adds a new event |handler| for XEvent's of |type|. // Adds a new event |handler| for XEvent's of |type|.
@ -69,12 +63,12 @@ class SharedXDisplay {
// Processes pending XEvents, calling corresponding event handlers. // Processes pending XEvents, calling corresponding event handlers.
void ProcessPendingXEvents(); void ProcessPendingXEvents();
protected:
~SharedXDisplay() override;
private: private:
typedef std::map<int, std::vector<XEventHandler*> > EventHandlersMap; typedef std::map<int, std::vector<XEventHandler*> > EventHandlersMap;
~SharedXDisplay();
Atomic32 ref_count_;
Display* display_; Display* display_;
EventHandlersMap event_handlers_; EventHandlersMap event_handlers_;

View File

@ -167,6 +167,7 @@ rtc_source_set("rtc_base_approved_generic") {
"ratetracker.h", "ratetracker.h",
"refcount.h", "refcount.h",
"refcountedobject.h", "refcountedobject.h",
"refcounter.h",
"safe_compare.h", "safe_compare.h",
"safe_conversions.h", "safe_conversions.h",
"safe_conversions_impl.h", "safe_conversions_impl.h",

View File

@ -12,8 +12,9 @@
#include <utility> #include <utility>
#include "rtc_base/atomicops.h" #include "rtc_base/constructormagic.h"
#include "rtc_base/refcount.h" #include "rtc_base/refcount.h"
#include "rtc_base/refcounter.h"
namespace rtc { namespace rtc {
@ -31,14 +32,14 @@ class RefCountedObject : public T {
std::forward<P1>(p1), std::forward<P1>(p1),
std::forward<Args>(args)...) {} std::forward<Args>(args)...) {}
virtual void AddRef() const { AtomicOps::Increment(&ref_count_); } virtual void AddRef() const { ref_count_.IncRef(); }
virtual RefCountReleaseStatus Release() const { virtual RefCountReleaseStatus Release() const {
if (AtomicOps::Decrement(&ref_count_) == 0) { const auto status = ref_count_.DecRef();
if (status == RefCountReleaseStatus::kDroppedLastRef) {
delete this; delete this;
return RefCountReleaseStatus::kDroppedLastRef;
} }
return RefCountReleaseStatus::kOtherRefsRemained; return status;
} }
// Return whether the reference count is one. If the reference count is used // Return whether the reference count is one. If the reference count is used
@ -47,14 +48,14 @@ class RefCountedObject : public T {
// performs the test for a reference count of one, and performs the memory // 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 // barrier needed for the owning thread to act on the object, knowing that it
// has exclusive access to the object. // has exclusive access to the object.
virtual bool HasOneRef() const { virtual bool HasOneRef() const { return ref_count_.HasOneRef(); }
return AtomicOps::AcquireLoad(&ref_count_) == 1;
}
protected: protected:
virtual ~RefCountedObject() {} virtual ~RefCountedObject() {}
mutable volatile int ref_count_ = 0; mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
RTC_DISALLOW_COPY_AND_ASSIGN(RefCountedObject);
}; };
} // namespace rtc } // namespace rtc

52
rtc_base/refcounter.h Normal file
View File

@ -0,0 +1,52 @@
/*
* Copyright 2017 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef RTC_BASE_REFCOUNTER_H_
#define RTC_BASE_REFCOUNTER_H_
#include "rtc_base/atomicops.h"
#include "rtc_base/refcount.h"
namespace webrtc {
namespace webrtc_impl {
class RefCounter {
public:
explicit RefCounter(int ref_count) : ref_count_(ref_count) {}
RefCounter() = delete;
void IncRef() { rtc::AtomicOps::Increment(&ref_count_); }
// TODO(nisse): Switch return type to RefCountReleaseStatus?
// Returns true if this was the last reference, and the resource protected by
// the reference counter can be deleted.
rtc::RefCountReleaseStatus DecRef() {
return (rtc::AtomicOps::Decrement(&ref_count_) == 0)
? rtc::RefCountReleaseStatus::kDroppedLastRef
: rtc::RefCountReleaseStatus::kOtherRefsRemained;
}
// 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 resource protected by the
// reference counter, knowing that it has exclusive access.
bool HasOneRef() const {
return rtc::AtomicOps::AcquireLoad(&ref_count_) == 1;
}
private:
volatile int ref_count_;
};
} // namespace webrtc_impl
} // namespace webrtc
#endif // RTC_BASE_REFCOUNTER_H_