Keep lock during all of ScriptStreamer::fetchDataFromResourceBuffer.

This fixes a race condition where both the main thread and the V8 background
parsing thread call fetchDataFromResourceBuffer. The current lock makes sure
only one thread will fetch data from teh resourceBuffer at a time, and the
queue they put it in is natively thread safe, but - if threads race in just
the right way - the order might be reversed.

Example:
- thread 1 acquires lock, fetches data from resource buffer.
- thread 1 gets interruped; new data arrives in the resource buffer.
- thread 2 acquires lock, fetches data from resource buffer
- thread 2 adds its chunks to the data queue
- thread 1 adds its chunks to the data queue
-> the chunks are now queued in the wrong order.

BUG=510825

Review URL: https://codereview.chromium.org/1286883004

git-svn-id: svn://svn.chromium.org/blink/trunk@200990 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent cc67f9bf
...@@ -288,6 +288,7 @@ private: ...@@ -288,6 +288,7 @@ private:
void fetchDataFromResourceBuffer(size_t lengthOfBOM) void fetchDataFromResourceBuffer(size_t lengthOfBOM)
{ {
ASSERT(isMainThread()); ASSERT(isMainThread());
MutexLocker locker(m_mutex); // For m_cancelled + m_queueTailPosition.
// Get as much data from the ResourceBuffer as we can. // Get as much data from the ResourceBuffer as we can.
const char* data = 0; const char* data = 0;
...@@ -295,18 +296,15 @@ private: ...@@ -295,18 +296,15 @@ private:
Vector<unsigned> chunkLengths; Vector<unsigned> chunkLengths;
size_t dataLength = 0; size_t dataLength = 0;
{ if (!m_cancelled) {
MutexLocker locker(m_mutex); // For m_cancelled + m_queueTailPosition. while (unsigned length = m_resourceBuffer->getSomeData(data, m_queueTailPosition)) {
if (!m_cancelled) { // FIXME: Here we can limit based on the total length, if it turns
while (unsigned length = m_resourceBuffer->getSomeData(data, m_queueTailPosition)) { // out that we don't want to give all the data we have (memory
// FIXME: Here we can limit based on the total length, if it turns // vs. speed).
// out that we don't want to give all the data we have (memory chunks.append(data);
// vs. speed). chunkLengths.append(length);
chunks.append(data); dataLength += length;
chunkLengths.append(length); m_queueTailPosition += length;
dataLength += length;
m_queueTailPosition += length;
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment