Generalize DocumentWeakReference into WTF::WeakPtr
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Jan 2013 21:35:08 +0000 (21:35 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Jan 2013 21:35:08 +0000 (21:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=106854

Reviewed by Darin Adler.

Source/WebCore:

This patch replaces DocumentWeakReference with WeakPtr. There should be
no change in behavior.

* dom/Document.cpp:
(WebCore):
(WebCore::Document::Document):
(WebCore::Document::~Document):
(WebCore::PerformTaskContext::PerformTaskContext):
(PerformTaskContext):
(WebCore::Document::didReceiveTask):
(WebCore::Document::postTask):
(WebCore::Document::reportMemoryUsage):
* dom/Document.h:
(WebCore):
(Document):

Source/WTF:

This patch adds a simple WeakPtr object to WTF. To use WeakPtr, objects
must hold a WeakPtrFactory member variable, which clears the WeakPtrs
when the object is destructed. The underlying storage is a
ThreadSafeRefCounted "WeakReference" object, which is shared by all the
WeakPtrs.

WeakPtr is a generalization of DocumentWeakReference, which is used to
check whether the Document object is alive when tasks arive on the main
thread from worker threads. We plan to use a similar pattern in the
threaded HTML parser, but we want to send tasks to objects other than
Document.

* GNUmakefile.list.am:
* WTF.gypi:
* WTF.pro:
* WTF.vcproj/WTF.vcproj:
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/WeakPtr.h: Added.
(WeakReference):
    - The ThreadSafeRefCounted object shared by all the WeakPtr
      instances. This patch uses ThreadSafeRefCounted so that we can
      use WeakPtrs to cancel cross-thread messages.
(WTF::WeakReference::create):
(WTF::WeakReference::get):
(WTF::WeakReference::clear):
    - When the object is destroyed, WeakPtrFactory calls this function
      to clear all the WeakPtrs.
(WTF::WeakReference::WeakReference):
(WTF::WeakPtr::WeakPtr):
(WTF::WeakPtr::get):
    - We might want to add implicit conversions and Boolean operators
      in the future, but I've kept this class simple for now.
(WTF::WeakPtrFactory::WeakPtrFactory):
(WTF::WeakPtrFactory::~WeakPtrFactory):
(WTF::WeakPtrFactory::createWeakPtr):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@139780 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/GNUmakefile.list.am
Source/WTF/WTF.gypi
Source/WTF/WTF.pro
Source/WTF/WTF.vcproj/WTF.vcproj
Source/WTF/WTF.xcodeproj/project.pbxproj
Source/WTF/wtf/CMakeLists.txt
Source/WTF/wtf/WeakPtr.h [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h

index 6a1799f4b4a5c6cc01e160168b4c58bbe24aa6eb..46a85a3064d1d7e0720f727b4c1d33fd18e911d2 100644 (file)
@@ -1,3 +1,47 @@
+2013-01-15  Adam Barth  <abarth@webkit.org>
+
+        Generalize DocumentWeakReference into WTF::WeakPtr
+        https://bugs.webkit.org/show_bug.cgi?id=106854
+
+        Reviewed by Darin Adler.
+
+        This patch adds a simple WeakPtr object to WTF. To use WeakPtr, objects
+        must hold a WeakPtrFactory member variable, which clears the WeakPtrs
+        when the object is destructed. The underlying storage is a
+        ThreadSafeRefCounted "WeakReference" object, which is shared by all the
+        WeakPtrs.
+
+        WeakPtr is a generalization of DocumentWeakReference, which is used to
+        check whether the Document object is alive when tasks arive on the main
+        thread from worker threads. We plan to use a similar pattern in the
+        threaded HTML parser, but we want to send tasks to objects other than
+        Document.
+
+        * GNUmakefile.list.am:
+        * WTF.gypi:
+        * WTF.pro:
+        * WTF.vcproj/WTF.vcproj:
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/CMakeLists.txt:
+        * wtf/WeakPtr.h: Added.
+        (WeakReference):
+            - The ThreadSafeRefCounted object shared by all the WeakPtr
+              instances. This patch uses ThreadSafeRefCounted so that we can
+              use WeakPtrs to cancel cross-thread messages.
+        (WTF::WeakReference::create):
+        (WTF::WeakReference::get):
+        (WTF::WeakReference::clear):
+            - When the object is destroyed, WeakPtrFactory calls this function
+              to clear all the WeakPtrs.
+        (WTF::WeakReference::WeakReference):
+        (WTF::WeakPtr::WeakPtr):
+        (WTF::WeakPtr::get):
+            - We might want to add implicit conversions and Boolean operators
+              in the future, but I've kept this class simple for now.
+        (WTF::WeakPtrFactory::WeakPtrFactory):
+        (WTF::WeakPtrFactory::~WeakPtrFactory):
+        (WTF::WeakPtrFactory::createWeakPtr):
+
 2013-01-12  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         Use __sync_add_and_fetch instead of __gnu_cxx::__exchange_and_add
index 7252b35523f9f3d18ff3ee82e0e0604119107fbc..187081faf63b9aa63b71a5260fdcf3024ae33567 100644 (file)
@@ -193,6 +193,7 @@ wtf_sources += \
     Source/WTF/wtf/VectorTraits.h \
     Source/WTF/wtf/WTFThreadData.cpp \
     Source/WTF/wtf/WTFThreadData.h \
+    Source/WTF/wtf/WeakPtr.h \
     Source/WTF/wtf/dtoa.cpp \
     Source/WTF/wtf/dtoa.h \
     Source/WTF/wtf/dtoa/bignum-dtoa.cc \
index 6cc3b8a3e039ab81aae89a25878e8658d29cc9c1..5336e096809628e626f5f0efbec217ade3c06138 100644 (file)
             'wtf/Vector.h',
             'wtf/VectorTraits.h',
             'wtf/WTFThreadData.h',
+            'wtf/WeakPtr.h',
             'wtf/dtoa.h',
             'wtf/dtoa/bignum-dtoa.h',
             'wtf/dtoa/bignum.h',
index 366194bbd32b98f4d7dbd2a184989047dcece366..c929c6816aed6d5fd7cdc93c5e49f39c056fdafd 100644 (file)
@@ -188,7 +188,8 @@ HEADERS += \
     Vector.h \
     VectorTraits.h \
     VMTags.h \
-    WTFThreadData.h
+    WTFThreadData.h \
+    WeakPtr.h
 
 unix: HEADERS += ThreadIdentifierDataPthreads.h
 
index ebc8194ad0a56f5b582646001c8bb53336954f38..f73b6fd9e11538febe48988d8e1d5166ab65f98e 100644 (file)
                        RelativePath="..\wtf\WTFThreadData.h"
                        >
                </File>
+               <File
+                       RelativePath="..\wtf\WeakPtr.h"
+                       >
+               </File>
        </Files>
        <Globals>
        </Globals>
index 061ecc7c0dbd9df267e2248593b78cacb382fd53..999f4c9ea000eb9a9e2a182f0855632233878cfd 100644 (file)
@@ -72,6 +72,7 @@
                7E29C33E15FFD79B00516D61 /* ObjcRuntimeExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E29C33D15FFD79B00516D61 /* ObjcRuntimeExtras.h */; };
                8134013815B092FD001FF0B8 /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8134013615B092FD001FF0B8 /* Base64.cpp */; };
                8134013915B092FD001FF0B8 /* Base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 8134013715B092FD001FF0B8 /* Base64.h */; };
