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") {
|
rtc_source_set("libjingle_peerconnection_test_api") {
|
||||||
testonly = true
|
testonly = true
|
||||||
sources = [
|
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_;
|
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
|
||||||
|
@ -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",
|
||||||
|
@ -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) {
|
||||||
|
@ -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_;
|
||||||
|
@ -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() {}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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>
|
||||||
|
@ -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_;
|
||||||
|
@ -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",
|
||||||
|
@ -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
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