Title: [176683] trunk
Revision
176683
Author
[email protected]
Date
2014-12-02 12:30:17 -0800 (Tue, 02 Dec 2014)

Log Message

Generalize PageActivityAssertionToken
https://bugs.webkit.org/show_bug.cgi?id=139106

Reviewed by Sam Weinig.

Source/WebCore:

PageActivityAssertionToken is a RAII mechanism implementing a counter, used by PageThrottler
to count user visible activity in progress on the page (currently page load and media playback).
Use of an RAII type is prevents a number of possible errors, including double counting a single
media element, or failing to decrement the count after a media element has been deallocated.

The current implementation has a number of drawbacks that have been addressed by this refactoring:
 - specific to single use in PageThrottler class - not reusable.
 - incomplete encapsulation - the counter and WeakPtrFactory that comprise the current implementation
   are not encapsulated (are in the client type, PageThrottler).
 - tokens are not shared - PageActivityAssertionToken instances are managed by std::unique, every
   increment requires an object allocation.
 - redundancy - the current implementation uses a WeakPtr to safely reference the PageThrottler, this
   is internally implemented using a reference counted type, resulting in two counters being
   incremented (one in the PageActivityAssertionToken, one in the PageThrottler).

In the reimplementation:
 - a callback is provided via a lambda function, which allows for easy reuse without a lot of
   boilerplate code.
 - the counter, callback and ownership of the otherwise weakly-owned token is encapsulated within the
   RefCounter type.
 - a single count within RefCounter::Count stores the counter value, and also manage the lifetime
   of this object.
 - standard RefPtrs are used to manage references to the RefCounter::Count.

* WebCore.xcodeproj/project.pbxproj:
    - removed PageActivityAssertionToken.cpp/.h
* html/HTMLMediaElement.cpp:
    - removed PageActivityAssertionToken.h
* html/HTMLMediaElement.h:
    - std::unique_ptr<PageActivityAssertionToken> -> RefPtr<RefCounter::Count>
* loader/FrameLoader.cpp:
    - removed PageActivityAssertionToken.h
* loader/FrameLoader.h:
    - std::unique_ptr<PageActivityAssertionToken> -> RefPtr<RefCounter::Count>
* loader/SubresourceLoader.cpp:
    - removed PageActivityAssertionToken.h
* loader/SubresourceLoader.h:
    - removed class PageActivityAssertionToken
* page/Page.cpp:
    - removed PageActivityAssertionToken.h
(WebCore::Page::Page):
    - removed Page* parameter to PageThrottler
* page/Page.h:
    - removed class PageActivityAssertionToken
* page/PageActivityAssertionToken.cpp: Removed.
* page/PageActivityAssertionToken.h: Removed.
    - removed PageActivityAssertionToken.cpp/.h
* page/PageThrottler.cpp:
(WebCore::PageThrottler::PageThrottler):
    - removed m_page, m_weakPtrFactory, m_activityCount; added m_pageActivityCounter.
(WebCore::PageThrottler::mediaActivityToken):
    - std::unique_ptr<PageActivityAssertionToken> -> PassRefPtr<RefCounter::Count>
(WebCore::PageThrottler::pageLoadActivityToken):
    - std::unique_ptr<PageActivityAssertionToken> -> PassRefPtr<RefCounter::Count>
(WebCore::PageThrottler::pageActivityCounterValueDidChange):
    - merged functionality of incrementActivityCount/decrementActivityCount
(WebCore::PageThrottler::incrementActivityCount): Deleted.
    - see pageActivityCounterValueDidChange
(WebCore::PageThrottler::decrementActivityCount): Deleted.
    - see pageActivityCounterValueDidChange
* page/PageThrottler.h:
(WebCore::PageThrottler::weakPtr): Deleted.
    - no longer required; this functionality is now encapsulated within RefCounter.

Source/WTF:

PageActivityAssertionToken is a RAII mechanism implementing a counter, used by PageThrottler
to count user visible activity in progress on the page (currently page load and media playback).
Use of an RAII type is prevents a number of possible errors, including double counting a single
media element, or failing to decrement the count after a media element has been deallocated.

The current implementation has a number of drawbacks that have been addressed by this refactoring:
 - specific to single use in PageThrottler class - not reusable.
 - incomplete encapsulation - the counter and WeakPtrFactory that comprise the current implementation
   are not encapsulated (are in the client type, PageThrottler).
 - tokens are not shared - PageActivityAssertionToken instances are managed by std::unique, every
   increment requires an object allocation.
 - redundancy - the current implementation uses a WeakPtr to safely reference the PageThrottler, this
   is internally implemented using a reference counted type, resulting in two counters being
   incremented (one in the PageActivityAssertionToken, one in the PageThrottler).

In the reimplementation:
 - a callback is provided via a lambda function, which allows for easy reuse without a lot of
   boilerplate code.
 - the counter, callback and ownership of the otherwise weakly-owned token is encapsulated within the
   RefCounter type.
 - a single count within RefCounter::Count stores the counter value, and also manage the lifetime
   of this object.
 - standard RefPtrs are used to manage references to the RefCounter::Count.

* WTF.xcodeproj/project.pbxproj:
    - added RefCounter.cpp/.h
* wtf/RefCounter.cpp: Added.
(WTF::RefCounter::Count::ref):
    - increment the counter.
(WTF::RefCounter::Count::deref):
    - decrement the counter, and delete as necessary.
(WTF::RefCounter::RefCounter):
    - create a RefCounter::Count.
(WTF::RefCounter::~RefCounter):
    - eagerly delete the Counter if it has no references, otherwise let it be deleted on last deref.
* wtf/RefCounter.h: Added.
(WTF::RefCounter::Count::Count):
    - initialize count to 0.
(WTF::RefCounter::RefCounter):
    - takes a lambda to be called when the value changes.
(WTF::RefCounter::count):
    - reference the counter (and in doing so increment the count).
(WTF::RefCounter::value):
    - access the current value of the counter.

Tools:

Add an API test for WTF::RefCounter.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/RefCounter.cpp: Added.
(TestWebKitAPI::TEST):
    - added RefCounter test.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (176682 => 176683)


