BackgroundHTMLParser::sendTokensToMainThread should use bind
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Jan 2013 22:15:54 +0000 (22:15 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Jan 2013 22:15:54 +0000 (22:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=107637

Reviewed by Eric Seidel.

Source/WebCore:

This patch replaces our hand-written implementation of bind for
didReceiveTokensFromBackgroundParser with bind from Functional.h. To
use the generic version of bind, we need to switch to using WeakPtr to
hold a reference to the main thread parser in the BackgroundHTMLParser.

* html/parser/BackgroundHTMLParser.cpp:
(WebCore::BackgroundHTMLParser::BackgroundHTMLParser):
(WebCore::BackgroundHTMLParser::sendTokensToMainThread):
(WebCore::BackgroundHTMLParser::createPartial):
* html/parser/BackgroundHTMLParser.h:
(WebCore::BackgroundHTMLParser::create):
(BackgroundHTMLParser):
(ParserMap):
* html/parser/HTMLDocumentParser.cpp:
(WebCore::HTMLDocumentParser::HTMLDocumentParser):
(WebCore::HTMLDocumentParser::startBackgroundParser):
(WebCore::HTMLDocumentParser::stopBackgroundParser):
* html/parser/HTMLDocumentParser.h:
(HTMLDocumentParser):

Source/WTF:

* wtf/Functional.h:
    - I had to re-work the approach to validating WeakPtr |this|
      arguments a bit. Previously you couldn't pass a WeakPtr as a
      non-|this| argument to a function because we would try to unwrap
      it into a raw pointer.
* wtf/WeakPtr.h:
(WTF::WeakPtrFactory::revokeAll):
(WeakPtrFactory):
    - Let clients revoke all outstanding WeakPtrs without needing to
      destroy the WeakPtrFactory.
* wtf/chromium/MainThreadChromium.cpp:
(WTF::callFunctionObject):
(WTF::callOnMainThread):
    - Implement callOnMainThread for Function objects. The non-Chromium
      implementation of MainThread.cpp already implements this feature.

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

Source/WTF/ChangeLog
Source/WTF/wtf/Functional.h
Source/WTF/wtf/WeakPtr.h
Source/WTF/wtf/chromium/MainThreadChromium.cpp
Source/WebCore/ChangeLog
Source/WebCore/html/parser/BackgroundHTMLParser.cpp
Source/WebCore/html/parser/BackgroundHTMLParser.h
Source/WebCore/html/parser/HTMLDocumentParser.cpp
Source/WebCore/html/parser/HTMLDocumentParser.h

index 6877149..66b4bcc 100644 (file)
@@ -1,3 +1,26 @@
+2013-01-23  Adam Barth  <abarth@webkit.org>
+
+        BackgroundHTMLParser::sendTokensToMainThread should use bind
+        https://bugs.webkit.org/show_bug.cgi?id=107637
+
+        Reviewed by Eric Seidel.
+
+        * wtf/Functional.h:
+            - I had to re-work the approach to validating WeakPtr |this|
+              arguments a bit. Previously you couldn't pass a WeakPtr as a
+              non-|this| argument to a function because we would try to unwrap
+              it into a raw pointer.
+        * wtf/WeakPtr.h:
+        (WTF::WeakPtrFactory::revokeAll):
+        (WeakPtrFactory):
+            - Let clients revoke all outstanding WeakPtrs without needing to
+              destroy the WeakPtrFactory.
+        * wtf/chromium/MainThreadChromium.cpp:
+        (WTF::callFunctionObject):
+        (WTF::callOnMainThread):
+            - Implement callOnMainThread for Function objects. The non-Chromium
+              implementation of MainThread.cpp already implements this feature.
+
 2013-01-23  Justin Schuh  <jschuh@chromium.org>
 
         [CHROMIUM] Suppress c4267 build warnings in WTF for Win64 targets
index c5b7124..0d9169f 100644 (file)
@@ -83,7 +83,6 @@ class FunctionWrapper<R (*)()> {
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = false;
-    static const bool shouldValidateFirstParameter = false;
 
     explicit FunctionWrapper(R (*function)())
         : m_function(function)
@@ -104,7 +103,6 @@ class FunctionWrapper<R (*)(P1)> {
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = false;
-    static const bool shouldValidateFirstParameter = false;
 
     explicit FunctionWrapper(R (*function)(P1))
         : m_function(function)
@@ -125,7 +123,6 @@ class FunctionWrapper<R (*)(P1, P2)> {
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = false;
-    static const bool shouldValidateFirstParameter = false;
 
     explicit FunctionWrapper(R (*function)(P1, P2))
         : m_function(function)
@@ -146,7 +143,6 @@ class FunctionWrapper<R (*)(P1, P2, P3)> {
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = false;
-    static const bool shouldValidateFirstParameter = false;
 
     explicit FunctionWrapper(R (*function)(P1, P2, P3))
         : m_function(function)
@@ -167,7 +163,6 @@ class FunctionWrapper<R (C::*)()> {
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
-    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)())
         : m_function(function)
@@ -179,6 +174,14 @@ public:
         return (c->*m_function)();
     }
 
+    R operator()(const WeakPtr<C>& c)
+    {
+        C* obj = c.get();
+        if (!obj)
+            return R();
+        return (obj->*m_function)();
+    }
+
 private:
     R (C::*m_function)();
 };
@@ -188,7 +191,6 @@ class FunctionWrapper<R (C::*)(P1)> {
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
-    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)(P1))
         : m_function(function)
@@ -200,6 +202,14 @@ public:
         return (c->*m_function)(p1);
     }
 
+    R operator()(const WeakPtr<C>& c, P1 p1)
+    {
+        C* obj = c.get();
+        if (!obj)
+            return R();
+        return (obj->*m_function)(p1);
+    }
+
 private:
     R (C::*m_function)(P1);
 };