+               974CFC8E16A4F327006D5404 /* WeakPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 974CFC8D16A4F327006D5404 /* WeakPtr.h */; };
                A876DBD8151816E500DADB95 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A876DBD7151816E500DADB95 /* Platform.h */; };
                A8A4737F151A825B004123FF /* Alignment.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A47254151A825A004123FF /* Alignment.h */; };
                A8A47380151A825B004123FF /* AlwaysInline.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A47255151A825A004123FF /* AlwaysInline.h */; };
                7E29C33D15FFD79B00516D61 /* ObjcRuntimeExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjcRuntimeExtras.h; sourceTree = "<group>"; };
                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>"; };
+               974CFC8D16A4F327006D5404 /* WeakPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakPtr.h; sourceTree = "<group>"; };
                A876DBD7151816E500DADB95 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Platform.h; sourceTree = "<group>"; };
                A8A47254151A825A004123FF /* Alignment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Alignment.h; sourceTree = "<group>"; };
                A8A47255151A825A004123FF /* AlwaysInline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlwaysInline.h; sourceTree = "<group>"; };
                                A8A47370151A825B004123FF /* Vector.h */,
                                A8A47371151A825B004123FF /* VectorTraits.h */,
                                A8A47372151A825B004123FF /* VMTags.h */,
+                               974CFC8D16A4F327006D5404 /* WeakPtr.h */,
                                A8A4737A151A825B004123FF /* WTFThreadData.cpp */,
                                A8A4737B151A825B004123FF /* WTFThreadData.h */,
                        );
                                A8A4747E151A825B004123FF /* Vector.h in Headers */,
                                A8A4747F151A825B004123FF /* VectorTraits.h in Headers */,
                                A8A47480151A825B004123FF /* VMTags.h in Headers */,
