| Index: Source/core/html/parser/BackgroundHTMLParser.cpp
|
| diff --git a/Source/core/html/parser/BackgroundHTMLParser.cpp b/Source/core/html/parser/BackgroundHTMLParser.cpp
|
| index 77d11543259836602909d8da77ebeed03c3d073e..a2ce11421d104602e2ef1c73231187f04c7ae3ec 100644
|
| --- a/Source/core/html/parser/BackgroundHTMLParser.cpp
|
| +++ b/Source/core/html/parser/BackgroundHTMLParser.cpp
|
| @@ -27,9 +27,9 @@
|
| #include "core/html/parser/BackgroundHTMLParser.h"
|
|
|
| #include "core/html/parser/HTMLDocumentParser.h"
|
| -#include "core/html/parser/HTMLParserThread.h"
|
| #include "core/html/parser/TextResourceDecoder.h"
|
| #include "core/html/parser/XSSAuditor.h"
|
| +#include "platform/SharedBuffer.h"
|
| #include "wtf/MainThread.h"
|
| #include "wtf/text/TextPosition.h"
|
|
|
| @@ -94,11 +94,43 @@ BackgroundHTMLParser::BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHT
|
| , m_xssAuditor(config->xssAuditor.release())
|
| , m_preloadScanner(config->preloadScanner.release())
|
| , m_decoder(config->decoder.release())
|
| + , m_resourceProvider(config->resourceProvider.release())
|
| + , m_receivingDataOnlyFromResourceProvider(false)
|
| + , m_queuedData(SharedBuffer::create())
|
| {
|
| + // Tell the resource provider that we're ready to start receiving
|
| + // chunks of data directly from the parser thread.
|
| + if (m_resourceProvider)
|
| + m_resourceProvider->setBackgroundClient(this);
|
| }
|
|
|
| BackgroundHTMLParser::~BackgroundHTMLParser()
|
| {
|
| + if (m_resourceProvider) {
|
| + // Tell the resource provider that calling into this instance
|
| + // is no longer safe and any further data received should be
|
| + // ignored.
|
| + m_resourceProvider->setBackgroundClient(0);
|
| + // The resource provider needs to be destructed on the main thread.
|
| + // Note we can only call static functions on the HTMLDocumentParser at this point
|
| + // as the weakptr we have for it is likely invalidated now.
|
| + callOnMainThread(bind(&HTMLDocumentParser::destroyResourceProvider, m_resourceProvider.release()));
|
| + }
|
| +}
|
| +
|
| +void BackgroundHTMLParser::didReceivedData(const char* data, size_t length)
|
| +{
|
| + if (m_receivingDataOnlyFromResourceProvider && m_decoder) {
|
| + updateDocument(m_decoder->decode(data, length));
|
| + return;
|
| + }
|
| +
|
| + // If the parser thread is not standalone yet, it means we may get
|
| + // further data packets from the main thread and will need to queue
|
| + // up any data coming directly from the parser thread until we're
|
| + // sure we're complete. This is also necessary if we've lost our
|
| + // decoder, until we get a new one passed from the main thread.
|
| + m_queuedData->append(data, length);
|
| }
|
|
|
| void BackgroundHTMLParser::append(const String& input)
|
| @@ -110,12 +142,18 @@ void BackgroundHTMLParser::append(const String& input)
|
|
|
| void BackgroundHTMLParser::appendBytes(PassOwnPtr<Vector<char> > buffer)
|
| {
|
| + ASSERT(!m_receivingDataOnlyFromResourceProvider);
|
| updateDocument(m_decoder->decode(buffer->data(), buffer->size()));
|
| }
|
|
|
| void BackgroundHTMLParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder)
|
| {
|
| m_decoder = decoder;
|
| +
|
| + // If our decoder got reset in mid-stream and got recreated, we may have
|
| + // some pending data here.
|
| + if (m_decoder)
|
| + flushQueuedData();
|
| }
|
|
|
| void BackgroundHTMLParser::flush()
|
| @@ -129,7 +167,6 @@ void BackgroundHTMLParser::updateDocument(const String& decodedData)
|
|
|
| if (encodingData != m_lastSeenEncodingData) {
|
| m_lastSeenEncodingData = encodingData;
|
| -
|
| m_xssAuditor->setEncoding(encodingData.encoding());
|
| callOnMainThread(bind(&HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser, m_parser, encodingData));
|
| }
|
| @@ -170,6 +207,34 @@ void BackgroundHTMLParser::stop()
|
| delete this;
|
| }
|
|
|
| +void BackgroundHTMLParser::flushQueuedData()
|
| +{
|
| + // We only process queued chunks if we have a decoder and if we know
|
| + // we won't be receiving any more chunks for the main thread. Otherwise
|
| + // we hang on to the chunks for a bit longer.
|
| + if (!m_decoder || !m_receivingDataOnlyFromResourceProvider)
|
| + return;
|
| +
|
| + const char* data;
|
| + size_t position = 0;
|
| + while (size_t length = m_queuedData->getSomeData(data, position)) {
|
| + updateDocument(m_decoder->decode(data, length));
|
| + position += length;
|
| + }
|
| +
|
| + m_queuedData->clear();
|
| +}
|
| +
|
| +void BackgroundHTMLParser::didSwitchedToBackgroundClient()
|
| +{
|
| + m_receivingDataOnlyFromResourceProvider = true;
|
| +
|
| + // At this point we know for sure that no further data will
|
| + // be coming from the main thread, so we can process anything
|
| + // we've received directly on the parser thread in the meantime.
|
| + flushQueuedData();
|
| +}
|
| +
|
| void BackgroundHTMLParser::forcePlaintextForTextDocument()
|
| {
|
| // This is only used by the TextDocumentParser (a subclass of HTMLDocumentParser)
|
|
|