@@ -209,7 +219,6 @@ class FunctionWrapper<R (C::*)(P1, P2)> {
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
-    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)(P1, P2))
         : m_function(function)
@@ -221,6 +230,14 @@ public:
         return (c->*m_function)(p1, p2);
     }
 
+    R operator()(const WeakPtr<C>& c, P1 p1, P2 p2)
+    {
+        C* obj = c.get();
+        if (!obj)
+            return R();
+        return (obj->*m_function)(p1, p2);
+    }
+
 private:
     R (C::*m_function)(P1, P2);
 };
@@ -230,7 +247,6 @@ class FunctionWrapper<R (C::*)(P1, P2, P3)> {
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
-    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)(P1, P2, P3))
         : m_function(function)
@@ -242,6 +258,14 @@ public:
         return (c->*m_function)(p1, p2, p3);
     }
 
+    R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3)
+    {
+        C* obj = c.get();
+        if (!obj)
+            return R();
+        return (obj->*m_function)(p1, p2, p3);
+    }
+
 private:
     R (C::*m_function)(P1, P2, P3);
 };
@@ -251,7 +275,6 @@ class FunctionWrapper<R (C::*)(P1, P2, P3, P4)> {
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
-    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)(P1, P2, P3, P4))
         : m_function(function)
@@ -263,6 +286,14 @@ public:
         return (c->*m_function)(p1, p2, p3, p4);
     }
 
+    R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3, P4 p4)
+    {
+        C* obj = c.get();
+        if (!obj)
+            return R();
+        return (obj->*m_function)(p1, p2, p3, p4);
+    }
+
 private:
     R (C::*m_function)(P1, P2, P3, P4);
 };
@@ -272,7 +303,6 @@ class FunctionWrapper<R (C::*)(P1, P2, P3, P4, P5)> {
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value;
-    static const bool shouldValidateFirstParameter = true;
 
     explicit FunctionWrapper(R (C::*function)(P1, P2, P3, P4, P5))
         : m_function(function)
@@ -284,6 +314,14 @@ public:
         return (c->*m_function)(p1, p2, p3, p4, p5);
     }
 