+                               974CFC8E16A4F327006D5404 /* WeakPtr.h in Headers */,
                                A8A47446151A825B004123FF /* WTFString.h in Headers */,
                                A8A47487151A825B004123FF /* WTFThreadData.h in Headers */,
                        );
index 42c2dad56e36611af88db695634232b6d6a1be23..b484836f884ad307de5ad5d99a2bdec8b8d724b5 100644 (file)
@@ -122,6 +122,7 @@ set(WTF_HEADERS
     Vector.h
     VectorTraits.h
     WTFThreadData.h
+    WeakPtr.h
     dtoa.h
 
     dtoa/bignum-dtoa.h
diff --git a/Source/WTF/wtf/WeakPtr.h b/Source/WTF/wtf/WeakPtr.h
new file mode 100644 (file)
index 0000000..0e64506
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 Google, 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. ``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
+ * 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 WTF_WeakPtr_h
+#define WTF_WeakPtr_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/ThreadSafeRefCounted.h>
+#include <wtf/Threading.h>
+
+namespace WTF {
+
+namespace Internal {
+
+template<typename T>
+class WeakReference : public ThreadSafeRefCounted<WeakReference<T> > {
+    WTF_MAKE_NONCOPYABLE(WeakReference<T>);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static PassRefPtr<WeakReference<T> > create(T* ptr) { return adoptRef(new WeakReference(ptr)); }
+
+    T* get() const
+    {
+        ASSERT(m_boundThread == currentThread());
+        return m_ptr;
+    }
+
+    void clear()
+    {
+        ASSERT(m_boundThread == currentThread());
+        m_ptr = 0;
+    }
+
+private:
+    explicit WeakReference(T* ptr)
+        : m_ptr(ptr)
+#ifndef NDEBUG
+        , m_boundThread(currentThread())
+#endif
+    {
+    }
+
+    T* m_ptr;
+#ifndef NDEBUG
+    ThreadIdentifier m_boundThread;
+#endif
+};
+
+}
+
+template<typename T>
+class WeakPtr {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    WeakPtr() { }
+    WeakPtr(PassRefPtr<Internal::WeakReference<T> > ref) : m_ref(ref) { }
+
+    T* get() const { return m_ref->get(); }
+
+private:
+    RefPtr<Internal::WeakReference<T> > m_ref;
+};
+
+template<typename T>
+class WeakPtrFactory {
+    WTF_MAKE_NONCOPYABLE(WeakPtrFactory<T>);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit WeakPtrFactory(T* ptr) { m_ref = Internal::WeakReference<T>::create(ptr); }
+    ~WeakPtrFactory() { m_ref->clear(); }
+
+    // We should consider having createWeakPtr populate m_ref the first time createWeakPtr is called.
+    WeakPtr<T> createWeakPtr() { return WeakPtr<T>(m_ref); }
+
+private:
+    RefPtr<Internal::WeakReference<T> > m_ref;
+};
+
+} // namespace WTF
+
+using WTF::WeakPtr;
+using WTF::WeakPtrFactory;
+
+#endif
index 4f8b495d7ce1b84cf0f10140a5a1a6016d6b40a4..01aa94d63591792d28f1037529a8349752b92aa1 100644 (file)
@@ -1,3 +1,26 @@
+2013-01-15  Adam Barth  <abarth@webkit.org>
+
+        Generalize DocumentWeakReference into WTF::WeakPtr
+        https://bugs.webkit.org/show_bug.cgi?id=106854
+
+        Reviewed by Darin Adler.
+
+        This patch replaces DocumentWeakReference with WeakPtr. There should be
+        no change in behavior.
+
+        * dom/Document.cpp:
+        (WebCore):
+        (WebCore::Document::Document):
+        (WebCore::Document::~Document):
+        (WebCore::PerformTaskContext::PerformTaskContext):
+        (PerformTaskContext):
+        (WebCore::Document::didReceiveTask):
+        (WebCore::Document::postTask):
+        (WebCore::Document::reportMemoryUsage):
+        * dom/Document.h:
+        (WebCore):
+        (Document):
+
 2013-01-15  James Simonsen  <simonjam@chromium.org>
 
         [User Timing] INVALID_ACCESS_ERR should be thrown if measuring from a 0 Nav Timing value
index b2fa8a7de8cfd9ce5db43b0b6d92ef98a740becc..0d29fdbb02af5283f9a9936b6235ef82ac592af4 100644 (file)
@@ -404,35 +404,6 @@ static void printNavigationErrorMessage(Frame* frame, const KURL& activeURL, con
 
 static HashSet<Document*>* documentsThatNeedStyleRecalc = 0;
 
-class DocumentWeakReference : public ThreadSafeRefCounted<DocumentWeakReference> {
-public:
-    static PassRefPtr<DocumentWeakReference> create(Document* document)
-    {
-        return adoptRef(new DocumentWeakReference(document));
-    }
-
-    Document* document()
-    {
-        ASSERT(isMainThread());
-        return m_document;
-    }
-
-    void clear()
-    {
-        ASSERT(isMainThread());
-        m_document = 0;
-    }
-
-private:
-    DocumentWeakReference(Document* document)
-        : m_document(document)
-    {
-        ASSERT(isMainThread());
-    }
-
-    Document* m_document;
-};
-
 uint64_t Document::s_globalTreeVersion = 0;
 
 Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
@@ -481,7 +452,7 @@ Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
     , m_isSrcdocDocument(false)
     , m_renderer(0)
     , m_eventQueue(DocumentEventQueue::create(this))
-    , m_weakReference(DocumentWeakReference::create(this))
+    , m_weakFactory(this)
     , m_idAttributeName(idAttr)
 #if ENABLE(FULLSCREEN_API)
     , m_areKeysEnabledInFullScreen(0)
@@ -657,8 +628,6 @@ Document::~Document()
     if (m_elemSheet)
         m_elemSheet->clearOwnerNode();
 
-    m_weakReference->clear();
-
     clearStyleResolver(); // We need to destory CSSFontSelector before destroying m_cachedResourceLoader.
 
     // It's possible for multiple Documents to end up referencing the same CachedResourceLoader (e.g., SVGImages
@@ -4808,13 +4777,13 @@ void Document::addMessage(MessageSource source, MessageLevel level, const String
 struct PerformTaskContext {
     WTF_MAKE_NONCOPYABLE(PerformTaskContext); WTF_MAKE_FAST_ALLOCATED;
 public:
-    PerformTaskContext(PassRefPtr<DocumentWeakReference> documentReference, PassOwnPtr<ScriptExecutionContext::Task> task)
-        : documentReference(documentReference)
+    PerformTaskContext(WeakPtr<Document> document, PassOwnPtr<ScriptExecutionContext::Task> task)
+        : documentReference(document)
         , task(task)
     {
     }
 
-    RefPtr<DocumentWeakReference> documentReference;
+    WeakPtr<Document> documentReference;
     OwnPtr<ScriptExecutionContext::Task> task;
 };
 
@@ -4825,7 +4794,7 @@ void Document::didReceiveTask(void* untypedContext)
     OwnPtr<PerformTaskContext> context = adoptPtr(static_cast<PerformTaskContext*>(untypedContext));
     ASSERT(context);
 
-    Document* document = context->documentReference->document();
+    Document* document = context->documentReference.get();
     if (!document)
         return;
 
@@ -4840,7 +4809,7 @@ void Document::didReceiveTask(void* untypedContext)
 
 void Document::postTask(PassOwnPtr<Task> task)
 {
-    callOnMainThread(didReceiveTask, new PerformTaskContext(m_weakReference, task));
+    callOnMainThread(didReceiveTask, new PerformTaskContext(m_weakFactory.createWeakPtr(), task));
 }
 
 void Document::pendingTasksTimerFired(Timer<Document>*)
@@ -5992,7 +5961,7 @@ void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 #endif
     info.addMember(m_selectorQueryCache);
     info.addMember(m_renderer);
-    info.addMember(m_weakReference);
+    info.addMember(m_weakFactory);
     info.addMember(m_idAttributeName);
 #if ENABLE(FULLSCREEN_API)
     info.addMember(m_fullScreenElement);
index 0b809e53752af4e69d6c0a899ee72e0a927001d6..0b2bdd7e28f6cd1d154c123c4d7a6b2e604cf993 100644 (file)
@@ -53,6 +53,7 @@
 #include <wtf/OwnPtr.h>
 #include <wtf/PassOwnPtr.h>
 #include <wtf/PassRefPtr.h>
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
@@ -81,7 +82,6 @@ class DocumentParser;
 class DocumentSharedObjectPool;
 class DocumentStyleSheetCollection;
 class DocumentType;
-class DocumentWeakReference;
 class Element;
 class EntityReference;
 class Event;
@@ -1475,7 +1475,7 @@ private:
     RenderObject* m_renderer;
     RefPtr<DocumentEventQueue> m_eventQueue;
 
-    RefPtr<DocumentWeakReference> m_weakReference;
+    WeakPtrFactory<Document> m_weakFactory;
 
     HashSet<MediaCanStartListener*> m_mediaCanStartListeners;