Bug 1618868 Part 3: Fix failure test race in CanvasEventRingBuffer::ReturnRead. r=jrmuizel
authorBob Owen <bobowencode@gmail.com>
Tue, 14 Apr 2020 17:53:15 +0000
changeset 523960 6d5126a367588635db656904db3dc39351d6a84d
parent 523959 0ab9d2f382808db82f2e9cdc405a9f11b01fa087
child 523961 6f92781171c80bb5b7e7c8b93211bfe81739081d
push id37313
push userccoroiu@mozilla.com
push dateWed, 15 Apr 2020 04:09:17 +0000
treeherdermozilla-central@c224327f2bdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1618868
milestone77.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1618868 Part 3: Fix failure test race in CanvasEventRingBuffer::ReturnRead. r=jrmuizel This also adds checks for the other side closing during the ReturnRead and ReturnWrite loops. Depends on D70336 Differential Revision: https://phabricator.services.mozilla.com/D70337
gfx/layers/CanvasDrawEventRecorder.cpp
--- a/gfx/layers/CanvasDrawEventRecorder.cpp
+++ b/gfx/layers/CanvasDrawEventRecorder.cpp
@@ -430,16 +430,18 @@ void CanvasEventRingBuffer::ReturnWrite(
     if (availableToWrite) {
       memcpy(mBuf + bufPos, aData, availableToWrite);
       writeCount += availableToWrite;
       mRead->returnCount = writeCount;
       bufPos = writeCount % kStreamSize;
       bufRemaining = kStreamSize - bufPos;
       aData += availableToWrite;
       aSize -= availableToWrite;
+    } else if (mReaderServices->WriterClosed()) {
+      return;
     }
 
     availableToWrite = std::min(
         bufRemaining, (mWrite->returnCount + kStreamSize - writeCount));
   }
 
   memcpy(mBuf + bufPos, aData, aSize);
   writeCount += aSize;
@@ -450,17 +452,19 @@ void CanvasEventRingBuffer::ReturnRead(c
   // First wait for the event returning the data to be read.
   WaitForCheckpoint(mOurCount);
   uint32_t readCount = mWrite->returnCount;
 
   // If the event sending back data fails to play then it will ReturnWrite
   // nothing. So, wait until something has been written or the reader has
   // stopped processing.
   while (readCount == mRead->returnCount) {
-    if (mRead->state != State::Processing) {
+    // We recheck the count, because the other side can write all the data and
+    // started waiting in between these two lines.
+    if (mRead->state != State::Processing && readCount == mRead->returnCount) {
       return;
     }
   }
 
   uint32_t bufPos = readCount % kStreamSize;
   uint32_t bufRemaining = kStreamSize - bufPos;
   uint32_t availableToRead =
       std::min(bufRemaining, (mRead->returnCount - readCount));
@@ -468,16 +472,18 @@ void CanvasEventRingBuffer::ReturnRead(c
     if (availableToRead) {
       memcpy(aOut, mBuf + bufPos, availableToRead);
       readCount += availableToRead;
       mWrite->returnCount = readCount;
       bufPos = readCount % kStreamSize;
       bufRemaining = kStreamSize - bufPos;
       aOut += availableToRead;
       aSize -= availableToRead;
+    } else if (mWriterServices->ReaderClosed()) {
+      return;
     }
 
     availableToRead = std::min(bufRemaining, (mRead->returnCount - readCount));
   }
 
   memcpy(aOut, mBuf + bufPos, aSize);
   readCount += aSize;
   mWrite->returnCount = readCount;