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:
@ -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") {
|
||||
testonly = true
|
||||
sources = [
|
||||
|
43
api/refcountedbase.h
Normal file
43
api/refcountedbase.h
Normal 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_
|
@ -50,6 +50,7 @@ class AudioState final : public webrtc::AudioState {
|
||||
ScopedVoEInterface<VoEBase> voe_base_;
|
||||
|
||||
// Reference count; implementation copied from rtc::RefCountedObject.
|
||||
// TODO(nisse): Use RefCountedObject or RefCountedBase instead.
|
||||
mutable volatile int ref_count_ = 0;
|
||||
|
||||
// Transports mixed audio from the mixer to the audio device and
|
||||
|
@ -337,6 +337,7 @@ rtc_static_library("desktop_capture_generic") {
|
||||
deps = [
|
||||
":primitives",
|
||||
"../..:webrtc_common",
|
||||
"../../api:refcountedbase",
|
||||
"../../rtc_base:rtc_base", # TODO(kjellander): Cleanup in bugs.webrtc.org/3806.
|
||||
"../../system_wrappers",
|
||||
"//third_party/libyuv",
|
||||
|
@ -20,8 +20,7 @@ namespace webrtc {
|
||||
static const int64_t kDisplayConfigurationEventTimeoutMs = 10 * 1000;
|
||||
|
||||
DesktopConfigurationMonitor::DesktopConfigurationMonitor()
|
||||
: ref_count_(0),
|
||||
display_configuration_capture_event_(EventWrapper::Create()) {
|
||||
: display_configuration_capture_event_(EventWrapper::Create()) {
|
||||
CGError err = CGDisplayRegisterReconfigurationCallback(
|
||||
DesktopConfigurationMonitor::DisplaysReconfiguredCallback, this);
|
||||
if (err != kCGErrorSuccess) {
|
||||
|
@ -16,9 +16,9 @@
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "api/refcountedbase.h"
|
||||
#include "modules/desktop_capture/mac/desktop_configuration.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "system_wrappers/include/atomic32.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -26,7 +26,7 @@ class EventWrapper;
|
||||
|
||||
// The class provides functions to synchronize capturing and display
|
||||
// reconfiguring across threads, and the up-to-date MacDesktopConfiguration.
|
||||
class DesktopConfigurationMonitor {
|
||||
class DesktopConfigurationMonitor : public rtc::RefCountedBase {
|
||||
public:
|
||||
DesktopConfigurationMonitor();
|
||||
// Acquires a lock on the current configuration.
|
||||
@ -39,22 +39,16 @@ class DesktopConfigurationMonitor {
|
||||
return desktop_configuration_;
|
||||
}
|
||||
|
||||
void AddRef() { ++ref_count_; }
|
||||
void Release() {
|
||||
if (--ref_count_ == 0)
|
||||
delete this;
|
||||
}
|
||||
protected:
|
||||
~DesktopConfigurationMonitor() override;
|
||||
|
||||
private:
|
||||
static void DisplaysReconfiguredCallback(CGDirectDisplayID display,
|
||||
CGDisplayChangeSummaryFlags flags,
|
||||
void *user_parameter);
|
||||
~DesktopConfigurationMonitor();
|
||||
|
||||
void DisplaysReconfigured(CGDirectDisplayID display,
|
||||
CGDisplayChangeSummaryFlags flags);
|
||||
|
||||
Atomic32 ref_count_;
|
||||
std::set<CGDirectDisplayID> reconfiguring_displays_;
|
||||
MacDesktopConfiguration desktop_configuration_;
|
||||
std::unique_ptr<EventWrapper> display_configuration_capture_event_;
|
||||
|
@ -141,7 +141,7 @@ bool IsChromeWindow(CGWindowID id) {
|
||||
} // namespace
|
||||
|
||||
FullScreenChromeWindowDetector::FullScreenChromeWindowDetector()
|
||||
: ref_count_(0), last_update_time_ns_(0) {}
|
||||
: last_update_time_ns_(0) {}
|
||||
|
||||
FullScreenChromeWindowDetector::~FullScreenChromeWindowDetector() {}
|
||||
|
||||
|
@ -13,9 +13,9 @@
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#include "api/refcountedbase.h"
|
||||
#include "modules/desktop_capture/desktop_capturer.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "system_wrappers/include/atomic32.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -30,16 +30,10 @@ namespace webrtc {
|
||||
// 3. The new window is full-screen.
|
||||
// 4. The new window didn't exist at least 500 millisecond ago.
|
||||
|
||||
class FullScreenChromeWindowDetector {
|
||||
class FullScreenChromeWindowDetector : public rtc::RefCountedBase {
|
||||
public:
|
||||
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
|
||||
// criteria are met, or kCGNullWindowID if no such window found.
|
||||
CGWindowID FindFullScreenWindow(CGWindowID original_window);
|
||||
@ -48,11 +42,10 @@ class FullScreenChromeWindowDetector {
|
||||
// second.
|
||||
void UpdateWindowListIfNeeded(CGWindowID original_window);
|
||||
|
||||
protected:
|
||||
~FullScreenChromeWindowDetector() override;
|
||||
|
||||
private:
|
||||
~FullScreenChromeWindowDetector();
|
||||
|
||||
Atomic32 ref_count_;
|
||||
|
||||
// We cache the last two results of the window list, so
|
||||
// |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.
|
||||
|
@ -8,6 +8,8 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
@ -16,9 +16,9 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "api/refcountedbase.h"
|
||||
#include "rtc_base/constructormagic.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
|
||||
// easily conflict with other headers.
|
||||
@ -28,7 +28,7 @@ typedef union _XEvent XEvent;
|
||||
namespace webrtc {
|
||||
|
||||
// A ref-counted object to store XDisplay connection.
|
||||
class SharedXDisplay {
|
||||
class SharedXDisplay : public rtc::RefCountedBase {
|
||||
public:
|
||||
class XEventHandler {
|
||||
public:
|
||||
@ -51,12 +51,6 @@ class SharedXDisplay {
|
||||
// DISPLAY). NULL is returned if X11 connection failed.
|
||||
static rtc::scoped_refptr<SharedXDisplay> CreateDefault();
|
||||
|
||||
void AddRef() { ++ref_count_; }
|
||||
void Release() {
|
||||
if (--ref_count_ == 0)
|
||||
delete this;
|
||||
}
|
||||
|
||||
Display* display() { return display_; }
|
||||
|
||||
// Adds a new event |handler| for XEvent's of |type|.
|
||||
@ -69,12 +63,12 @@ class SharedXDisplay {
|
||||
// Processes pending XEvents, calling corresponding event handlers.
|
||||
void ProcessPendingXEvents();
|
||||
|
||||
protected:
|
||||
~SharedXDisplay() override;
|
||||
|
||||
private:
|
||||
typedef std::map<int, std::vector<XEventHandler*> > EventHandlersMap;
|
||||
|
||||
~SharedXDisplay();
|
||||
|
||||
Atomic32 ref_count_;
|
||||
Display* display_;
|
||||
|
||||
EventHandlersMap event_handlers_;
|
||||
|
@ -167,6 +167,7 @@ rtc_source_set("rtc_base_approved_generic") {
|
||||
"ratetracker.h",
|
||||
"refcount.h",
|
||||
"refcountedobject.h",
|
||||
"refcounter.h",
|
||||
"safe_compare.h",
|
||||
"safe_conversions.h",
|
||||
"safe_conversions_impl.h",
|
||||
|
@ -12,8 +12,9 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "rtc_base/atomicops.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "rtc_base/refcount.h"
|
||||
#include "rtc_base/refcounter.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
@ -31,14 +32,14 @@ class RefCountedObject : public T {
|
||||
std::forward<P1>(p1),
|
||||
std::forward<Args>(args)...) {}
|
||||
|
||||
virtual void AddRef() const { AtomicOps::Increment(&ref_count_); }
|
||||
virtual void AddRef() const { ref_count_.IncRef(); }
|
||||
|
||||
virtual RefCountReleaseStatus Release() const {
|
||||
if (AtomicOps::Decrement(&ref_count_) == 0) {
|
||||
const auto status = ref_count_.DecRef();
|
||||
if (status == RefCountReleaseStatus::kDroppedLastRef) {
|
||||
delete this;
|
||||
return RefCountReleaseStatus::kDroppedLastRef;
|
||||
}
|
||||
return RefCountReleaseStatus::kOtherRefsRemained;
|
||||
return status;
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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 AtomicOps::AcquireLoad(&ref_count_) == 1;
|
||||
}
|
||||
virtual bool HasOneRef() const { return ref_count_.HasOneRef(); }
|
||||
|
||||
protected:
|
||||
virtual ~RefCountedObject() {}
|
||||
|
||||
mutable volatile int ref_count_ = 0;
|
||||
mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(RefCountedObject);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
52
rtc_base/refcounter.h
Normal file
52
rtc_base/refcounter.h
Normal 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_
|
Reference in New Issue
Block a user