--- trunk/Source/WTF/ChangeLog	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WTF/ChangeLog	2014-12-02 20:30:17 UTC (rev 176683)
@@ -1,3 +1,55 @@
+2014-12-02  Gavin Barraclough  <[email protected]>
+
+        Generalize PageActivityAssertionToken
+        https://bugs.webkit.org/show_bug.cgi?id=139106
+
+        Reviewed by Sam Weinig.
+
+        PageActivityAssertionToken is a RAII mechanism implementing a counter, used by PageThrottler
+        to count user visible activity in progress on the page (currently page load and media playback).
+        Use of an RAII type is prevents a number of possible errors, including double counting a single
+        media element, or failing to decrement the count after a media element has been deallocated.
+
+        The current implementation has a number of drawbacks that have been addressed by this refactoring:
+         - specific to single use in PageThrottler class - not reusable.
+         - incomplete encapsulation - the counter and WeakPtrFactory that comprise the current implementation
+           are not encapsulated (are in the client type, PageThrottler).
+         - tokens are not shared - PageActivityAssertionToken instances are managed by std::unique, every
+           increment requires an object allocation.
+         - redundancy - the current implementation uses a WeakPtr to safely reference the PageThrottler, this
+           is internally implemented using a reference counted type, resulting in two counters being
+           incremented (one in the PageActivityAssertionToken, one in the PageThrottler).
+
+        In the reimplementation:
+         - a callback is provided via a lambda function, which allows for easy reuse without a lot of
+           boilerplate code.
+         - the counter, callback and ownership of the otherwise weakly-owned token is encapsulated within the
+           RefCounter type.
+         - a single count within RefCounter::Count stores the counter value, and also manage the lifetime
+           of this object.
+         - standard RefPtrs are used to manage references to the RefCounter::Count.
+
+        * WTF.xcodeproj/project.pbxproj:
+            - added RefCounter.cpp/.h
+        * wtf/RefCounter.cpp: Added.
+        (WTF::RefCounter::Count::ref):
+            - increment the counter.
+        (WTF::RefCounter::Count::deref):
+            - decrement the counter, and delete as necessary.
+        (WTF::RefCounter::RefCounter):
+            - create a RefCounter::Count.
+        (WTF::RefCounter::~RefCounter):
+            - eagerly delete the Counter if it has no references, otherwise let it be deleted on last deref.
+        * wtf/RefCounter.h: Added.
+        (WTF::RefCounter::Count::Count):
+            - initialize count to 0.
+        (WTF::RefCounter::RefCounter):
+            - takes a lambda to be called when the value changes.
+        (WTF::RefCounter::count):
+            - reference the counter (and in doing so increment the count).
+        (WTF::RefCounter::value):
+            - access the current value of the counter.
+
 2014-12-01  Andreas Kling  <[email protected]>
 
         Optimize constructing JSC::Identifier from AtomicString.

Modified: trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj (176682 => 176683)


--- trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj	2014-12-02 20:30:17 UTC (rev 176683)
@@ -120,6 +120,7 @@
     <ClCompile Include="..\wtf\RAMSize.cpp" />
     <ClCompile Include="..\wtf\RandomNumber.cpp" />
     <ClCompile Include="..\wtf\RefCountedLeakCounter.cpp" />
+    <ClCompile Include="..\wtf\RefCounter.cpp" />
     <ClCompile Include="..\wtf\RunLoop.cpp" />
     <ClCompile Include="..\wtf\SHA1.cpp" />
     <ClCompile Include="..\wtf\SixCharacterHash.cpp" />
@@ -258,6 +259,7 @@
     <ClInclude Include="..\wtf\RedBlackTree.h" />
     <ClInclude Include="..\wtf\RefCounted.h" />
     <ClInclude Include="..\wtf\RefCountedLeakCounter.h" />
+    <ClInclude Include="..\wtf\RefCounter.h" />
     <ClInclude Include="..\wtf\RefPtr.h" />
     <ClInclude Include="..\wtf\RetainPtr.h" />
     <ClInclude Include="..\wtf\RunLoop.h" />

Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (176682 => 176683)


--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2014-12-02 20:30:17 UTC (rev 176683)
@@ -80,6 +80,8 @@
 		8134013815B092FD001FF0B8 /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8134013615B092FD001FF0B8 /* Base64.cpp */; };
 		8134013915B092FD001FF0B8 /* Base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 8134013715B092FD001FF0B8 /* Base64.h */; };
 		83FBA93219DF459700F30ADB /* TypeCasts.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FBA93119DF459700F30ADB /* TypeCasts.h */; };
+		86F46F601A2840EE00CCBF22 /* RefCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86F46F5E1A2840EE00CCBF22 /* RefCounter.cpp */; };
+		86F46F611A2840EE00CCBF22 /* RefCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F46F5F1A2840EE00CCBF22 /* RefCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		93934BD318A1E8C300D0D6A1 /* StringViewObjC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93934BD218A1E8C300D0D6A1 /* StringViewObjC.mm */; };
 		93934BD518A1F16900D0D6A1 /* StringViewCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93934BD418A1F16900D0D6A1 /* StringViewCF.cpp */; };
 		93AC91A818942FC400244939 /* LChar.h in Headers */ = {isa = PBXBuildFile; fileRef = 93AC91A718942FC400244939 /* LChar.h */; };
@@ -372,6 +374,8 @@
 		8134013615B092FD001FF0B8 /* Base64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Base64.cpp; sourceTree = "<group>"; };
 		8134013715B092FD001FF0B8 /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = "<group>"; };
 		83FBA93119DF459700F30ADB /* TypeCasts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeCasts.h; sourceTree = "<group>"; };
+		86F46F5E1A2840EE00CCBF22 /* RefCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefCounter.cpp; sourceTree = "<group>"; };
+		86F46F5F1A2840EE00CCBF22 /* RefCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefCounter.h; sourceTree = "<group>"; };
 		93934BD218A1E8C300D0D6A1 /* StringViewObjC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = StringViewObjC.mm; path = mac/StringViewObjC.mm; sourceTree = "<group>"; };
 		93934BD418A1F16900D0D6A1 /* StringViewCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringViewCF.cpp; path = cf/StringViewCF.cpp; sourceTree = "<group>"; };
 		93AC91A718942FC400244939 /* LChar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LChar.h; sourceTree = "<group>"; };
@@ -836,6 +840,8 @@
 				A8A47300151A825B004123FF /* RefCountedArray.h */,
 				A8A47301151A825B004123FF /* RefCountedLeakCounter.cpp */,
 				A8A47302151A825B004123FF /* RefCountedLeakCounter.h */,
