Log Message
Get rid of AudioNode::RefType https://bugs.webkit.org/show_bug.cgi?id=216945
Reviewed by Darin Adler. Source/_javascript_Core: * runtime/CachedTypes.cpp: (JSC::CachedRefPtr::decode const): Source/WebCore: Previously, the node had ref()/deref() function taking a RefType parameter. The RefType would be used to determine which counter should be incremented or decremented: either m_normalRefCount or m_connectionRefCount. In a previous patch, I have already ported code that was calling ref() / deref() explicitly with RefTypeNormal to use RefPtr<> instead. This patch goes further by: 1. Dropping the RefType parameter to ref() / deref(). ref() / deref() now increment or decrement m_normalRefCount only. Clients are expected to use RefPtr to handle ref counting. 2. Introduce new incrementConnectionCount() / decrementConnectionCount() to increment or decrement m_connectionRefCount. To reduce the chance of leakage, clients should not call these functions directly anymore. Instead, they use use the new AudioConnectionRefPtr<> pointer type to handle the connection ref counting for them. AudioConnectionRefPtr<> is a RefPtr<> which special traits causing incrementConnectionCount() and decrementConnectionCount() to get called on the AudioNode instead of ref() and deref(). I believe this new design is a bit simpler to reason about and less prone to leaks. There is no longer any code explicitly ref'ing or deref'ing the AudioNodes. Instead, RefPtr<> or AudioConnectionRefPtr<> is used to increment/decrement the right internal count. No new tests, no Web-facing behavior change. * Modules/webaudio/AudioBufferSourceNode.cpp: (WebCore::AudioBufferSourceNode::setPannerNode): (WebCore::AudioBufferSourceNode::clearPannerNode): * Modules/webaudio/AudioBufferSourceNode.h: * Modules/webaudio/AudioNode.cpp: (WebCore::AudioNode::disableOutputsIfNecessary): (WebCore::AudioNode::incrementConnectionCount): (WebCore::AudioNode::decrementConnectionCount): (WebCore::AudioNode::decrementConnectionCountWithLock): (WebCore::AudioNode::markNodeForDeletionIfNecessary): (WebCore::AudioNode::ref): (WebCore::AudioNode::deref): (WebCore::AudioNode::derefWithLock): * Modules/webaudio/AudioNode.h: (WebCore::AudioNodeConnectionRefDerefTraits::refIfNotNull): (WebCore::AudioNodeConnectionRefDerefTraits::derefIfNotNull): * Modules/webaudio/AudioNodeInput.cpp: (WebCore::AudioNodeInput::connect): (WebCore::AudioNodeInput::disconnect): * Modules/webaudio/AudioNodeOutput.cpp: (WebCore::AudioNodeOutput::propagateChannelCount): (WebCore::AudioNodeOutput::addInput): (WebCore::AudioNodeOutput::disconnectAllInputs): (WebCore::AudioNodeOutput::disable): (WebCore::AudioNodeOutput::enable): * Modules/webaudio/AudioNodeOutput.h: * Modules/webaudio/BaseAudioContext.cpp: (WebCore::BaseAudioContext::~BaseAudioContext): (WebCore::BaseAudioContext::refNode): (WebCore::BaseAudioContext::derefNode): (WebCore::BaseAudioContext::derefUnfinishedSourceNodes): (WebCore::BaseAudioContext::addDeferredDecrementConnectionCount): (WebCore::BaseAudioContext::handlePostRenderTasks): (WebCore::BaseAudioContext::handleDeferredDecrementConnectionCounts): * Modules/webaudio/BaseAudioContext.h: * Modules/webaudio/ScriptProcessorNode.cpp: (WebCore::ScriptProcessorNode::process): Source/WTF: Add third template parameter to RefPtr allowing to define the traits from incrementing / decrementing the refcount. The default traits call ref() / deref() but this can now be customized to call other functions. * wtf/CompactRefPtrTuple.h: * wtf/Forward.h: * wtf/RefPtr.h: (WTF::DefaultRefDerefTraits::refIfNotNull): (WTF::DefaultRefDerefTraits::derefIfNotNull): (WTF::RefPtr::RefPtr): (WTF::RefPtr::~RefPtr): (WTF::V>::RefPtr): (WTF::V>::leakRef): (WTF::=): (WTF::V>::swap): (WTF::swap): (WTF::operator==): (WTF::operator!=): (WTF::static_pointer_cast): (WTF::adoptRef): (WTF::is):
Modified Paths
- trunk/Source/_javascript_Core/ChangeLog
- trunk/Source/_javascript_Core/runtime/CachedTypes.cpp
- trunk/Source/WTF/ChangeLog
- trunk/Source/WTF/wtf/CompactRefPtrTuple.h
- trunk/Source/WTF/wtf/Forward.h
- trunk/Source/WTF/wtf/RefPtr.h
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
- trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h
- trunk/Source/WebCore/Modules/webaudio/AudioNode.cpp
- trunk/Source/WebCore/Modules/webaudio/AudioNode.h
- trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp
- trunk/Source/WebCore/Modules/webaudio/AudioNodeOutput.cpp
- trunk/Source/WebCore/Modules/webaudio/AudioNodeOutput.h
- trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp
- trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h
- trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp
- trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp
- trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h
- trunk/Source/WebCore/platform/graphics/freetype/RefPtrFontconfig.cpp
- trunk/Source/WebCore/platform/graphics/freetype/RefPtrFontconfig.h
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (267590 => 267591)
--- trunk/Source/_javascript_Core/ChangeLog 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-09-25 20:36:50 UTC (rev 267591)
@@ -1,3 +1,13 @@
+2020-09-25 Chris Dumez <[email protected]>
+
+ Get rid of AudioNode::RefType
+ https://bugs.webkit.org/show_bug.cgi?id=216945
+
+ Reviewed by Darin Adler.
+
+ * runtime/CachedTypes.cpp:
+ (JSC::CachedRefPtr::decode const):
+
2020-09-25 Alexey Shvayka <[email protected]>
DataView instances should not have own "byteLength" and "byteOffset" properties
Modified: trunk/Source/_javascript_Core/runtime/CachedTypes.cpp (267590 => 267591)
--- trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2020-09-25 20:36:50 UTC (rev 267591)
@@ -554,10 +554,10 @@
return nullptr;
if (isNewAllocation) {
decoder.addFinalizer([=] {
- derefIfNotNull(decodedPtr);
+ WTF::DefaultRefDerefTraits<Source>::derefIfNotNull(decodedPtr);
});
}
- refIfNotNull(decodedPtr);
+ WTF::DefaultRefDerefTraits<Source>::refIfNotNull(decodedPtr);
return adoptRef(decodedPtr);
}
Modified: trunk/Source/WTF/ChangeLog (267590 => 267591)
--- trunk/Source/WTF/ChangeLog 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WTF/ChangeLog 2020-09-25 20:36:50 UTC (rev 267591)
@@ -1,3 +1,33 @@
+2020-09-25 Chris Dumez <[email protected]>
+
+ Get rid of AudioNode::RefType
+ https://bugs.webkit.org/show_bug.cgi?id=216945
+
+ Reviewed by Darin Adler.
+
+ Add third template parameter to RefPtr allowing to define the traits
+ from incrementing / decrementing the refcount. The default traits
+ call ref() / deref() but this can now be customized to call other
+ functions.
+
+ * wtf/CompactRefPtrTuple.h:
+ * wtf/Forward.h:
+ * wtf/RefPtr.h:
+ (WTF::DefaultRefDerefTraits::refIfNotNull):
+ (WTF::DefaultRefDerefTraits::derefIfNotNull):
+ (WTF::RefPtr::RefPtr):
+ (WTF::RefPtr::~RefPtr):
+ (WTF::V>::RefPtr):
+ (WTF::V>::leakRef):
+ (WTF::=):
+ (WTF::V>::swap):
+ (WTF::swap):
+ (WTF::operator==):
+ (WTF::operator!=):
+ (WTF::static_pointer_cast):
+ (WTF::adoptRef):
+ (WTF::is):
+
2020-09-25 Antti Koivisto <[email protected]>
[LFC][Integration] Enable on Apple Windows port
Modified: trunk/Source/WTF/wtf/CompactRefPtrTuple.h (267590 => 267591)
--- trunk/Source/WTF/wtf/CompactRefPtrTuple.h 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WTF/wtf/CompactRefPtrTuple.h 2020-09-25 20:36:50 UTC (rev 267591)
@@ -39,7 +39,7 @@
CompactRefPtrTuple() = default;
~CompactRefPtrTuple()
{
- derefIfNotNull(m_data.pointer());
+ WTF::DefaultRefDerefTraits<T>::derefIfNotNull(m_data.pointer());
}
T* pointer() const
@@ -49,10 +49,10 @@
void setPointer(T* pointer)
{
- refIfNotNull(pointer);
+ WTF::DefaultRefDerefTraits<T>::refIfNotNull(pointer);
auto* old = m_data.pointer();
m_data.setPointer(pointer);
- derefIfNotNull(old);
+ WTF::DefaultRefDerefTraits<T>::derefIfNotNull(old);
}
Type type() const { return m_data.type(); }
Modified: trunk/Source/WTF/wtf/Forward.h (267590 => 267591)
--- trunk/Source/WTF/wtf/Forward.h 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WTF/wtf/Forward.h 2020-09-25 20:36:50 UTC (rev 267591)
@@ -59,6 +59,7 @@
#endif
template<typename> struct DumbPtrTraits;
+template<typename> struct DefaultRefDerefTraits;
template<typename> class CompletionHandler;
template<typename> class Function;
@@ -69,7 +70,7 @@
template<typename> class Packed;
template<typename T, size_t = alignof(T)> class PackedAlignedPtr;
template<typename T, typename = DumbPtrTraits<T>> class Ref;
-template<typename T, typename = DumbPtrTraits<T>> class RefPtr;
+template<typename T, typename = DumbPtrTraits<T>, typename = DefaultRefDerefTraits<T>> class RefPtr;
template<typename> class StringBuffer;
template<typename> class StringParsingBuffer;
template<typename, typename = void> class StringTypeAdapter;
Modified: trunk/Source/WTF/wtf/RefPtr.h (267590 => 267591)
--- trunk/Source/WTF/wtf/RefPtr.h 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WTF/wtf/RefPtr.h 2020-09-25 20:36:50 UTC (rev 267591)
@@ -29,26 +29,29 @@
namespace WTF {
-template<typename T, typename PtrTraits> class RefPtr;
-template<typename T, typename PtrTraits = DumbPtrTraits<T>> RefPtr<T, PtrTraits> adoptRef(T*);
+template<typename T> struct DefaultRefDerefTraits {
+ static ALWAYS_INLINE void refIfNotNull(T* ptr)
+ {
+ if (LIKELY(ptr != nullptr))
+ ptr->ref();
+ }
-template<typename T> ALWAYS_INLINE void refIfNotNull(T* ptr)
-{
- if (LIKELY(ptr != nullptr))
- ptr->ref();
-}
+ static ALWAYS_INLINE void derefIfNotNull(T* ptr)
+ {
+ if (LIKELY(ptr != nullptr))
+ ptr->deref();
+ }
+};
-template<typename T> ALWAYS_INLINE void derefIfNotNull(T* ptr)
-{
- if (LIKELY(ptr != nullptr))
- ptr->deref();
-}
+template<typename T, typename PtrTraits, typename RefDerefTraits> class RefPtr;
+template<typename T, typename PtrTraits = DumbPtrTraits<T>, typename RefDerefTraits = DefaultRefDerefTraits<T>> RefPtr<T, PtrTraits, RefDerefTraits> adoptRef(T*);
-template<typename T, typename Traits>
+template<typename T, typename _PtrTraits, typename _RefDerefTraits>
class RefPtr {
WTF_MAKE_FAST_ALLOCATED;
public:
- using PtrTraits = Traits;
+ using PtrTraits = _PtrTraits;
+ using RefDerefTraits = _RefDerefTraits;
typedef T ValueType;
typedef ValueType* PtrType;
@@ -55,12 +58,12 @@
static constexpr bool isRefPtr = true;
ALWAYS_INLINE constexpr RefPtr() : m_ptr(nullptr) { }
- ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
- ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(PtrTraits::unwrap(m_ptr)); }
- template<typename X, typename Y> RefPtr(const RefPtr<X, Y>& o) : m_ptr(o.get()) { refIfNotNull(PtrTraits::unwrap(m_ptr)); }
+ ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { RefDerefTraits::refIfNotNull(ptr); }
+ ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { RefDerefTraits::refIfNotNull(PtrTraits::unwrap(m_ptr)); }
+ template<typename X, typename Y, typename Z> RefPtr(const RefPtr<X, Y, Z>& o) : m_ptr(o.get()) { RefDerefTraits::refIfNotNull(PtrTraits::unwrap(m_ptr)); }
ALWAYS_INLINE RefPtr(RefPtr&& o) : m_ptr(o.leakRef()) { }
- template<typename X, typename Y> RefPtr(RefPtr<X, Y>&& o) : m_ptr(o.leakRef()) { }
+ template<typename X, typename Y, typename Z> RefPtr(RefPtr<X, Y, Z>&& o) : m_ptr(o.leakRef()) { }
template<typename X, typename Y> RefPtr(Ref<X, Y>&&);
// Hash table deleted values, which are only constructed and never copied or destroyed.
@@ -67,7 +70,7 @@
RefPtr(HashTableDeletedValueType) : m_ptr(PtrTraits::hashTableDeletedValue()) { }
bool isHashTableDeletedValue() const { return PtrTraits::isHashTableDeletedValue(m_ptr); }
- ALWAYS_INLINE ~RefPtr() { derefIfNotNull(PtrTraits::exchange(m_ptr, nullptr)); }
+ ALWAYS_INLINE ~RefPtr() { RefDerefTraits::derefIfNotNull(PtrTraits::exchange(m_ptr, nullptr)); }
T* get() const { return PtrTraits::unwrap(m_ptr); }
@@ -90,12 +93,12 @@
RefPtr& operator=(const RefPtr&);
RefPtr& operator=(T*);
RefPtr& operator=(std::nullptr_t);
- template<typename X, typename Y> RefPtr& operator=(const RefPtr<X, Y>&);
+ template<typename X, typename Y, typename Z> RefPtr& operator=(const RefPtr<X, Y, Z>&);
RefPtr& operator=(RefPtr&&);
- template<typename X, typename Y> RefPtr& operator=(RefPtr<X, Y>&&);
+ template<typename X, typename Y, typename Z> RefPtr& operator=(RefPtr<X, Y, Z>&&);
template<typename X> RefPtr& operator=(Ref<X>&&);
- template<typename X, typename Y> void swap(RefPtr<X, Y>&);
+ template<typename X, typename Y, typename Z> void swap(RefPtr<X, Y, Z>&);
RefPtr copyRef() && = delete;
RefPtr copyRef() const & WARN_UNUSED_RETURN { return RefPtr(m_ptr); }
@@ -103,8 +106,8 @@
private:
void unspecifiedBoolTypeInstance() const { }
- friend RefPtr adoptRef<T, PtrTraits>(T*);
- template<typename X, typename Y> friend class RefPtr;
+ friend RefPtr adoptRef<T, PtrTraits, RefDerefTraits>(T*);
+ template<typename X, typename Y, typename Z> friend class RefPtr;
enum AdoptTag { Adopt };
RefPtr(T* ptr, AdoptTag) : m_ptr(ptr) { }
@@ -112,21 +115,21 @@
typename PtrTraits::StorageType m_ptr;
};
-template<typename T, typename U>
+template<typename T, typename U, typename V>
template<typename X, typename Y>
-inline RefPtr<T, U>::RefPtr(Ref<X, Y>&& reference)
+inline RefPtr<T, U, V>::RefPtr(Ref<X, Y>&& reference)
: m_ptr(&reference.leakRef())
{
}
-template<typename T, typename U>
-inline T* RefPtr<T, U>::leakRef()
+template<typename T, typename U, typename V>
+inline T* RefPtr<T, U, V>::leakRef()
{
return U::exchange(m_ptr, nullptr);
}
-template<typename T, typename U>
-inline RefPtr<T, U>& RefPtr<T, U>::operator=(const RefPtr& o)
+template<typename T, typename U, typename V>
+inline RefPtr<T, U, V>& RefPtr<T, U, V>::operator=(const RefPtr& o)
{
RefPtr ptr = o;
swap(ptr);
@@ -133,9 +136,9 @@
return *this;
}
-template<typename T, typename U>
-template<typename X, typename Y>
-inline RefPtr<T, U>& RefPtr<T, U>::operator=(const RefPtr<X, Y>& o)
+template<typename T, typename U, typename V>
+template<typename X, typename Y, typename Z>
+inline RefPtr<T, U, V>& RefPtr<T, U, V>::operator=(const RefPtr<X, Y, Z>& o)
{
RefPtr ptr = o;
swap(ptr);
@@ -142,8 +145,8 @@
return *this;
}
-template<typename T, typename U>
-inline RefPtr<T, U>& RefPtr<T, U>::operator=(T* optr)
+template<typename T, typename U, typename V>
+inline RefPtr<T, U, V>& RefPtr<T, U, V>::operator=(T* optr)
{
RefPtr ptr = optr;
swap(ptr);
@@ -150,15 +153,15 @@
return *this;
}
-template<typename T, typename U>
-inline RefPtr<T, U>& RefPtr<T, U>::operator=(std::nullptr_t)
+template<typename T, typename U, typename V>
+inline RefPtr<T, U, V>& RefPtr<T, U, V>::operator=(std::nullptr_t)
{
- derefIfNotNull(U::exchange(m_ptr, nullptr));
+ V::derefIfNotNull(U::exchange(m_ptr, nullptr));
return *this;
}
-template<typename T, typename U>
-inline RefPtr<T, U>& RefPtr<T, U>::operator=(RefPtr&& o)
+template<typename T, typename U, typename V>
+inline RefPtr<T, U, V>& RefPtr<T, U, V>::operator=(RefPtr&& o)
{
RefPtr ptr = WTFMove(o);
swap(ptr);
@@ -165,9 +168,9 @@
return *this;
}
-template<typename T, typename U>
-template<typename X, typename Y>
-inline RefPtr<T, U>& RefPtr<T, U>::operator=(RefPtr<X, Y>&& o)
+template<typename T, typename U, typename V>
+template<typename X, typename Y, typename Z>
+inline RefPtr<T, U, V>& RefPtr<T, U, V>::operator=(RefPtr<X, Y, Z>&& o)
{
RefPtr ptr = WTFMove(o);
swap(ptr);
@@ -174,9 +177,9 @@
return *this;
}
-template<typename T, typename V>
+template<typename T, typename V, typename W>
template<typename U>
-inline RefPtr<T, V>& RefPtr<T, V>::operator=(Ref<U>&& reference)
+inline RefPtr<T, V, W>& RefPtr<T, V, W>::operator=(Ref<U>&& reference)
{
RefPtr ptr = WTFMove(reference);
swap(ptr);
@@ -183,71 +186,71 @@
return *this;
}
-template<class T, typename U>
-template<typename X, typename Y>
-inline void RefPtr<T, U>::swap(RefPtr<X, Y>& o)
+template<class T, typename U, typename V>
+template<typename X, typename Y, typename Z>
+inline void RefPtr<T, U, V>::swap(RefPtr<X, Y, Z>& o)
{
U::swap(m_ptr, o.m_ptr);
}
-template<typename T, typename U, typename X, typename Y, typename = std::enable_if_t<!std::is_same<U, DumbPtrTraits<T>>::value || !std::is_same<Y, DumbPtrTraits<X>>::value>>
-inline void swap(RefPtr<T, U>& a, RefPtr<X, Y>& b)
+template<typename T, typename U, typename V, typename X, typename Y, typename Z, typename = std::enable_if_t<!std::is_same<U, DumbPtrTraits<T>>::value || !std::is_same<Y, DumbPtrTraits<X>>::value>>
+inline void swap(RefPtr<T, U, V>& a, RefPtr<X, Y, Z>& b)
{
a.swap(b);
}
-template<typename T, typename U, typename X, typename Y>
-inline bool operator==(const RefPtr<T, U>& a, const RefPtr<X, Y>& b)
+template<typename T, typename U, typename V, typename X, typename Y, typename Z>
+inline bool operator==(const RefPtr<T, U, V>& a, const RefPtr<X, Y, Z>& b)
{
return a.get() == b.get();
}
-template<typename T, typename U, typename X>
-inline bool operator==(const RefPtr<T, U>& a, X* b)
+template<typename T, typename U, typename V, typename X>
+inline bool operator==(const RefPtr<T, U, V>& a, X* b)
{
return a.get() == b;
}
-template<typename T, typename X, typename Y>
-inline bool operator==(T* a, const RefPtr<X, Y>& b)
+template<typename T, typename X, typename Y, typename Z>
+inline bool operator==(T* a, const RefPtr<X, Y, Z>& b)
{
return a == b.get();
}
-template<typename T, typename U, typename X, typename Y>
-inline bool operator!=(const RefPtr<T, U>& a, const RefPtr<X, Y>& b)
+template<typename T, typename U, typename V, typename X, typename Y, typename Z>
+inline bool operator!=(const RefPtr<T, U, V>& a, const RefPtr<X, Y, Z>& b)
{
return a.get() != b.get();
}
-template<typename T, typename U, typename X>
-inline bool operator!=(const RefPtr<T, U>& a, X* b)
+template<typename T, typename U, typename V, typename X>
+inline bool operator!=(const RefPtr<T, U, V>& a, X* b)
{
return a.get() != b;
}
-template<typename T, typename X, typename Y>
-inline bool operator!=(T* a, const RefPtr<X, Y>& b)
+template<typename T, typename X, typename Y, typename Z>
+inline bool operator!=(T* a, const RefPtr<X, Y, Z>& b)
{
return a != b.get();
}
-template<typename T, typename U = DumbPtrTraits<T>, typename X, typename Y>
-inline RefPtr<T, U> static_pointer_cast(const RefPtr<X, Y>& p)
+template<typename T, typename U = DumbPtrTraits<T>, typename V = DefaultRefDerefTraits<T>, typename X, typename Y, typename Z>
+inline RefPtr<T, U, V> static_pointer_cast(const RefPtr<X, Y, Z>& p)
{
- return RefPtr<T, U>(static_cast<T*>(p.get()));
+ return RefPtr<T, U, V>(static_cast<T*>(p.get()));
}
-template <typename T, typename U>
-struct IsSmartPtr<RefPtr<T, U>> {
+template <typename T, typename U, typename V>
+struct IsSmartPtr<RefPtr<T, U, V>> {
static constexpr bool value = true;
};
-template<typename T, typename U>
-inline RefPtr<T, U> adoptRef(T* p)
+template<typename T, typename U, typename V>
+inline RefPtr<T, U, V> adoptRef(T* p)
{
adopted(p);
- return RefPtr<T, U>(p, RefPtr<T, U>::Adopt);
+ return RefPtr<T, U, V>(p, RefPtr<T, U, V>::Adopt);
}
template<typename T> inline RefPtr<T> makeRefPtr(T* pointer)
@@ -260,14 +263,14 @@
return &reference;
}
-template<typename ExpectedType, typename ArgType, typename PtrTraits>
-inline bool is(RefPtr<ArgType, PtrTraits>& source)
+template<typename ExpectedType, typename ArgType, typename PtrTraits, typename RefDerefTraits>
+inline bool is(RefPtr<ArgType, PtrTraits, RefDerefTraits>& source)
{
return is<ExpectedType>(source.get());
}
-template<typename ExpectedType, typename ArgType, typename PtrTraits>
-inline bool is(const RefPtr<ArgType, PtrTraits>& source)
+template<typename ExpectedType, typename ArgType, typename PtrTraits, typename RefDerefTraits>
+inline bool is(const RefPtr<ArgType, PtrTraits, RefDerefTraits>& source)
{
return is<ExpectedType>(source.get());
}
Modified: trunk/Source/WebCore/ChangeLog (267590 => 267591)
--- trunk/Source/WebCore/ChangeLog 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/ChangeLog 2020-09-25 20:36:50 UTC (rev 267591)
@@ -1,3 +1,72 @@
+2020-09-25 Chris Dumez <[email protected]>
+
+ Get rid of AudioNode::RefType
+ https://bugs.webkit.org/show_bug.cgi?id=216945
+
+ Reviewed by Darin Adler.
+
+ Previously, the node had ref()/deref() function taking a RefType parameter.
+ The RefType would be used to determine which counter should be incremented
+ or decremented: either m_normalRefCount or m_connectionRefCount.
+
+ In a previous patch, I have already ported code that was calling ref() / deref()
+ explicitly with RefTypeNormal to use RefPtr<> instead. This patch goes further by:
+ 1. Dropping the RefType parameter to ref() / deref(). ref() / deref() now increment
+ or decrement m_normalRefCount only. Clients are expected to use RefPtr to handle
+ ref counting.
+ 2. Introduce new incrementConnectionCount() / decrementConnectionCount() to increment
+ or decrement m_connectionRefCount. To reduce the chance of leakage, clients should
+ not call these functions directly anymore. Instead, they use use the new
+ AudioConnectionRefPtr<> pointer type to handle the connection ref counting for them.
+ AudioConnectionRefPtr<> is a RefPtr<> which special traits causing incrementConnectionCount()
+ and decrementConnectionCount() to get called on the AudioNode instead of ref() and
+ deref().
+
+ I believe this new design is a bit simpler to reason about and less prone to leaks.
+ There is no longer any code explicitly ref'ing or deref'ing the AudioNodes. Instead,
+ RefPtr<> or AudioConnectionRefPtr<> is used to increment/decrement the right internal
+ count.
+
+ No new tests, no Web-facing behavior change.
+
+ * Modules/webaudio/AudioBufferSourceNode.cpp:
+ (WebCore::AudioBufferSourceNode::setPannerNode):
+ (WebCore::AudioBufferSourceNode::clearPannerNode):
+ * Modules/webaudio/AudioBufferSourceNode.h:
+ * Modules/webaudio/AudioNode.cpp:
+ (WebCore::AudioNode::disableOutputsIfNecessary):
+ (WebCore::AudioNode::incrementConnectionCount):
+ (WebCore::AudioNode::decrementConnectionCount):
+ (WebCore::AudioNode::decrementConnectionCountWithLock):
+ (WebCore::AudioNode::markNodeForDeletionIfNecessary):
+ (WebCore::AudioNode::ref):
+ (WebCore::AudioNode::deref):
+ (WebCore::AudioNode::derefWithLock):
+ * Modules/webaudio/AudioNode.h:
+ (WebCore::AudioNodeConnectionRefDerefTraits::refIfNotNull):
+ (WebCore::AudioNodeConnectionRefDerefTraits::derefIfNotNull):
+ * Modules/webaudio/AudioNodeInput.cpp:
+ (WebCore::AudioNodeInput::connect):
+ (WebCore::AudioNodeInput::disconnect):
+ * Modules/webaudio/AudioNodeOutput.cpp:
+ (WebCore::AudioNodeOutput::propagateChannelCount):
+ (WebCore::AudioNodeOutput::addInput):
+ (WebCore::AudioNodeOutput::disconnectAllInputs):
+ (WebCore::AudioNodeOutput::disable):
+ (WebCore::AudioNodeOutput::enable):
+ * Modules/webaudio/AudioNodeOutput.h:
+ * Modules/webaudio/BaseAudioContext.cpp:
+ (WebCore::BaseAudioContext::~BaseAudioContext):
+ (WebCore::BaseAudioContext::refNode):
+ (WebCore::BaseAudioContext::derefNode):
+ (WebCore::BaseAudioContext::derefUnfinishedSourceNodes):
+ (WebCore::BaseAudioContext::addDeferredDecrementConnectionCount):
+ (WebCore::BaseAudioContext::handlePostRenderTasks):
+ (WebCore::BaseAudioContext::handleDeferredDecrementConnectionCounts):
+ * Modules/webaudio/BaseAudioContext.h:
+ * Modules/webaudio/ScriptProcessorNode.cpp:
+ (WebCore::ScriptProcessorNode::process):
+
2020-09-25 Rob Buis <[email protected]>
Simplify SVGTests.hasExtension idl
Modified: trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp (267590 => 267591)
--- trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp 2020-09-25 20:36:50 UTC (rev 267591)
@@ -580,22 +580,13 @@
void AudioBufferSourceNode::setPannerNode(PannerNodeBase* pannerNode)
{
- if (m_pannerNode != pannerNode && !hasFinished()) {
- if (pannerNode)
- pannerNode->ref(AudioNode::RefTypeConnection);
- if (m_pannerNode)
- m_pannerNode->deref(AudioNode::RefTypeConnection);
-
+ if (m_pannerNode != pannerNode && !hasFinished())
m_pannerNode = pannerNode;
- }
}
void AudioBufferSourceNode::clearPannerNode()
{
- if (m_pannerNode) {
- m_pannerNode->deref(AudioNode::RefTypeConnection);
- m_pannerNode = nullptr;
- }
+ m_pannerNode = nullptr;
}
void AudioBufferSourceNode::finish()
Modified: trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h (267590 => 267591)
--- trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h 2020-09-25 20:36:50 UTC (rev 267591)
@@ -141,8 +141,8 @@
double totalPitchRate();
// We optionally keep track of a panner node which has a doppler shift that is incorporated into
- // the pitch rate. We manually manage ref-counting because we want to use RefTypeConnection.
- PannerNodeBase* m_pannerNode { nullptr };
+ // the pitch rate.
+ AudioConnectionRefPtr<PannerNodeBase> m_pannerNode;
// This synchronizes process() with setBuffer() which can cause dynamic channel count changes.
mutable Lock m_processMutex;
Modified: trunk/Source/WebCore/Modules/webaudio/AudioNode.cpp (267590 => 267591)
--- trunk/Source/WebCore/Modules/webaudio/AudioNode.cpp 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/Modules/webaudio/AudioNode.cpp 2020-09-25 20:36:50 UTC (rev 267591)
@@ -548,7 +548,7 @@
void AudioNode::disableOutputsIfNecessary()
{
// Disable outputs if appropriate. We do this if the number of connections is 0 or 1. The case
- // of 0 is from finishDeref() where there are no connections left. The case of 1 is from
+ // of 0 is from decrementConnectionCountWithLock() where there are no connections left. The case of 1 is from
// AudioNodeInput::disable() where we want to disable outputs when there's only one connection
// left because we're ready to go away, but can't quite yet.
if (m_connectionRefCount <= 1 && !m_isDisabled) {
@@ -574,31 +574,21 @@
output->disable();
}
-void AudioNode::ref(RefType refType)
+void AudioNode::incrementConnectionCount()
{
- switch (refType) {
- case RefTypeNormal:
- ++m_normalRefCount;
- break;
- case RefTypeConnection:
- ++m_connectionRefCount;
- break;
- default:
- ASSERT_NOT_REACHED();
- }
+ ++m_connectionRefCount;
+ // See the disabling code in decrementConnectionCountWithLock() below. This handles the case where a node
+ // is being re-connected after being used at least once and disconnected.
+ // In this case, we need to re-enable.
+ enableOutputsIfNecessary();
+
#if DEBUG_AUDIONODE_REFERENCES
- fprintf(stderr, "%p: %d: AudioNode::ref(%d) %d %d\n", this, nodeType(), refType, m_normalRefCount, m_connectionRefCount);
+ fprintf(stderr, "%p: %d: AudioNode::incrementConnectionCount() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount);
#endif
-
- // See the disabling code in finishDeref() below. This handles the case where a node
- // is being re-connected after being used at least once and disconnected.
- // In this case, we need to re-enable.
- if (refType == RefTypeConnection)
- enableOutputsIfNecessary();
}
-void AudioNode::deref(RefType refType)
+void AudioNode::decrementConnectionCount()
{
// The actually work for deref happens completely within the audio context's graph lock.
// In the case of the audio thread, we must use a tryLock to avoid glitches.
@@ -615,7 +605,7 @@
if (hasLock) {
// This is where the real deref work happens.
- finishDeref(refType);
+ decrementConnectionCountWithLock();
if (mustReleaseLock)
context().unlock();
@@ -622,8 +612,7 @@
} else {
// We were unable to get the lock, so put this in a list to finish up later.
ASSERT(context().isAudioThread());
- ASSERT(refType == RefTypeConnection);
- context().addDeferredFinishDeref(this);
+ context().addDeferredDecrementConnectionCount(this);
}
// Once AudioContext::uninitialize() is called there's no more chances for deleteMarkedNodes() to get called, so we call here.
@@ -633,6 +622,66 @@
context().deleteMarkedNodes();
}
+void AudioNode::decrementConnectionCountWithLock()
+{
+ ASSERT(context().isGraphOwner());
+
+ ASSERT(m_connectionRefCount > 0);
+ --m_connectionRefCount;
+
+#if DEBUG_AUDIONODE_REFERENCES
+ fprintf(stderr, "%p: %d: AudioNode::decrementConnectionCountWithLock() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount);
+#endif
+
+ if (!m_connectionRefCount && m_normalRefCount)
+ disableOutputsIfNecessary();
+
+ markNodeForDeletionIfNecessary();
+}
+
+void AudioNode::markNodeForDeletionIfNecessary()
+{
+ ASSERT(context().isGraphOwner());
+
+ if (m_connectionRefCount || m_normalRefCount || m_isMarkedForDeletion)
+ return;
+
+ // All references are gone - we need to go away.
+ for (auto& output : m_outputs)
+ output->disconnectAll(); // This will deref() nodes we're connected to.
+
+ // Mark for deletion at end of each render quantum or when context shuts down.
+ context().markForDeletion(*this);
+ m_isMarkedForDeletion = true;
+ didBecomeMarkedForDeletion();
+}
+
+void AudioNode::ref()
+{
+ ++m_normalRefCount;
+
+#if DEBUG_AUDIONODE_REFERENCES
+ fprintf(stderr, "%p: %d: AudioNode::ref() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount);
+#endif
+}
+
+void AudioNode::deref()
+{
+ ASSERT(!context().isAudioThread());
+
+ {
+ BaseAudioContext::AutoLocker locker(context());
+ // This is where the real deref work happens.
+ derefWithLock();
+ }
+
+ // Once AudioContext::uninitialize() is called there's no more chances for deleteMarkedNodes() to get called, so we call here.
+ // We can't call in AudioContext::~AudioContext() since it will never be called as long as any AudioNode is alive
+ // because AudioNodes keep a reference to the context.
+ if (context().isAudioThreadFinished())
+ context().deleteMarkedNodes();
+}
+
Variant<RefPtr<BaseAudioContext>, RefPtr<WebKitAudioContext>> AudioNode::contextForBindings() const
{
if (m_context->isWebKitAudioContext())
@@ -640,42 +689,18 @@
return makeRefPtr(m_context.get());
}
-void AudioNode::finishDeref(RefType refType)
+void AudioNode::derefWithLock()
{
ASSERT(context().isGraphOwner());
- switch (refType) {
- case RefTypeNormal:
- ASSERT(m_normalRefCount > 0);
- --m_normalRefCount;
- break;
- case RefTypeConnection:
- ASSERT(m_connectionRefCount > 0);
- --m_connectionRefCount;
- break;
- default:
- ASSERT_NOT_REACHED();
- }
+ ASSERT(m_normalRefCount > 0);
+ --m_normalRefCount;
#if DEBUG_AUDIONODE_REFERENCES
- fprintf(stderr, "%p: %d: AudioNode::deref(%d) %d %d\n", this, nodeType(), refType, m_normalRefCount, m_connectionRefCount);
+ fprintf(stderr, "%p: %d: AudioNode::deref() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount);
#endif
- if (!m_connectionRefCount) {
- if (!m_normalRefCount) {
- if (!m_isMarkedForDeletion) {
- // All references are gone - we need to go away.
- for (auto& output : m_outputs)
- output->disconnectAll(); // This will deref() nodes we're connected to.
-
- // Mark for deletion at end of each render quantum or when context shuts down.
- context().markForDeletion(*this);
- m_isMarkedForDeletion = true;
- didBecomeMarkedForDeletion();
- }
- } else if (refType == RefTypeConnection)
- disableOutputsIfNecessary();
- }
+ markNodeForDeletionIfNecessary();
}
ExceptionOr<void> AudioNode::handleAudioNodeOptions(const AudioNodeOptions& options, const DefaultAudioNodeOptions& defaults)
Modified: trunk/Source/WebCore/Modules/webaudio/AudioNode.h (267590 => 267591)
--- trunk/Source/WebCore/Modules/webaudio/AudioNode.h 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/Modules/webaudio/AudioNode.h 2020-09-25 20:36:50 UTC (rev 267591)
@@ -96,17 +96,14 @@
NodeType nodeType() const { return m_nodeType; }
void setNodeType(NodeType);
- // We handle our own ref-counting because of the threading issues and subtle nature of
- // how AudioNodes can continue processing (playing one-shot sound) after there are no more
- // _javascript_ references to the object.
- enum RefType { RefTypeNormal, RefTypeConnection };
-
// Can be called from main thread or context's audio thread.
- void ref(RefType refType = RefTypeNormal);
- void deref(RefType refType = RefTypeNormal);
+ void ref();
+ void deref();
+ void incrementConnectionCount();
+ void decrementConnectionCount();
// Can be called from main thread or context's audio thread. It must be called while the context's graph lock is held.
- void finishDeref(RefType refType);
+ void decrementConnectionCountWithLock();
virtual void didBecomeMarkedForDeletion() { }
// The AudioNodeInput(s) (if any) will already have their input data available when process() is called.
@@ -202,6 +199,9 @@
void addInput();
void addOutput(unsigned numberOfChannels);
+ void markNodeForDeletionIfNecessary();
+ void derefWithLock();
+
struct DefaultAudioNodeOptions {
unsigned channelCount;
ChannelCountMode channelCountMode;
@@ -270,6 +270,23 @@
ChannelInterpretation m_channelInterpretation { ChannelInterpretation::Speakers };
};
+template<typename T> struct AudioNodeConnectionRefDerefTraits {
+ static ALWAYS_INLINE void refIfNotNull(T* ptr)
+ {
+ if (LIKELY(ptr != nullptr))
+ ptr->incrementConnectionCount();
+ }
+
+ static ALWAYS_INLINE void derefIfNotNull(T* ptr)
+ {
+ if (LIKELY(ptr != nullptr))
+ ptr->decrementConnectionCount();
+ }
+};
+
+template<typename T>
+using AudioConnectionRefPtr = RefPtr<T, DumbPtrTraits<T>, AudioNodeConnectionRefDerefTraits<T>>;
+
String convertEnumerationToString(AudioNode::NodeType);
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp (267590 => 267591)
--- trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp 2020-09-25 20:36:50 UTC (rev 267591)
@@ -60,9 +60,6 @@
output->addInput(this);
changedOutputs();
-
- // Sombody has just connected to us, so count it as a reference.
- node()->ref(AudioNode::RefTypeConnection);
}
void AudioNodeInput::disconnect(AudioNodeOutput* output)
@@ -76,15 +73,13 @@
// First try to disconnect from "active" connections.
if (m_outputs.remove(output)) {
changedOutputs();
- output->removeInput(this);
- node()->deref(AudioNode::RefTypeConnection); // Note: it's important to return immediately after all deref() calls since the node may be deleted.
+ output->removeInput(this); // Note: it's important to return immediately after this since the node may be deleted.
return;
}
// Otherwise, try to disconnect from disabled connections.
if (m_disabledOutputs.remove(output)) {
- output->removeInput(this);
- node()->deref(AudioNode::RefTypeConnection); // Note: it's important to return immediately after all deref() calls since the node may be deleted.
+ output->removeInput(this); // Note: it's important to return immediately after this since the node may be deleted.
return;
}
Modified: trunk/Source/WebCore/Modules/webaudio/AudioNodeOutput.cpp (267590 => 267591)
--- trunk/Source/WebCore/Modules/webaudio/AudioNodeOutput.cpp 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/Modules/webaudio/AudioNodeOutput.cpp 2020-09-25 20:36:50 UTC (rev 267591)
@@ -95,7 +95,7 @@
if (isChannelCountKnown()) {
// Announce to any nodes we're connected to that we changed our channel count for its input.
- for (auto& input : m_inputs) {
+ for (auto& input : m_inputs.keys()) {
AudioNode* connectionNode = input->node();
connectionNode->checkNumberOfChannelsForInput(input);
}
@@ -157,7 +157,7 @@
if (!input)
return;
- m_inputs.add(input);
+ m_inputs.add(input, input->node());
}
void AudioNodeOutput::removeInput(AudioNodeInput* input)
@@ -177,7 +177,7 @@
// AudioNodeInput::disconnect() changes m_inputs by calling removeInput().
while (!m_inputs.isEmpty()) {
- AudioNodeInput* input = *m_inputs.begin();
+ AudioNodeInput* input = m_inputs.begin()->key;
input->disconnect(this);
}
}
@@ -226,7 +226,7 @@
ASSERT(context().isGraphOwner());
if (m_isEnabled) {
- for (auto& input : m_inputs)
+ for (auto& input : m_inputs.keys())
input->disable(this);
m_isEnabled = false;
}
@@ -237,7 +237,7 @@
ASSERT(context().isGraphOwner());
if (!m_isEnabled) {
- for (auto& input : m_inputs)
+ for (auto& input : m_inputs.keys())
input->enable(this);
m_isEnabled = true;
}
Modified: trunk/Source/WebCore/Modules/webaudio/AudioNodeOutput.h (267590 => 267591)
--- trunk/Source/WebCore/Modules/webaudio/AudioNodeOutput.h 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/Modules/webaudio/AudioNodeOutput.h 2020-09-25 20:36:50 UTC (rev 267591)
@@ -140,8 +140,9 @@
// If m_isInPlace is true, use m_inPlaceBus as the valid AudioBus; If false, use the default m_internalBus.
bool m_isInPlace { false };
- HashSet<AudioNodeInput*> m_inputs;
- typedef HashSet<AudioNodeInput*>::iterator InputsIterator;
+ using InputsMap = HashMap<AudioNodeInput*, AudioConnectionRefPtr<AudioNode>>;
+ InputsMap m_inputs;
+ typedef InputsMap::iterator InputsIterator;
bool m_isEnabled { true };
// For the purposes of rendering, keeps track of the number of inputs and AudioParams we're connected to.
Modified: trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp (267590 => 267591)
--- trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp 2020-09-25 20:36:50 UTC (rev 267591)
@@ -197,7 +197,7 @@
if (m_automaticPullNodesNeedUpdating)
m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size());
ASSERT(m_renderingAutomaticPullNodes.isEmpty());
- // FIXME: Can we assert that m_deferredFinishDerefList is empty?
+ // FIXME: Can we assert that m_deferredBreakConnectionList is empty?
if (!isOfflineContext() && scriptExecutionContext()) {
document()->removeAudioProducer(*this);
@@ -681,7 +681,6 @@
ASSERT(isMainThread());
AutoLocker locker(*this);
- node.ref(AudioNode::RefTypeConnection);
m_referencedNodes.append(&node);
}
@@ -689,8 +688,6 @@
{
ASSERT(isGraphOwner());
- node.deref(AudioNode::RefTypeConnection);
-
ASSERT(m_referencedNodes.contains(&node));
m_referencedNodes.removeFirst(&node);
}
@@ -698,9 +695,6 @@
void BaseAudioContext::derefUnfinishedSourceNodes()
{
ASSERT(isMainThread() && isAudioThreadFinished());
- for (auto& node : m_referencedNodes)
- node->deref(AudioNode::RefTypeConnection);
-
m_referencedNodes.clear();
}
@@ -778,10 +772,10 @@
return m_graphOwnerThread == &Thread::current();
}
-void BaseAudioContext::addDeferredFinishDeref(AudioNode* node)
+void BaseAudioContext::addDeferredDecrementConnectionCount(AudioNode* node)
{
ASSERT(isAudioThread());
- m_deferredFinishDerefList.append(node);
+ m_deferredBreakConnectionList.append(node);
}
void BaseAudioContext::handlePreRenderTasks(const AudioIOPosition& outputPosition)
@@ -821,7 +815,7 @@
bool mustReleaseLock;
if (tryLock(mustReleaseLock)) {
// Take care of finishing any derefs where the tryLock() failed previously.
- handleDeferredFinishDerefs();
+ handleDeferredDecrementConnectionCounts();
// Dynamically clean up nodes which are no longer needed.
derefFinishedSourceNodes();
@@ -841,13 +835,13 @@
}
}
-void BaseAudioContext::handleDeferredFinishDerefs()
+void BaseAudioContext::handleDeferredDecrementConnectionCounts()
{
ASSERT(isAudioThread() && isGraphOwner());
- for (auto& node : m_deferredFinishDerefList)
- node->finishDeref(AudioNode::RefTypeConnection);
+ for (auto& node : m_deferredBreakConnectionList)
+ node->decrementConnectionCountWithLock();
- m_deferredFinishDerefList.clear();
+ m_deferredBreakConnectionList.clear();
}
void BaseAudioContext::markForDeletion(AudioNode& node)
Modified: trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h (267590 => 267591)
--- trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h 2020-09-25 20:36:50 UTC (rev 267591)
@@ -229,11 +229,11 @@
// Returns the maximum number of channels we can support.
static unsigned maxNumberOfChannels() { return MaxNumberOfChannels; }
- // In AudioNode::deref() a tryLock() is used for calling finishDeref(), but if it fails keep track here.
- void addDeferredFinishDeref(AudioNode*);
+ // In AudioNode::decrementConnectionCount() a tryLock() is used for calling decrementConnectionCountWithLock(), but if it fails keep track here.
+ void addDeferredDecrementConnectionCount(AudioNode*);
- // In the audio thread at the start of each render cycle, we'll call handleDeferredFinishDerefs().
- void handleDeferredFinishDerefs();
+ // In the audio thread at the start of each render cycle, we'll call handleDeferredDecrementConnectionCounts().
+ void handleDeferredDecrementConnectionCounts();
// Only accessed when the graph lock is held.
void markSummingJunctionDirty(AudioSummingJunction*);
@@ -397,10 +397,8 @@
// Only accessed in the audio thread.
Vector<AudioNode*> m_finishedNodes;
- // We don't use RefPtr<AudioNode> here because AudioNode has a more complex ref() / deref() implementation
- // with an optional argument for refType. We need to use the special refType: RefTypeConnection
// Either accessed when the graph lock is held, or on the main thread when the audio thread has finished.
- Vector<AudioNode*> m_referencedNodes;
+ Vector<AudioConnectionRefPtr<AudioNode>> m_referencedNodes;
// Accumulate nodes which need to be deleted here.
// This is copied to m_nodesToDelete at the end of a render cycle in handlePostRenderTasks(), where we're assured of a stable graph
@@ -427,7 +425,7 @@
HashSet<AudioNode*> m_automaticPullNodes;
Vector<AudioNode*> m_renderingAutomaticPullNodes;
// Only accessed in the audio thread.
- Vector<AudioNode*> m_deferredFinishDerefList;
+ Vector<AudioNode*> m_deferredBreakConnectionList;
Vector<Vector<DOMPromiseDeferred<void>>> m_stateReactions;
std::unique_ptr<PlatformMediaSession> m_mediaSession;
Modified: trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp (267590 => 267591)
--- trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp 2020-09-25 20:36:50 UTC (rev 267591)
@@ -183,12 +183,10 @@
// When this happens, fire an event and swap buffers.
if (!m_bufferReadWriteIndex) {
// Reference ourself so we don't accidentally get deleted before fireProcessEvent() gets called.
- auto protector = makeRef(*this);
-
// We only wait for script code execution when the context is an offline one for performance reasons.
if (context().isOfflineContext()) {
BinarySemaphore semaphore;
- callOnMainThread([this, &semaphore, doubleBufferIndex = m_doubleBufferIndex] {
+ callOnMainThread([this, &semaphore, doubleBufferIndex = m_doubleBufferIndex, protector = makeRef(*this)] {
fireProcessEvent(doubleBufferIndex);
semaphore.signal();
});
@@ -202,7 +200,7 @@
return;
}
- callOnMainThread([this, doubleBufferIndex = m_doubleBufferIndex, protector = WTFMove(protector)] {
+ callOnMainThread([this, doubleBufferIndex = m_doubleBufferIndex, protector = makeRef(*this)] {
auto locker = holdLock(m_processLock);
fireProcessEvent(doubleBufferIndex);
});
Modified: trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp (267590 => 267591)
--- trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp 2020-09-25 20:36:50 UTC (rev 267591)
@@ -25,73 +25,73 @@
namespace WTF {
-template<> void refIfNotNull(cairo_t* ptr)
+void DefaultRefDerefTraits<cairo_t>::refIfNotNull(cairo_t* ptr)
{
if (LIKELY(ptr))
cairo_reference(ptr);
}
-template<> void derefIfNotNull(cairo_t* ptr)
+void DefaultRefDerefTraits<cairo_t>::derefIfNotNull(cairo_t* ptr)
{
if (LIKELY(ptr))
cairo_destroy(ptr);
}
-template<> void refIfNotNull(cairo_surface_t* ptr)
+void DefaultRefDerefTraits<cairo_surface_t>::refIfNotNull(cairo_surface_t* ptr)
{
if (LIKELY(ptr))
cairo_surface_reference(ptr);
}
-template<> void derefIfNotNull(cairo_surface_t* ptr)
+void DefaultRefDerefTraits<cairo_surface_t>::derefIfNotNull(cairo_surface_t* ptr)
{
if (LIKELY(ptr))
cairo_surface_destroy(ptr);
}
-template<> void refIfNotNull(cairo_font_face_t* ptr)
+void DefaultRefDerefTraits<cairo_font_face_t>::refIfNotNull(cairo_font_face_t* ptr)
{
if (LIKELY(ptr))
cairo_font_face_reference(ptr);
}
-template<> void derefIfNotNull(cairo_font_face_t* ptr)
+void DefaultRefDerefTraits<cairo_font_face_t>::derefIfNotNull(cairo_font_face_t* ptr)
{
if (LIKELY(ptr))
cairo_font_face_destroy(ptr);
}
-template<> void refIfNotNull(cairo_scaled_font_t* ptr)
+void DefaultRefDerefTraits<cairo_scaled_font_t>::refIfNotNull(cairo_scaled_font_t* ptr)
{
if (LIKELY(ptr))
cairo_scaled_font_reference(ptr);
}
-template<> void derefIfNotNull(cairo_scaled_font_t* ptr)
+void DefaultRefDerefTraits<cairo_scaled_font_t>::derefIfNotNull(cairo_scaled_font_t* ptr)
{
if (LIKELY(ptr))
cairo_scaled_font_destroy(ptr);
}
-template<> void refIfNotNull(cairo_pattern_t* ptr)
+void DefaultRefDerefTraits<cairo_pattern_t>::refIfNotNull(cairo_pattern_t* ptr)
{
if (LIKELY(ptr))
cairo_pattern_reference(ptr);
}
-template<> void derefIfNotNull(cairo_pattern_t* ptr)
+void DefaultRefDerefTraits<cairo_pattern_t>::derefIfNotNull(cairo_pattern_t* ptr)
{
if (LIKELY(ptr))
cairo_pattern_destroy(ptr);
}
-template<> void refIfNotNull(cairo_region_t* ptr)
+void DefaultRefDerefTraits<cairo_region_t>::refIfNotNull(cairo_region_t* ptr)
{
if (LIKELY(ptr))
cairo_region_reference(ptr);
}
-template<> void derefIfNotNull(cairo_region_t* ptr)
+void DefaultRefDerefTraits<cairo_region_t>::derefIfNotNull(cairo_region_t* ptr)
{
if (LIKELY(ptr))
cairo_region_destroy(ptr);
Modified: trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h (267590 => 267591)
--- trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h 2020-09-25 20:36:50 UTC (rev 267591)
@@ -33,23 +33,41 @@
namespace WTF {
-template<> void refIfNotNull(cairo_t* ptr);
-template<> WEBCORE_EXPORT void derefIfNotNull(cairo_t* ptr);
+template<>
+struct DefaultRefDerefTraits<cairo_t> {
+ static void refIfNotNull(cairo_t* ptr);
+ WEBCORE_EXPORT static void derefIfNotNull(cairo_t* ptr);
+};
-template<> WEBCORE_EXPORT void refIfNotNull(cairo_surface_t* ptr);
-template<> WEBCORE_EXPORT void derefIfNotNull(cairo_surface_t* ptr);
+template<>
+struct DefaultRefDerefTraits<cairo_surface_t> {
+ WEBCORE_EXPORT static void refIfNotNull(cairo_surface_t* ptr);
+ WEBCORE_EXPORT static void derefIfNotNull(cairo_surface_t* ptr);
+};
-template<> void refIfNotNull(cairo_font_face_t* ptr);
-template<> void derefIfNotNull(cairo_font_face_t* ptr);
+template<>
+struct DefaultRefDerefTraits<cairo_font_face_t> {
+ static void refIfNotNull(cairo_font_face_t* ptr);
+ static void derefIfNotNull(cairo_font_face_t* ptr);
+};
-template<> void refIfNotNull(cairo_scaled_font_t* ptr);
-template<> void derefIfNotNull(cairo_scaled_font_t* ptr);
+template<>
+struct DefaultRefDerefTraits<cairo_scaled_font_t> {
+ static void refIfNotNull(cairo_scaled_font_t* ptr);
+ static void derefIfNotNull(cairo_scaled_font_t* ptr);
+};
-template<> void refIfNotNull(cairo_pattern_t*);
-template<> void derefIfNotNull(cairo_pattern_t*);
+template<>
+struct DefaultRefDerefTraits<cairo_pattern_t> {
+ static void refIfNotNull(cairo_pattern_t*);
+ static void derefIfNotNull(cairo_pattern_t*);
+};
-template<> void refIfNotNull(cairo_region_t*);
-template<> void derefIfNotNull(cairo_region_t*);
+template<>
+struct DefaultRefDerefTraits<cairo_region_t> {
+ static void refIfNotNull(cairo_region_t*);
+ static void derefIfNotNull(cairo_region_t*);
+};
} // namespace WTF
Modified: trunk/Source/WebCore/platform/graphics/freetype/RefPtrFontconfig.cpp (267590 => 267591)
--- trunk/Source/WebCore/platform/graphics/freetype/RefPtrFontconfig.cpp 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/platform/graphics/freetype/RefPtrFontconfig.cpp 2020-09-25 20:36:50 UTC (rev 267591)
@@ -25,25 +25,25 @@
namespace WTF {
-template<> void refIfNotNull(FcPattern* ptr)
+void DefaultRefDerefTraits<FcPattern>::refIfNotNull(FcPattern* ptr)
{
if (LIKELY(ptr))
FcPatternReference(ptr);
}
-template<> void derefIfNotNull(FcPattern* ptr)
+void DefaultRefDerefTraits<FcPattern>::derefIfNotNull(FcPattern* ptr)
{
if (LIKELY(ptr))
FcPatternDestroy(ptr);
}
-template<> void refIfNotNull(FcConfig* ptr)
+void DefaultRefDerefTraits<FcConfig>::refIfNotNull(FcConfig* ptr)
{
if (LIKELY(ptr))
FcConfigReference(ptr);
}
-template<> void derefIfNotNull(FcConfig* ptr)
+void DefaultRefDerefTraits<FcConfig>::derefIfNotNull(FcConfig* ptr)
{
if (LIKELY(ptr))
FcConfigDestroy(ptr);
Modified: trunk/Source/WebCore/platform/graphics/freetype/RefPtrFontconfig.h (267590 => 267591)
--- trunk/Source/WebCore/platform/graphics/freetype/RefPtrFontconfig.h 2020-09-25 20:19:39 UTC (rev 267590)
+++ trunk/Source/WebCore/platform/graphics/freetype/RefPtrFontconfig.h 2020-09-25 20:36:50 UTC (rev 267591)
@@ -28,11 +28,17 @@
namespace WTF {
-template<> void refIfNotNull(FcPattern* ptr);
-template<> void derefIfNotNull(FcPattern* ptr);
+template<>
+struct DefaultRefDerefTraits<FcPattern> {
+ static void refIfNotNull(FcPattern* ptr);
+ static void derefIfNotNull(FcPattern* ptr);
+};
-template<> void refIfNotNull(FcConfig* ptr);
-template<> void derefIfNotNull(FcConfig* ptr);
+template<>
+struct DefaultRefDerefTraits<FcConfig> {
+ static void refIfNotNull(FcConfig* ptr);
+ static void derefIfNotNull(FcConfig* ptr);
+};
} // namespace WTF
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