+    R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
+    {
+        C* obj = c.get();
+        if (!obj)
+            return R();
+        return (obj->*m_function)(p1, p2, p3, p4, p5);
+    }
+
 private:
     R (C::*m_function)(P1, P2, P3, P4, P5);
 };
@@ -294,7 +332,6 @@ class FunctionWrapper<R (^)()> {
 public:
     typedef R ResultType;
     static const bool shouldRefFirstParameter = false;
-    static const bool shouldValidateFirstParameter = false;
 
     explicit FunctionWrapper(R (^block)())
         : m_block(Block_copy(block))
@@ -335,7 +372,6 @@ template<typename T> struct ParamStorageTraits {
     typedef T StorageType;
 
     static StorageType wrap(const T& value) { return value; }
-    static bool validate(const StorageType&) { return true; }
     static const T& unwrap(const StorageType& value) { return value; }
 };
 
@@ -343,7 +379,6 @@ template<typename T> struct ParamStorageTraits<PassRefPtr<T> > {
     typedef RefPtr<T> StorageType;
 
     static StorageType wrap(PassRefPtr<T> value) { return value; }
-    static bool validate(const StorageType&) { return true; }
     static T* unwrap(const StorageType& value) { return value.get(); }
 };
 
@@ -351,26 +386,15 @@ template<typename T> struct ParamStorageTraits<RefPtr<T> > {
     typedef RefPtr<T> StorageType;
 
     static StorageType wrap(RefPtr<T> value) { return value.release(); }
-    static bool validate(const StorageType&) { return true; }
     static T* unwrap(const StorageType& value) { return value.get(); }
 };
 
-template<typename T> struct ParamStorageTraits<WeakPtr<T> > {
-    typedef WeakPtr<T> StorageType;
-
-    static StorageType wrap(WeakPtr<T> value) { return value; }
-    static bool validate(const StorageType& value) { return value.get(); }
-    static T* unwrap(const StorageType& value) { return value.get(); }
-};
-
-
 template<typename> class RetainPtr;
 
 template<typename T> struct ParamStorageTraits<RetainPtr<T> > {
     typedef RetainPtr<T> StorageType;
 
     static StorageType wrap(const RetainPtr<T>& value) { return value; }
-    static bool validate(const StorageType&) { return true; }
     static typename RetainPtr<T>::PtrType unwrap(const StorageType& value) { return value.get(); }
 };
 
@@ -425,8 +449,6 @@ public:
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
-        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
-            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1));
     }
 
@@ -453,8 +475,6 @@ public:
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
-        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
-            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2));
     }
 
@@ -483,8 +503,6 @@ public:
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
-        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
-            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3));
     }
 
@@ -515,8 +533,6 @@ public:
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
-        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
-            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageTraits<P4>::unwrap(m_p4));
     }
 
@@ -549,8 +565,6 @@ public:
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
-        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
-            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageTraits<P4>::unwrap(m_p4), ParamStorageTraits<P5>::unwrap(m_p5));
     }
 
@@ -585,8 +599,6 @@ public:
 
     virtual typename FunctionWrapper::ResultType operator()()
     {
-        if (FunctionWrapper::shouldValidateFirstParameter && !ParamStorageTraits<P1>::validate(m_p1))
-            return typename FunctionWrapper::ResultType();
         return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageTraits<P4>::unwrap(m_p4), ParamStorageTraits<P5>::unwrap(m_p5), ParamStorageTraits<P6>::unwrap(m_p6));
     }
 
index 0e64506..289a10c 100644 (file)
@@ -96,6 +96,14 @@ public:
     // We should consider having createWeakPtr populate m_ref the first time createWeakPtr is called.
     WeakPtr<T> createWeakPtr() { return WeakPtr<T>(m_ref); }
 