+				86F46F5E1A2840EE00CCBF22 /* RefCounter.cpp */,
+				86F46F5F1A2840EE00CCBF22 /* RefCounter.h */,
 				A8A47303151A825B004123FF /* RefPtr.h */,
 				A8A47305151A825B004123FF /* RetainPtr.h */,
 				2CDED0F118115C85004DBA70 /* RunLoop.cpp */,
@@ -1166,6 +1172,7 @@
 				A8A4741C151A825B004123FF /* RefPtr.h in Headers */,
 				A8A4741E151A825B004123FF /* RetainPtr.h in Headers */,
 				2CDED0F418115C85004DBA70 /* RunLoop.h in Headers */,
+				86F46F611A2840EE00CCBF22 /* RefCounter.h in Headers */,
 				1469419216EAAF6D0024E146 /* RunLoopTimer.h in Headers */,
 				14F3B0F715E45E4600210069 /* SaturatedArithmetic.h in Headers */,
 				1469419616EAAFF80024E146 /* SchedulePair.h in Headers */,
@@ -1339,6 +1346,7 @@
 				A8A4739A151A825B004123FF /* CryptographicallyRandomNumber.cpp in Sources */,
 				A8A47439151A825B004123FF /* CString.cpp in Sources */,
 				A8A4739C151A825B004123FF /* CurrentTime.cpp in Sources */,
+				86F46F601A2840EE00CCBF22 /* RefCounter.cpp in Sources */,
 				A8A4739E151A825B004123FF /* DataLog.cpp in Sources */,
 				A8A473A0151A825B004123FF /* DateMath.cpp in Sources */,
 				A8A473A2151A825B004123FF /* DecimalNumber.cpp in Sources */,

Modified: trunk/Source/WTF/wtf/CMakeLists.txt (176682 => 176683)


--- trunk/Source/WTF/wtf/CMakeLists.txt	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WTF/wtf/CMakeLists.txt	2014-12-02 20:30:17 UTC (rev 176683)
@@ -82,6 +82,7 @@
     Ref.h
     RefCounted.h
     RefCountedLeakCounter.h
+    RefCounter.h
     RefPtr.h
     RetainPtr.h
     RunLoop.h
@@ -175,6 +176,7 @@
     RAMSize.cpp
     RandomNumber.cpp
     RefCountedLeakCounter.cpp
+    RefCounter.cpp
     RunLoop.cpp
     SHA1.cpp
     SixCharacterHash.cpp

Added: trunk/Source/WTF/wtf/RefCounter.cpp (0 => 176683)


--- trunk/Source/WTF/wtf/RefCounter.cpp	                        (rev 0)
+++ trunk/Source/WTF/wtf/RefCounter.cpp	2014-12-02 20:30:17 UTC (rev 176683)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RefCounter.h"
+
+namespace WTF {
+
+void RefCounter::Count::ref()
+{
+    ++m_value;
+
+    if (m_refCounter)
+        m_refCounter->m_valueDidChange();
+}
+
+void RefCounter::Count::deref()
+{
+    ASSERT(m_value);
+    --m_value;
+
+    // The Count object is kept alive so long as either the RefCounter that created it remains
+    // allocated, or so long as its reference count is non-zero.
+    // If the RefCounter has already been deallocted then delete the Count when its reference
+    // count reaches zero.
+    if (m_refCounter)
+        m_refCounter->m_valueDidChange();
+    else if (!m_value)
+        delete this;
+}
+
+RefCounter::RefCounter(std::function<void()> valueDidChange)
+    : m_valueDidChange(valueDidChange)
+    , m_count(new Count(*this))
+{
+}
+
+RefCounter::~RefCounter()
+{
+    // The Count object is kept alive so long as either the RefCounter that created it remains
+    // allocated, or so long as its reference count is non-zero.
+    // If the reference count of the Count is already zero then delete it now, otherwise
+    // clear its m_refCounter pointer.
+    if (m_count->m_value)
+        m_count->m_refCounter = nullptr;
+    else
+        delete m_count;
+}
+
+} // namespace WebCore

Added: trunk/Source/WTF/wtf/RefCounter.h (0 => 176683)


--- trunk/Source/WTF/wtf/RefCounter.h	                        (rev 0)
+++ trunk/Source/WTF/wtf/RefCounter.h	2014-12-02 20:30:17 UTC (rev 176683)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RefCounter_h
+#define RefCounter_h
+
+#include <functional>
+#include <wtf/Noncopyable.h>
+#include <wtf/RefPtr.h>
+
+namespace WTF {
+
+class RefCounter {
+    WTF_MAKE_NONCOPYABLE(RefCounter);
+public:
+    class Count {
+        WTF_MAKE_NONCOPYABLE(Count);
+    public:
+        WTF_EXPORT_PRIVATE void ref();
+        WTF_EXPORT_PRIVATE void deref();
+
+    private:
+        friend class RefCounter;
+
+        Count(RefCounter& refCounter)
+            : m_refCounter(&refCounter)
+            , m_value(0)
+        {
+        }
+
+        RefCounter* m_refCounter;
+        unsigned m_value;
+    };
+
+    WTF_EXPORT_PRIVATE RefCounter(std::function<void()> = []() { });
+    WTF_EXPORT_PRIVATE ~RefCounter();
+
+    PassRef<Count> count() const
+    {
+        return *m_count;
+    }
+
+    unsigned value() const
+    {
+        return m_count->m_value;
+    }
+
+private:
+    std::function<void()> m_valueDidChange;
+    Count* m_count;
+};
+
+} // namespace WTF
+
+using WTF::RefCounter;
+
+#endif // RefCounter_h

Modified: trunk/Source/WebCore/CMakeLists.txt (176682 => 176683)


--- trunk/Source/WebCore/CMakeLists.txt	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/CMakeLists.txt	2014-12-02 20:30:17 UTC (rev 176683)
@@ -1909,7 +1909,6 @@
     page/NavigatorBase.cpp
     page/OriginAccessEntry.cpp
     page/Page.cpp
-    page/PageActivityAssertionToken.cpp
     page/PageConfiguration.cpp
     page/PageConsoleClient.cpp
     page/PageGroup.cpp

Modified: trunk/Source/WebCore/ChangeLog (176682 => 176683)


