Modified: trunk/Source/WebCore/ChangeLog (142842 => 142843)
--- trunk/Source/WebCore/ChangeLog 2013-02-14 02:36:01 UTC (rev 142842)
+++ trunk/Source/WebCore/ChangeLog 2013-02-14 03:31:58 UTC (rev 142843)
@@ -1,5 +1,33 @@
2013-02-13 Adam Barth <aba...@webkit.org>
+ TokenPreloadScanner should be (mostly!) thread-safe
+ https://bugs.webkit.org/show_bug.cgi?id=109760
+
+ Reviewed by Eric Seidel.
+
+ This patch makes the bulk of TokenPreloadScanner thread-safe. The one
+ remaining wart is processPossibleBaseTag because it wants to grub
+ around in the base tag's attributes. I have a plan for that, but it's
+ going to need to wait for the next patch.
+
+ * html/parser/HTMLPreloadScanner.cpp:
+ (WebCore::isStartTag):
+ (WebCore::isStartOrEndTag):
+ (WebCore::TokenPreloadScanner::identifierFor):
+ (WebCore::TokenPreloadScanner::inititatorFor):
+ (WebCore::TokenPreloadScanner::StartTagScanner::StartTagScanner):
+ (WebCore::TokenPreloadScanner::StartTagScanner::processAttributes):
+ (TokenPreloadScanner::StartTagScanner):
+ (WebCore::TokenPreloadScanner::processPossibleTemplateTag):
+ (WebCore::TokenPreloadScanner::processPossibleStyleTag):
+ (WebCore::TokenPreloadScanner::processPossibleBaseTag):
+ (WebCore::TokenPreloadScanner::scan):
+ (WebCore::HTMLPreloadScanner::scan):
+ * html/parser/HTMLPreloadScanner.h:
+ (WebCore):
+
+2013-02-13 Adam Barth <aba...@webkit.org>
+
StartTagScanner should be thread-safe
https://bugs.webkit.org/show_bug.cgi?id=109750
Modified: trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp (142842 => 142843)
--- trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp 2013-02-14 02:36:01 UTC (rev 142842)
+++ trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp 2013-02-14 03:31:58 UTC (rev 142843)
@@ -43,25 +43,17 @@
using namespace HTMLNames;
-static bool isStartTag(const HTMLToken& token)
+static bool isStartTag(HTMLToken::Type type)
{
- return token.type() == HTMLToken::StartTag;
+ return type == HTMLToken::StartTag;
}
-static bool isStartOrEndTag(const HTMLToken& token)
+static bool isStartOrEndTag(HTMLToken::Type type)
{
- return token.type() == HTMLToken::EndTag || isStartTag(token);
+ return type == HTMLToken::EndTag || isStartTag(type);
}
-enum HTMLTagIdentifier {
- ImgTagId,
- InputTagId,
- LinkTagId,
- ScriptTagId,
- UnknownTagId,
-};
-
-static HTMLTagIdentifier identifierFor(const AtomicString& tagName)
+TokenPreloadScanner::TagId TokenPreloadScanner::identifierFor(const AtomicString& tagName)
{
if (tagName == imgTag)
return ImgTagId;
@@ -71,10 +63,16 @@
return LinkTagId;
if (tagName == scriptTag)
return ScriptTagId;
+ if (tagName == styleTag)
+ return StyleTagId;
+ if (tagName == baseTag)
+ return BaseTagId;
+ if (tagName == templateTag)
+ return TemplateTagId;
return UnknownTagId;
}
-static String inititatorFor(HTMLTagIdentifier tagId)
+String TokenPreloadScanner::inititatorFor(TagId tagId)
{
switch (tagId) {
case ImgTagId:
@@ -86,6 +84,9 @@
case ScriptTagId:
return "script";
case UnknownTagId:
+ case StyleTagId:
+ case BaseTagId:
+ case TemplateTagId:
ASSERT_NOT_REACHED();
return "unknown";
}
@@ -93,9 +94,9 @@
return "unknown";
}
-class StartTagScanner {
+class TokenPreloadScanner::StartTagScanner {
public:
- explicit StartTagScanner(HTMLTagIdentifier tagId)
+ explicit StartTagScanner(TagId tagId)
: m_tagId(tagId)
, m_linkIsStyleSheet(false)
, m_linkMediaAttributeIsScreen(true)
@@ -107,7 +108,7 @@
{
ASSERT(isMainThread());
- if (m_tagId == UnknownTagId)
+ if (m_tagId >= UnknownTagId)
return;
for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
@@ -221,7 +222,7 @@
return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode, "use-credentials");
}
- HTMLTagIdentifier m_tagId;
+ TagId m_tagId;
String m_urlToLoad;
String m_charset;
String m_crossOriginMode;
@@ -244,10 +245,10 @@
}
#if ENABLE(TEMPLATE_ELEMENT)
-bool TokenPreloadScanner::processPossibleTemplateTag(const AtomicString& tagName, const HTMLToken& token)
+bool TokenPreloadScanner::processPossibleTemplateTag(TagId tagId, HTMLToken::Type type)
{
- if (isStartOrEndTag(token) && tagName == templateTag) {
- if (isStartTag(token))
+ if (isStartOrEndTag(type) && tagId == TemplateTagId) {
+ if (isStartTag(type))
m_templateCount++;
else
m_templateCount--;
@@ -258,13 +259,13 @@
}
#endif
-bool TokenPreloadScanner::processPossibleStyleTag(const AtomicString& tagName, const HTMLToken& token)
+bool TokenPreloadScanner::processPossibleStyleTag(TagId tagId, HTMLToken::Type type)
{
- ASSERT(isStartOrEndTag(token));
- if (tagName != styleTag)
+ ASSERT(isStartOrEndTag(type));
+ if (tagId != StyleTagId)
return false;
- m_inStyle = isStartTag(token);
+ m_inStyle = isStartTag(type);
if (!m_inStyle)
m_cssScanner.reset();
@@ -272,10 +273,10 @@
return true;
}
-bool TokenPreloadScanner::processPossibleBaseTag(const AtomicString& tagName, const HTMLToken& token)
+bool TokenPreloadScanner::processPossibleBaseTag(TagId tagId, const HTMLToken& token)
{
- ASSERT(isStartTag(token));
- if (tagName != baseTag)
+ ASSERT(isStartTag(token.type()));
+ if (tagId != BaseTagId)
return false;
// The first <base> element is the one that wins.
@@ -303,22 +304,24 @@
return m_cssScanner.scan(characters.begin(), characters.end(), requests);
}
- if (!isStartOrEndTag(token))
+ if (!isStartOrEndTag(token.type()))
return;
AtomicString tagName(token.name());
+ TagId tagId = identifierFor(tagName);
+
#if ENABLE(TEMPLATE_ELEMENT)
- if (processPossibleTemplateTag(tagName, token))
+ if (processPossibleTemplateTag(tagId, token.type()))
return;
#endif
- if (processPossibleStyleTag(tagName, token))
+ if (processPossibleStyleTag(tagId, token.type()))
return;
- if (!isStartTag(token))
+ if (!isStartTag(token.type()))
return;
- if (processPossibleBaseTag(tagName, token))
+ if (processPossibleBaseTag(tagId, token))
return;
- StartTagScanner scanner(identifierFor(tagName));
+ StartTagScanner scanner(tagId);
scanner.processAttributes(token.attributes());
OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predictedBaseElementURL);
if (request)
@@ -350,7 +353,7 @@
Vector<OwnPtr<PreloadRequest> > requests;
while (m_tokenizer->nextToken(m_source, m_token)) {
- if (isStartTag(m_token))
+ if (isStartTag(m_token.type()))
m_tokenizer->updateStateFor(AtomicString(m_token.name()));
m_scanner.scan(m_token, requests);
m_token.clear();
Modified: trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h (142842 => 142843)
--- trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h 2013-02-14 02:36:01 UTC (rev 142842)
+++ trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h 2013-02-14 03:31:58 UTC (rev 142843)
@@ -34,7 +34,6 @@
namespace WebCore {
class HTMLParserOptions;
-class HTMLToken;
class HTMLTokenizer;
class SegmentedString;
@@ -49,14 +48,31 @@
void setPredictedBaseElementURL(const KURL& url) { m_predictedBaseElementURL = url; }
private:
- bool processStyleCharacters(const HTMLToken&);
+ enum TagId {
+ // These tags are scanned by the StartTagScanner.
+ ImgTagId,
+ InputTagId,
+ LinkTagId,
+ ScriptTagId,
+ // These tags are not scanned by the StartTagScanner.
+ UnknownTagId,
+ StyleTagId,
+ BaseTagId,
+ TemplateTagId,
+ };
+
+ class StartTagScanner;
+
+ static TagId identifierFor(const AtomicString& tagName);
+ static String inititatorFor(TagId);
+
#if ENABLE(TEMPLATE_ELEMENT)
- bool processPossibleTemplateTag(const AtomicString& tagName, const HTMLToken&);
+ bool processPossibleTemplateTag(TagId, HTMLToken::Type);
#endif
- bool processPossibleStyleTag(const AtomicString& tagName, const HTMLToken&);
- bool processPossibleBaseTag(const AtomicString& tagName, const HTMLToken&);
+ bool processPossibleStyleTag(TagId, HTMLToken::Type);
+ bool processPossibleBaseTag(TagId, const HTMLToken&);
CSSPreloadScanner m_cssScanner;
KURL m_documentURL;