+    void revokeAll()
+    {
+        T* ptr = m_ref->get();
+        m_ref->clear();
+        // We create a new WeakReference so that future calls to createWeakPtr() create nonzero WeakPtrs.
+        m_ref = Internal::WeakReference<T>::create(ptr);
+    }
+
 private:
     RefPtr<Internal::WeakReference<T> > m_ref;
 };
index 9e6592b..40b2f08 100644 (file)
@@ -34,6 +34,7 @@
 #include "Assertions.h"
 #include "ChromiumThreading.h"
 #include "Threading.h"
+#include <wtf/Functional.h>
 
 namespace WTF {
 
@@ -54,6 +55,18 @@ void callOnMainThread(MainThreadFunction* function, void* context)
     ChromiumThreading::callOnMainThread(function, context);
 }
 
+static void callFunctionObject(void* context)
+{
+    Function<void()>* function = static_cast<Function<void()>*>(context);
+    (*function)();
+    delete function;
+}
+
+void callOnMainThread(const Function<void()>& function)
+{
+    callOnMainThread(callFunctionObject, new Function<void()>(function));
+}
+
 void callOnMainThreadAndWait(MainThreadFunction*, void*)
 {
     ASSERT_NOT_REACHED();
index ac8c6b8..8e9e35c 100644 (file)
@@ -1,3 +1,30 @@
+2013-01-23  Adam Barth  <abarth@webkit.org>
+
+        BackgroundHTMLParser::sendTokensToMainThread should use bind
+        https://bugs.webkit.org/show_bug.cgi?id=107637
+
+        Reviewed by Eric Seidel.
+
+        This patch replaces our hand-written implementation of bind for
+        didReceiveTokensFromBackgroundParser with bind from Functional.h. To
+        use the generic version of bind, we need to switch to using WeakPtr to
+        hold a reference to the main thread parser in the BackgroundHTMLParser.
+
+        * html/parser/BackgroundHTMLParser.cpp:
+        (WebCore::BackgroundHTMLParser::BackgroundHTMLParser):
+        (WebCore::BackgroundHTMLParser::sendTokensToMainThread):
+        (WebCore::BackgroundHTMLParser::createPartial):
+        * html/parser/BackgroundHTMLParser.h:
+        (WebCore::BackgroundHTMLParser::create):
+        (BackgroundHTMLParser):
+        (ParserMap):
+        * html/parser/HTMLDocumentParser.cpp:
+        (WebCore::HTMLDocumentParser::HTMLDocumentParser):
+        (WebCore::HTMLDocumentParser::startBackgroundParser):
+        (WebCore::HTMLDocumentParser::stopBackgroundParser):
+        * html/parser/HTMLDocumentParser.h:
+        (HTMLDocumentParser):
+
 2013-01-23  Roger Fong  <roger_fong@apple.com>
 
         Unreviewed. Cleanup VS2010 WebCore project. 
index cfd363f..c0ef404 100644 (file)
@@ -68,9 +68,6 @@ static bool threadSafeMatch(const String& localName, const QualifiedName& qName)
     return threadSafeEqual(localName.impl(), qName.localName().impl());
 }
 
-typedef const void* ParserIdentifier;
-class HTMLDocumentParser;
-
 ParserMap& parserMap()
 {
     // This initialization assumes that this will be initialize on the main thread before
@@ -85,17 +82,11 @@ ParserMap::BackgroundParserMap& ParserMap::backgroundParsers()
     return m_backgroundParsers;
 }
 
-ParserMap::MainThreadParserMap& ParserMap::mainThreadParsers()
-{
-    ASSERT(isMainThread());
-    return m_mainThreadParsers;
-}
-
-BackgroundHTMLParser::BackgroundHTMLParser(const HTMLParserOptions& options, ParserIdentifier identifier)
+BackgroundHTMLParser::BackgroundHTMLParser(const HTMLParserOptions& options, WeakPtr<HTMLDocumentParser> parser)
     : m_inForeignContent(false)
     , m_tokenizer(HTMLTokenizer::create(options))
     , m_options(options)