--- trunk/Source/WebCore/ChangeLog	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/ChangeLog	2014-12-02 20:30:17 UTC (rev 176683)
@@ -1,3 +1,74 @@
+2014-12-02  Gavin Barraclough  <[email protected]>
+
+        Generalize PageActivityAssertionToken
+        https://bugs.webkit.org/show_bug.cgi?id=139106
+
+        Reviewed by Sam Weinig.
+
+        PageActivityAssertionToken is a RAII mechanism implementing a counter, used by PageThrottler
+        to count user visible activity in progress on the page (currently page load and media playback).
+        Use of an RAII type is prevents a number of possible errors, including double counting a single
+        media element, or failing to decrement the count after a media element has been deallocated.
+
+        The current implementation has a number of drawbacks that have been addressed by this refactoring:
+         - specific to single use in PageThrottler class - not reusable.
+         - incomplete encapsulation - the counter and WeakPtrFactory that comprise the current implementation
+           are not encapsulated (are in the client type, PageThrottler).
+         - tokens are not shared - PageActivityAssertionToken instances are managed by std::unique, every
+           increment requires an object allocation.
+         - redundancy - the current implementation uses a WeakPtr to safely reference the PageThrottler, this
+           is internally implemented using a reference counted type, resulting in two counters being
+           incremented (one in the PageActivityAssertionToken, one in the PageThrottler).
+
+        In the reimplementation:
+         - a callback is provided via a lambda function, which allows for easy reuse without a lot of
+           boilerplate code.
+         - the counter, callback and ownership of the otherwise weakly-owned token is encapsulated within the
+           RefCounter type.
+         - a single count within RefCounter::Count stores the counter value, and also manage the lifetime
+           of this object.
+         - standard RefPtrs are used to manage references to the RefCounter::Count.
+
+        * WebCore.xcodeproj/project.pbxproj:
+            - removed PageActivityAssertionToken.cpp/.h
+        * html/HTMLMediaElement.cpp:
+            - removed PageActivityAssertionToken.h
+        * html/HTMLMediaElement.h:
+            - std::unique_ptr<PageActivityAssertionToken> -> RefPtr<RefCounter::Count>
+        * loader/FrameLoader.cpp:
+            - removed PageActivityAssertionToken.h
+        * loader/FrameLoader.h:
+            - std::unique_ptr<PageActivityAssertionToken> -> RefPtr<RefCounter::Count>
+        * loader/SubresourceLoader.cpp:
+            - removed PageActivityAssertionToken.h
+        * loader/SubresourceLoader.h:
+            - removed class PageActivityAssertionToken
+        * page/Page.cpp:
+            - removed PageActivityAssertionToken.h
+        (WebCore::Page::Page):
+            - removed Page* parameter to PageThrottler
+        * page/Page.h:
+            - removed class PageActivityAssertionToken
+        * page/PageActivityAssertionToken.cpp: Removed.
+        * page/PageActivityAssertionToken.h: Removed.
+            - removed PageActivityAssertionToken.cpp/.h
+        * page/PageThrottler.cpp:
+        (WebCore::PageThrottler::PageThrottler):
+            - removed m_page, m_weakPtrFactory, m_activityCount; added m_pageActivityCounter.
+        (WebCore::PageThrottler::mediaActivityToken):
+            - std::unique_ptr<PageActivityAssertionToken> -> PassRefPtr<RefCounter::Count>
+        (WebCore::PageThrottler::pageLoadActivityToken):
+            - std::unique_ptr<PageActivityAssertionToken> -> PassRefPtr<RefCounter::Count>
+        (WebCore::PageThrottler::pageActivityCounterValueDidChange):
+            - merged functionality of incrementActivityCount/decrementActivityCount
+        (WebCore::PageThrottler::incrementActivityCount): Deleted.
+            - see pageActivityCounterValueDidChange
+        (WebCore::PageThrottler::decrementActivityCount): Deleted.
+            - see pageActivityCounterValueDidChange
+        * page/PageThrottler.h:
+        (WebCore::PageThrottler::weakPtr): Deleted.
+            - no longer required; this functionality is now encapsulated within RefCounter.
+
 2014-12-02  Tim Horton  <[email protected]>
 
         Always show the arrow for text selection services

Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (176682 => 176683)


--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj	2014-12-02 20:30:17 UTC (rev 176683)
@@ -7188,7 +7188,6 @@
     <ClCompile Include="..\page\NavigatorBase.cpp" />
     <ClCompile Include="..\page\OriginAccessEntry.cpp" />
     <ClCompile Include="..\page\Page.cpp" />
-    <ClCompile Include="..\page\PageActivityAssertionToken.cpp" />
     <ClCompile Include="..\page\PageConfiguration.cpp" />
     <ClCompile Include="..\page\PageConsoleClient.cpp" />
     <ClCompile Include="..\page\PageGroup.cpp" />

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (176682 => 176683)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2014-12-02 20:30:17 UTC (rev 176683)
@@ -5593,7 +5593,6 @@
 		CCC2B51415F613060048CDD6 /* DeviceClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CCC2B51015F613060048CDD6 /* DeviceClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		CCC2B51515F613060048CDD6 /* DeviceController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CCC2B51115F613060048CDD6 /* DeviceController.cpp */; };
 		CCC2B51615F613060048CDD6 /* DeviceController.h in Headers */ = {isa = PBXBuildFile; fileRef = CCC2B51215F613060048CDD6 /* DeviceController.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		CD08285C1757250F00EC5FB7 /* PageActivityAssertionToken.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD08285A1757250800EC5FB7 /* PageActivityAssertionToken.cpp */; };
 		CD0EEE0E14743F39003EAFA2 /* AudioDestinationIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD0EEE0B14743E35003EAFA2 /* AudioDestinationIOS.cpp */; };
 		CD127DED14F3097D00E84779 /* WebCoreFullScreenWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD127DEB14F3097900E84779 /* WebCoreFullScreenWindow.mm */; };
 		CD127DEE14F3098400E84779 /* WebCoreFullScreenWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = CD127DEA14F3097900E84779 /* WebCoreFullScreenWindow.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -13051,8 +13050,6 @@
 		CCC2B51015F613060048CDD6 /* DeviceClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceClient.h; sourceTree = "<group>"; };
 		CCC2B51115F613060048CDD6 /* DeviceController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeviceController.cpp; sourceTree = "<group>"; };
 		CCC2B51215F613060048CDD6 /* DeviceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceController.h; sourceTree = "<group>"; };
-		CD08285A1757250800EC5FB7 /* PageActivityAssertionToken.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PageActivityAssertionToken.cpp; sourceTree = "<group>"; };
-		CD08285B1757250800EC5FB7 /* PageActivityAssertionToken.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PageActivityAssertionToken.h; sourceTree = "<group>"; };
 		CD0EEE0A14743E34003EAFA2 /* AudioDestinationIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioDestinationIOS.h; path = ios/AudioDestinationIOS.h; sourceTree = "<group>"; };
 		CD0EEE0B14743E35003EAFA2 /* AudioDestinationIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioDestinationIOS.cpp; path = ios/AudioDestinationIOS.cpp; sourceTree = "<group>"; };
 		CD127DEA14F3097900E84779 /* WebCoreFullScreenWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreFullScreenWindow.h; sourceTree = "<group>"; };
@@ -16671,8 +16668,6 @@
 				00146289103CD1DE000B20DB /* OriginAccessEntry.h */,
 				65FEA86809833ADE00BED4AB /* Page.cpp */,
 				65A21467097A329100B9050A /* Page.h */,
