Bug 1417939 - do not crash in release builds when a PRFileDescStream is closed twice; r=bobowen a=gchang
authorAlex Gaynor <agaynor@mozilla.com>
Thu, 16 Nov 2017 13:38:33 -0500
changeset 444812 59c2cb4225938b754a44b1c79877a988722e4a0c
parent 444811 062c4b37d9ab0653df560445c12ab5b951cd917a
child 444813 cd0cba138a4c336e25bd1b6e05dffe822f6bd537
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbobowen, gchang
bugs1417939
milestone58.0
Bug 1417939 - do not crash in release builds when a PRFileDescStream is closed twice; r=bobowen a=gchang This makes it API compatible with std::ostream, which it replaced. This silences a rare crash. MozReview-Commit-ID: JoNo1qRCb0n
layout/printing/DrawEventRecorder.h
--- a/layout/printing/DrawEventRecorder.h
+++ b/layout/printing/DrawEventRecorder.h
@@ -29,43 +29,46 @@ public:
     MOZ_ASSERT(!IsOpen());
     mFd = PR_Open(aFilename, PR_RDWR | PR_CREATE_FILE, PR_IRUSR | PR_IWUSR);
     mGood = true;
     mBuffer.reset(new uint8_t[kBufferSize]);
     mBufferPos = 0;
   }
 
   void Close() {
-    Flush();
-    PR_Close(mFd);
-    mFd = nullptr;
-    mBuffer.reset();
-    mBufferPos = 0;
+    // We need to be API compatible with std::ostream, and so we silently handle
+    // closes on a closed FD.
+    if (IsOpen()) {
+      Flush();
+      PR_Close(mFd);
+      mFd = nullptr;
+      mBuffer.reset();
+      mBufferPos = 0;
+    }
   }
 
   bool IsOpen() {
     return mFd != nullptr;
   }
 
   void Flush() {
-    // We need to be API compatible with std::ostream, and so we silently handle
-    // flushes on a closed FD.
+    // See comment in Close().
     if (IsOpen() && mBufferPos > 0) {
       PR_Write(mFd, static_cast<const void*>(mBuffer.get()), mBufferPos);
       mBufferPos = 0;
     }
   }
 
   void Seek(PRInt32 aOffset, PRSeekWhence aWhence) {
     Flush();
     PR_Seek(mFd, aOffset, aWhence);
   }
 
   void write(const char* aData, size_t aSize) {
-    // See comment in Flush().
+    // See comment in Close().
     if (IsOpen()) {
       // If we're writing more data than could ever fit in our buffer, flush the
       // buffer and write directly.
       if (aSize > kBufferSize) {
         Flush();
         PR_Write(mFd, static_cast<const void*>(aData), aSize);
       // If our write could fit in our buffer, but doesn't because the buffer is
       // partially full, write to the buffer, flush the buffer, and then write