-    , m_parserIdentifer(identifier)
+    , m_parser(parser)
     , m_pendingTokens(adoptPtr(new CompactHTMLTokenStream))
 {
 }
@@ -173,29 +164,6 @@ void BackgroundHTMLParser::pumpTokenizer()
     sendTokensToMainThread();
 }
 
-class TokenDelivery {
-    WTF_MAKE_NONCOPYABLE(TokenDelivery);
-public:
-    TokenDelivery()
-        : identifier(0)
-    {
-    }
-
-    ParserIdentifier identifier;
-    OwnPtr<CompactHTMLTokenStream> tokens;
-    static void execute(void* context)
-    {
-        TokenDelivery* delivery = static_cast<TokenDelivery*>(context);
-        HTMLDocumentParser* parser = parserMap().mainThreadParsers().get(delivery->identifier);
-        if (parser)
-            parser->didReceiveTokensFromBackgroundParser(delivery->tokens.release());
-        // FIXME: Ideally we wouldn't need to call delete manually. Instead
-        // we would like an API where the message queue owns the tasks and
-        // takes care of deleting them.
-        delete delivery;
-    }
-};
-
 void BackgroundHTMLParser::sendTokensToMainThread()
 {
     if (m_pendingTokens->isEmpty())
@@ -205,18 +173,15 @@ void BackgroundHTMLParser::sendTokensToMainThread()
     checkThatTokensAreSafeToSendToAnotherThread(m_pendingTokens.get());
 #endif
 
-    TokenDelivery* delivery = new TokenDelivery;
-    delivery->identifier = m_parserIdentifer;
-    delivery->tokens = m_pendingTokens.release();
-    callOnMainThread(TokenDelivery::execute, delivery);
+    callOnMainThread(bind(&HTMLDocumentParser::didReceiveTokensFromBackgroundParser, m_parser, m_pendingTokens.release()));
 
     m_pendingTokens = adoptPtr(new CompactHTMLTokenStream);
 }
 
-void BackgroundHTMLParser::createPartial(ParserIdentifier identifier, HTMLParserOptions options)
+void BackgroundHTMLParser::createPartial(ParserIdentifier identifier, HTMLParserOptions options, WeakPtr<HTMLDocumentParser> parser)
 {
     ASSERT(!parserMap().backgroundParsers().get(identifier));
-    parserMap().backgroundParsers().set(identifier, BackgroundHTMLParser::create(options, identifier));
+    parserMap().backgroundParsers().set(identifier, BackgroundHTMLParser::create(options, parser));
 }
 
 void BackgroundHTMLParser::stopPartial(ParserIdentifier identifier)
index 2e4db41..e6e8276 100644 (file)
@@ -32,6 +32,7 @@
 #include "HTMLParserOptions.h"
 #include "HTMLToken.h"
 #include "HTMLTokenizer.h"
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
@@ -44,18 +45,18 @@ public:
     void append(const String&);
     void finish();
 
-    static PassOwnPtr<BackgroundHTMLParser> create(const HTMLParserOptions& options, ParserIdentifier identifier)
+    static PassOwnPtr<BackgroundHTMLParser> create(const HTMLParserOptions& options, WeakPtr<HTMLDocumentParser> parser)
     {
-        return adoptPtr(new BackgroundHTMLParser(options, identifier));
+        return adoptPtr(new BackgroundHTMLParser(options, parser));
     }
 
-    static void createPartial(ParserIdentifier, HTMLParserOptions);
+    static void createPartial(ParserIdentifier, HTMLParserOptions, WeakPtr<HTMLDocumentParser>);
     static void stopPartial(ParserIdentifier);
     static void appendPartial(ParserIdentifier, const String& input);
     static void finishPartial(ParserIdentifier);
 
 private:
-    explicit BackgroundHTMLParser(const HTMLParserOptions&, ParserIdentifier);
+    BackgroundHTMLParser(const HTMLParserOptions&, WeakPtr<HTMLDocumentParser>);
 
     void markEndOfFile();
     void pumpTokenizer();
@@ -68,7 +69,7 @@ private:
     bool m_inForeignContent; // FIXME: We need a stack of foreign content markers.
     OwnPtr<HTMLTokenizer> m_tokenizer;
     HTMLParserOptions m_options;
-    ParserIdentifier m_parserIdentifer;
+    WeakPtr<HTMLDocumentParser> m_parser;
     OwnPtr<CompactHTMLTokenStream> m_pendingTokens;
 };
 
@@ -80,14 +81,11 @@ public:
     }
 
     typedef HashMap<ParserIdentifier, OwnPtr<BackgroundHTMLParser> > BackgroundParserMap;
-    typedef HashMap<ParserIdentifier, HTMLDocumentParser*> MainThreadParserMap;
 
     BackgroundParserMap& backgroundParsers();
-    MainThreadParserMap& mainThreadParsers();
 
 private:
     BackgroundParserMap m_backgroundParsers;
-    MainThreadParserMap m_mainThreadParsers;
 };
 
 ParserMap& parserMap();
index a4d7c2a..46159f0 100644 (file)
@@ -82,6 +82,9 @@ HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors
     , m_treeBuilder(HTMLTreeBuilder::create(this, document, reportErrors, m_options))
     , m_parserScheduler(HTMLParserScheduler::create(this))
     , m_xssAuditor(this)
+#if ENABLE(THREADED_HTML_PARSER)
+    , m_weakFactory(this)
+#endif
     , m_endWasDelayed(false)
     , m_haveBackgroundParser(false)
     , m_pumpSessionNestingLevel(0)
@@ -96,6 +99,9 @@ HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont
     , m_tokenizer(HTMLTokenizer::create(m_options))
     , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, scriptingPermission, m_options))
     , m_xssAuditor(this)
+#if ENABLE(THREADED_HTML_PARSER)
+    , m_weakFactory(this)
+#endif
     , m_endWasDelayed(false)
     , m_haveBackgroundParser(false)
     , m_pumpSessionNestingLevel(0)
@@ -456,9 +462,8 @@ void HTMLDocumentParser::startBackgroundParser()
     m_haveBackgroundParser = true;
 
     ParserIdentifier identifier = ParserMap::identifierForParser(this);
-    parserMap().mainThreadParsers().set(identifier, this);
-
-    HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::createPartial, identifier, m_options));
+    WeakPtr<HTMLDocumentParser> parser = m_weakFactory.createWeakPtr();
+    HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::createPartial, identifier, m_options, parser));
 }
 
 void HTMLDocumentParser::stopBackgroundParser()
@@ -469,9 +474,7 @@ void HTMLDocumentParser::stopBackgroundParser()
 
     ParserIdentifier identifier = ParserMap::identifierForParser(this);
     HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::stopPartial, identifier));
-
-    parserMap().mainThreadParsers().set(identifier, 0);
-    // We will not recieve any messages from the parser after this point.
+    m_weakFactory.revokeAll();
 }
 
 #endif
index b7f0cab..f19cb12 100644 (file)
@@ -39,6 +39,7 @@
 #include "XSSAuditor.h"
 #include <wtf/Deque.h>
 #include <wtf/OwnPtr.h>
+#include <wtf/WeakPtr.h>
 #include <wtf/text/TextPosition.h>
 
 namespace WebCore {
@@ -171,6 +172,7 @@ private:
 
 #if ENABLE(THREADED_HTML_PARSER)
     Deque<OwnPtr<CompactHTMLTokenStream> > m_pendingTokens;
+    WeakPtrFactory<HTMLDocumentParser> m_weakFactory;
 #endif
 
     bool m_endWasDelayed;