-				CD08285A1757250800EC5FB7 /* PageActivityAssertionToken.cpp */,
-				CD08285B1757250800EC5FB7 /* PageActivityAssertionToken.h */,
 				CD5E5B601A15F156000C609E /* PageConfiguration.cpp */,
 				CD5E5B5E1A15CE54000C609E /* PageConfiguration.h */,
 				DAACB3D916F2416400666135 /* PageConsoleClient.cpp */,
@@ -29110,7 +29105,6 @@
 				FD581FAE1520F91F003A7A75 /* OscillatorNode.cpp in Sources */,
 				1A0D57360A5C77FE007EDD4C /* OverflowEvent.cpp in Sources */,
 				65FEA86909833ADE00BED4AB /* Page.cpp in Sources */,
-				CD08285C1757250F00EC5FB7 /* PageActivityAssertionToken.cpp in Sources */,
 				1477E7760BF4134A00152872 /* PageCache.cpp in Sources */,
 				F3820892147D35F90010BC06 /* PageConsoleAgent.cpp in Sources */,
 				DAED203016F2442B0070EC0F /* PageConsoleClient.cpp in Sources */,

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (176682 => 176683)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2014-12-02 20:30:17 UTC (rev 176683)
@@ -66,7 +66,6 @@
 #include "MediaResourceLoader.h"
 #include "MediaSessionManager.h"
 #include "NetworkingContext.h"
-#include "PageActivityAssertionToken.h"
 #include "PageGroup.h"
 #include "PageThrottler.h"
 #include "ProgressTracker.h"

Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (176682 => 176683)


--- trunk/Source/WebCore/html/HTMLMediaElement.h	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h	2014-12-02 20:30:17 UTC (rev 176683)
@@ -35,6 +35,7 @@
 #include "MediaCanStartListener.h"
 #include "MediaControllerInterface.h"
 #include "MediaPlayer.h"
+#include "PageThrottler.h"
 
 #if ENABLE(VIDEO_TRACK)
 #include "AudioTrack.h"
@@ -65,7 +66,6 @@
 class MediaControls;
 class MediaControlsHost;
 class MediaError;
-class PageActivityAssertionToken;
 class TimeRanges;
 #if ENABLE(ENCRYPTED_MEDIA_V2)
 class MediaKeys;
@@ -899,7 +899,7 @@
 #endif
 
     std::unique_ptr<HTMLMediaSession> m_mediaSession;
-    std::unique_ptr<PageActivityAssertionToken> m_activityToken;
+    PageActivityAssertionToken m_activityToken;
     size_t m_reportedExtraMemoryCost;
 
 #if ENABLE(MEDIA_CONTROLS_SCRIPT)

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (176682 => 176683)


--- trunk/Source/WebCore/loader/FrameLoader.cpp	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp	2014-12-02 20:30:17 UTC (rev 176683)
@@ -85,7 +85,6 @@
 #include "MainFrame.h"
 #include "MemoryCache.h"
 #include "Page.h"
-#include "PageActivityAssertionToken.h"
 #include "PageCache.h"
 #include "PageThrottler.h"
 #include "PageTransitionEvent.h"

Modified: trunk/Source/WebCore/loader/FrameLoader.h (176682 => 176683)


--- trunk/Source/WebCore/loader/FrameLoader.h	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/loader/FrameLoader.h	2014-12-02 20:30:17 UTC (rev 176683)
@@ -38,6 +38,7 @@
 #include "IconURL.h"
 #include "LayoutMilestones.h"
 #include "MixedContentChecker.h"
+#include "PageThrottler.h"
 #include "ResourceHandleTypes.h"
 #include "ResourceLoadNotifier.h"
 #include "SecurityContext.h"
@@ -66,7 +67,6 @@
 class NavigationAction;
 class NetworkingContext;
 class Page;
-class PageActivityAssertionToken;
 class PolicyChecker;
 class ResourceError;
 class ResourceRequest;
@@ -443,7 +443,7 @@
 
     URL m_previousURL;
     RefPtr<HistoryItem> m_requestedHistoryItem;
-    std::unique_ptr<PageActivityAssertionToken> m_activityAssertion;
+    PageActivityAssertionToken m_activityAssertion;
 };
 
 // This function is called by createWindow() in JSDOMWindowBase.cpp, for example, for

Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (176682 => 176683)


--- trunk/Source/WebCore/loader/SubresourceLoader.cpp	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/loader/SubresourceLoader.cpp	2014-12-02 20:30:17 UTC (rev 176683)
@@ -37,7 +37,6 @@
 #include "Logging.h"
 #include "MemoryCache.h"
 #include "Page.h"
-#include "PageActivityAssertionToken.h"
 #include <wtf/Ref.h>
 #include <wtf/RefCountedLeakCounter.h>
 #include <wtf/StdLibExtras.h>

Modified: trunk/Source/WebCore/loader/SubresourceLoader.h (176682 => 176683)


--- trunk/Source/WebCore/loader/SubresourceLoader.h	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/loader/SubresourceLoader.h	2014-12-02 20:30:17 UTC (rev 176683)
@@ -39,7 +39,6 @@
 class CachedResource;
 class CachedResourceLoader;
 class Document;
-class PageActivityAssertionToken;
 class ResourceRequest;
 
 class SubresourceLoader final : public ResourceLoader {

Modified: trunk/Source/WebCore/page/Page.cpp (176682 => 176683)


--- trunk/Source/WebCore/page/Page.cpp	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/page/Page.cpp	2014-12-02 20:30:17 UTC (rev 176683)
@@ -55,7 +55,6 @@
 #include "MediaCanStartListener.h"
 #include "Navigator.h"
 #include "NetworkStateNotifier.h"
-#include "PageActivityAssertionToken.h"
 #include "PageCache.h"
 #include "PageConfiguration.h"
 #include "PageConsoleClient.h"
@@ -195,7 +194,7 @@
 #endif
     , m_alternativeTextClient(pageConfiguration.alternativeTextClient)
     , m_scriptedAnimationsSuspended(false)
-    , m_pageThrottler(*this, m_viewState)
+    , m_pageThrottler(m_viewState)
     , m_consoleClient(std::make_unique<PageConsoleClient>(*this))
 #if ENABLE(REMOTE_INSPECTOR)
     , m_inspectorDebuggable(std::make_unique<PageDebuggable>(*this))

Modified: trunk/Source/WebCore/page/Page.h (176682 => 176683)


--- trunk/Source/WebCore/page/Page.h	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/page/Page.h	2014-12-02 20:30:17 UTC (rev 176683)
@@ -80,7 +80,6 @@
 class InspectorController;
 class MainFrame;
 class MediaCanStartListener;
-class PageActivityAssertionToken;
 class PageConfiguration;
 class PageConsoleClient;
 class PageDebuggable;

Deleted: trunk/Source/WebCore/page/PageActivityAssertionToken.cpp (176682 => 176683)


--- trunk/Source/WebCore/page/PageActivityAssertionToken.cpp	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/page/PageActivityAssertionToken.cpp	2014-12-02 20:30:17 UTC (rev 176683)
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "PageActivityAssertionToken.h"
-
-#include "PageThrottler.h"
-
-namespace WebCore {
-
-PageActivityAssertionToken::PageActivityAssertionToken(PageThrottler& throttler)
-    : m_throttler(throttler.weakPtr())
-{
-    throttler.incrementActivityCount();
-}
-
-PageActivityAssertionToken::~PageActivityAssertionToken()
-{
-    if (PageThrottler* throttler = m_throttler.get())
-        throttler->decrementActivityCount();
-}
-
-} // namespace WebCore
-
-

Deleted: trunk/Source/WebCore/page/PageActivityAssertionToken.h (176682 => 176683)


--- trunk/Source/WebCore/page/PageActivityAssertionToken.h	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/page/PageActivityAssertionToken.h	2014-12-02 20:30:17 UTC (rev 176683)
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PageActivityAssertionToken_h
-#define PageActivityAssertionToken_h
-
-#include <wtf/Noncopyable.h>
-#include <wtf/WeakPtr.h>
-
-namespace WebCore {
-
-class PageThrottler;
-
-class PageActivityAssertionToken {
-    WTF_MAKE_NONCOPYABLE(PageActivityAssertionToken);
-public:
-    PageActivityAssertionToken(PageThrottler&);
-    ~PageActivityAssertionToken();
-
-private:
-    WeakPtr<PageThrottler> m_throttler;
-};
-
-} // namespace WebCore
-
-#endif // PageActivityAssertionToken_h

Modified: trunk/Source/WebCore/page/PageThrottler.cpp (176682 => 176683)


--- trunk/Source/WebCore/page/PageThrottler.cpp	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/page/PageThrottler.cpp	2014-12-02 20:30:17 UTC (rev 176683)
@@ -26,16 +26,12 @@
 #include "config.h"
 #include "PageThrottler.h"
 
-#include "PageActivityAssertionToken.h"
-
 namespace WebCore {
 
-PageThrottler::PageThrottler(Page& page, ViewState::Flags viewState)
-    : m_page(page)
-    , m_viewState(viewState)
-    , m_weakPtrFactory(this)
+PageThrottler::PageThrottler(ViewState::Flags viewState)
+    : m_viewState(viewState)
     , m_hysteresis(*this)
-    , m_activityCount(0)
+    , m_pageActivityCounter([this]() { pageActivityCounterValueDidChange(); })
 {
     updateUserActivity();
 }
@@ -47,36 +43,25 @@
     updateUserActivity();
 }
 
-std::unique_ptr<PageActivityAssertionToken> PageThrottler::mediaActivityToken()
+PageActivityAssertionToken PageThrottler::mediaActivityToken()
 {
-    return std::make_unique<PageActivityAssertionToken>(*this);
+    return m_pageActivityCounter.count();
 }
 
-std::unique_ptr<PageActivityAssertionToken> PageThrottler::pageLoadActivityToken()
+PageActivityAssertionToken PageThrottler::pageLoadActivityToken()
 {
-    return std::make_unique<PageActivityAssertionToken>(*this);
+    return m_pageActivityCounter.count();
 }
 
-void PageThrottler::incrementActivityCount()
+void PageThrottler::pageActivityCounterValueDidChange()
 {
-    // If m_activityCount is nonzero, state must be Started; if m_activityCount is zero, state may be Waiting or Stopped.
-    ASSERT(!!m_activityCount == (m_hysteresis.state() == HysteresisState::Started));
-
-    if (!m_activityCount++)
+    if (m_pageActivityCounter.value())
         m_hysteresis.start();
-
-    ASSERT(m_activityCount && m_hysteresis.state() == HysteresisState::Started);
-}
-
-void PageThrottler::decrementActivityCount()
-{
-    ASSERT(m_activityCount && m_hysteresis.state() == HysteresisState::Started);
-
-    if (!--m_activityCount)
+    else
         m_hysteresis.stop();
 
-    // If m_activityCount is nonzero, state must be Started; if m_activityCount is zero, state may be Waiting or Stopped.
-    ASSERT(!!m_activityCount == (m_hysteresis.state() == HysteresisState::Started));
+    // If the counter is nonzero, state must be Started; if the counter is zero, state may be Waiting or Stopped.
+    ASSERT(!!m_pageActivityCounter.value() == (m_hysteresis.state() == HysteresisState::Started));
 }
 
 void PageThrottler::updateUserActivity()

Modified: trunk/Source/WebCore/page/PageThrottler.h (176682 => 176683)


--- trunk/Source/WebCore/page/PageThrottler.h	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Source/WebCore/page/PageThrottler.h	2014-12-02 20:30:17 UTC (rev 176683)
@@ -30,31 +30,27 @@
 
 #include "UserActivity.h"
 #include "ViewState.h"
-#include <wtf/WeakPtr.h>
+#include <wtf/RefCounter.h>
 
 namespace WebCore {
 
-class Page;
-class PageActivityAssertionToken;
+typedef RefPtr<RefCounter::Count> PageActivityAssertionToken;
 
 class PageThrottler {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    PageThrottler(Page&, ViewState::Flags);
+    PageThrottler(ViewState::Flags);
 
     void createUserActivity();
     void setViewState(ViewState::Flags);
 
     void didReceiveUserInput() { m_hysteresis.impulse(); }
     void pluginDidEvaluateWhileAudioIsPlaying() { m_hysteresis.impulse(); }
-    std::unique_ptr<PageActivityAssertionToken> mediaActivityToken();
-    std::unique_ptr<PageActivityAssertionToken> pageLoadActivityToken();
+    PageActivityAssertionToken mediaActivityToken();
+    PageActivityAssertionToken pageLoadActivityToken();
 
 private:
-    friend class PageActivityAssertionToken;
-    WeakPtr<PageThrottler> weakPtr() { return m_weakPtrFactory.createWeakPtr(); }
-    void incrementActivityCount();
-    void decrementActivityCount();
+    void pageActivityCounterValueDidChange();
 
     void updateUserActivity();
 
@@ -62,12 +58,10 @@
     WEBCORE_EXPORT void started();
     void stopped();
 
-    Page& m_page;
     ViewState::Flags m_viewState;
-    WeakPtrFactory<PageThrottler> m_weakPtrFactory;
     HysteresisActivity<PageThrottler> m_hysteresis;
     std::unique_ptr<UserActivity::Impl> m_activity;
-    size_t m_activityCount;
+    RefCounter m_pageActivityCounter;
 };
 
 }

Modified: trunk/Tools/ChangeLog (176682 => 176683)


--- trunk/Tools/ChangeLog	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Tools/ChangeLog	2014-12-02 20:30:17 UTC (rev 176683)
@@ -1,3 +1,17 @@
+2014-12-02  Gavin Barraclough  <[email protected]>
+
+        Generalize PageActivityAssertionToken
+        https://bugs.webkit.org/show_bug.cgi?id=139106
+
+        Reviewed by Sam Weinig.
+
+        Add an API test for WTF::RefCounter.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WTF/RefCounter.cpp: Added.
+        (TestWebKitAPI::TEST):
+            - added RefCounter test.
+
 2014-12-02  Alexey Proskuryakov  <[email protected]>
 
         [Mac, iOS] Crash log application information contains latest main frame URL instead of test URL

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (176682 => 176683)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2014-12-02 19:49:34 UTC (rev 176682)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2014-12-02 20:30:17 UTC (rev 176683)
@@ -134,6 +134,7 @@
 		7CFBCADF1743234F00B2BFCF /* WillLoad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CFBCADD1743234F00B2BFCF /* WillLoad.cpp */; };
 		7CFBCAE51743238F00B2BFCF /* WillLoad_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CFBCAE31743238E00B2BFCF /* WillLoad_Bundle.cpp */; };
 		81B50193140F232300D9EB58 /* StringBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 81B50192140F232300D9EB58 /* StringBuilder.cpp */; };
+		86BD19981A2DB05B006DCF0A /* RefCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86BD19971A2DB05B006DCF0A /* RefCounter.cpp */; };
 		8A2C750E16CED9550024F352 /* ResizeWindowAfterCrash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A2C750D16CED9550024F352 /* ResizeWindowAfterCrash.cpp */; };
 		8A3AF93B16C9ED2700D248C1 /* ReloadPageAfterCrash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A3AF93A16C9ED2700D248C1 /* ReloadPageAfterCrash.cpp */; };
 		8AA28C1A16D2FA7B002FF4DB /* LoadPageOnCrash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8AA28C1916D2FA7B002FF4DB /* LoadPageOnCrash.cpp */; };
@@ -496,6 +497,7 @@
 		7CFBCADD1743234F00B2BFCF /* WillLoad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillLoad.cpp; sourceTree = "<group>"; };
 		7CFBCAE31743238E00B2BFCF /* WillLoad_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillLoad_Bundle.cpp; sourceTree = "<group>"; };
 		81B50192140F232300D9EB58 /* StringBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringBuilder.cpp; sourceTree = "<group>"; };
+		86BD19971A2DB05B006DCF0A /* RefCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefCounter.cpp; sourceTree = "<group>"; };
 		8A2C750D16CED9550024F352 /* ResizeWindowAfterCrash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResizeWindowAfterCrash.cpp; sourceTree = "<group>"; };
 		8A3AF93A16C9ED2700D248C1 /* ReloadPageAfterCrash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReloadPageAfterCrash.cpp; sourceTree = "<group>"; };
 		8AA28C1916D2FA7B002FF4DB /* LoadPageOnCrash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadPageOnCrash.cpp; sourceTree = "<group>"; };
@@ -961,6 +963,7 @@
 				1AFDE6541953B2C000C48FFA /* Optional.cpp */,
 				0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */,
 				93A427AA180DA26400CD24D7 /* Ref.cpp */,
+				86BD19971A2DB05B006DCF0A /* RefCounter.cpp */,
 				93A427AD180DA60F00CD24D7 /* RefLogger.h */,
 				93A427A8180D9B0700CD24D7 /* RefPtr.cpp */,
 				CD5393C91757BAC400C07123 /* SHA1.cpp */,
@@ -1387,6 +1390,7 @@
 				CDC2C71517970DDB00E627FB /* TimeRanges.cpp in Sources */,
 				51FCF79A1534AC6D00104491 /* ShouldGoToBackForwardListItem.cpp in Sources */,
 				1AFDE6561953B2C000C48FFA /* Optional.cpp in Sources */,
+				86BD19981A2DB05B006DCF0A /* RefCounter.cpp in Sources */,
 				C540F776152E4DA000A40C8C /* SimplifyMarkup.mm in Sources */,
 				4A410F4C19AF7BD6002EBAB5 /* UserMedia.cpp in Sources */,
 				C02B77F2126612140026BF0F /* SpacebarScrolling.cpp in Sources */,

Added: trunk/Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp (0 => 176683)


--- trunk/Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/RefCounter.cpp	2014-12-02 20:30:17 UTC (rev 176683)
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <wtf/Ref.h>
+#include <wtf/RefCounter.h>
+#include <wtf/text/WTFString.h>
+
+namespace TestWebKitAPI {
+
+static const int CallbackExpected = 0xC0FFEE;
+static const int CallbackNotExpected = 0xDECAF;
+
+TEST(WTF, RefCounter)
+{
+    // RefCounter API is pretty simple, containing the following 4 methods to test:
+    //
+    // 1) RefCounter(std::function<void()>);
+    // 2) ~RefCounter();
+    // 3) PassRef<Count> count() const;
+    // 4) unsigned value() const;
+    //
+    // We'll test:
+    // 1) Construction:
+    //   1a) with a callback
+    //   1b) without a callback
+    // 2) Destruction where the RefCounter::Count has:
+    //   2a) a non-zero reference count (Count outlives RefCounter).
+    //   2b) a zero reference count (Count is deleted by RefCounter's destructor).
+    // 3) Call count to ref/deref the Count object, where:
+    //   3a) ref with callback from 0 -> 1.
+    //   3b) ref with callback from 1 -> >1.
+    //   3c) deref with callback from >1 -> 1.
+    //   3d) deref with callback from 1 -> 0.
+    //   3d) deref with callback from 1 -> 0.
+    //   3e) ref with callback from 1 -> >1 AFTER RefCounter has been destroyed.
+    //   3f) deref with callback from >1 -> 1 AFTER RefCounter has been destroyed.
+    //   3g) deref with callback from 1 -> 0 AFTER RefCounter has been destroyed.
+    //   3h) ref without callback
+    //   3i) deref without callback
+    //   3j) ref using a Ref rather than a RefPtr (make sure there is no unnecessary reference count churn).
+    //   3k) deref using a Ref rather than a RefPtr (make sure there is no unnecessary reference count churn).
+    // 4) Test the value of the counter:
+    //   4a) at construction.
+    //   4b) as read within the callback.
+    //   4c) as read after the ref/deref.
+
+    // These values will outlive the following block.
+    int callbackValue = CallbackNotExpected;
+    RefPtr<RefCounter::Count> incTo1Again;
+
+    {
+        // Testing (1a) - Construction with a callback.
+        RefCounter* counterPtr = nullptr;
+        RefCounter counter([&]() {
+            // Check that the callback is called at the expected times, and the correct number of times.
+            EXPECT_EQ(callbackValue, CallbackExpected);
+            // return the value of the counter in the callback.
+            callbackValue = counterPtr->value();
+        });
+        counterPtr = &counter;
+        // Testing (4a) - after construction value() is 0.
+        EXPECT_EQ(0, static_cast<int>(counter.value()));
+
+        // Testing (3a) - ref with callback from 0 -> 1.
+        callbackValue = CallbackExpected;
+        RefPtr<RefCounter::Count> incTo1(counter.count());
+        // Testing (4b) & (4c) - values within & after callback.
+        EXPECT_EQ(1, callbackValue);
+        EXPECT_EQ(1, static_cast<int>(counter.value()));
+
+        // Testing (3b) - ref with callback from 1 -> 2.
+        callbackValue = CallbackExpected;
+        RefPtr<RefCounter::Count> incTo2(incTo1);
+        // Testing (4b) & (4c) - values within & after callback.
+        EXPECT_EQ(2, callbackValue);
+        EXPECT_EQ(2, static_cast<int>(counter.value()));
+
+        // Testing (3c) - deref with callback from >1 -> 1.
+        callbackValue = CallbackExpected;
+        incTo1.clear();
+        // Testing (4b) & (4c) - values within & after callback.
+        EXPECT_EQ(1, callbackValue);
+        EXPECT_EQ(1, static_cast<int>(counter.value()));
+
+        {
+            // Testing (3j) - ref using a Ref rather than a RefPtr.
+            callbackValue = CallbackExpected;
+            Ref<RefCounter::Count> incTo2Again(counter.count());
+            // Testing (4b) & (4c) - values within & after callback.
+            EXPECT_EQ(2, callbackValue);
+            EXPECT_EQ(2, static_cast<int>(counter.value()));
+            // Testing (3k) - deref using a Ref rather than a RefPtr.
+            callbackValue = CallbackExpected;
+        }
+        EXPECT_EQ(1, callbackValue);
+        EXPECT_EQ(1, static_cast<int>(counter.value()));
+        // Testing (4b) & (4c) - values within & after callback.
+
+        // Testing (3d) - deref with callback from 1 -> 0.
+        callbackValue = CallbackExpected;
+        incTo2.clear();
+        // Testing (4b) & (4c) - values within & after callback.
+        EXPECT_EQ(0, callbackValue);
+        EXPECT_EQ(0, static_cast<int>(counter.value()));
+
+        // Testing (2a) - Destruction where the RefCounter::Count has a non-zero reference count.
+        callbackValue = CallbackExpected;
+        incTo1Again = counter.count();
+        EXPECT_EQ(1, callbackValue);
+        EXPECT_EQ(1, static_cast<int>(counter.value()));
+        callbackValue = CallbackNotExpected;
+    }
+
+    // Testing (3e) - ref with callback from 1 -> >1 AFTER RefCounter has been destroyed.
+    RefPtr<RefCounter::Count> incTo2Again = incTo1Again;
+    // Testing (3f) - deref with callback from >1 -> 1 AFTER RefCounter has been destroyed.
+    incTo1Again.clear();
+    // Testing (3g) - deref with callback from 1 -> 0 AFTER RefCounter has been destroyed.
+    incTo2Again.clear();
+
+    // Testing (1b) - Construction without a callback.
+    RefCounter counter;
+    // Testing (4a) - after construction value() is 0.
+    EXPECT_EQ(0, static_cast<int>(counter.value()));
+    // Testing (3h) - ref without callback
+    RefPtr<RefCounter::Count> incTo1(counter.count());
+    // Testing (4c) - value as read after the ref.
+    EXPECT_EQ(1, static_cast<int>(counter.value()));
+    // Testing (3i) - deref without callback
+    incTo1.clear();
+    // Testing (4c) - value as read after the deref.
+    EXPECT_EQ(0, static_cast<int>(counter.value()));
+    // Testing (2b) - Destruction where the RefCounter::Count has a zero reference count.
+    // ... not a lot to test here! - we can at least ensure this code path is run & we don't crash!
+}
+
+} // namespace TestWebKitAPI
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to