Bug 1239789 - Add secondary buffers to zxx_stream::StaticAllocator to handle reentrancy. r=glandium a=lizzard
authorDylan Roeh <droeh@mozilla.com>
Thu, 24 Mar 2016 17:25:57 -0500
changeset 325586 9e0bc04410121516f125f411a4450d6072089a90
parent 325585 33214b79a4ccfa336ff54e7bc4d99b405aab8e49
child 325587 37642befed5959b63febdfaeb41e8b95c4aa3022
push id1128
push userjlund@mozilla.com
push dateWed, 01 Jun 2016 01:31:59 +0000
treeherdermozilla-release@fe0d30de989d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium, lizzard
bugs1239789
milestone47.0a2
Bug 1239789 - Add secondary buffers to zxx_stream::StaticAllocator to handle reentrancy. r=glandium a=lizzard MozReview-Commit-ID: Iv20CMmpneo
mozglue/linker/Zip.h
--- a/mozglue/linker/Zip.h
+++ b/mozglue/linker/Zip.h
@@ -67,23 +67,24 @@ private:
    * Helper class for each buffer in StaticAllocator.
    */
   template <size_t Size>
   class ZStreamBuf
   {
   public:
     ZStreamBuf() : inUse(false) { }
 
-    char *get()
+    bool get(char*& out)
     {
       if (!inUse) {
         inUse = true;
-        return buf;
+        out = buf;
+        return true;
       } else {
-        MOZ_CRASH("ZStreamBuf already in use");
+        return false;
       }
     }
 
     void Release()
     {
       memset(buf, 0, Size);
       inUse = false;
     }
@@ -101,38 +102,51 @@ public:
   /**
    * Special allocator that uses static buffers to allocate from.
    */
   class StaticAllocator
   {
   public:
     void *Alloc(uInt items, uInt size)
     {
-      if (items == 1 && size <= stateBuf.size) {
-        return stateBuf.get();
-      } else if (items * size == windowBuf.size) {
-        return windowBuf.get();
+      if (items == 1 && size <= stateBuf1.size) {
+        char* res = nullptr;
+        if (stateBuf1.get(res) || stateBuf2.get(res)) {
+          return res;
+        }
+        MOZ_CRASH("ZStreamBuf already in use");
+      } else if (items * size == windowBuf1.size) {
+        char* res = nullptr;
+        if (windowBuf1.get(res) || windowBuf2.get(res)) {
+          return res;
+        }
+        MOZ_CRASH("ZStreamBuf already in use");
       } else {
         MOZ_CRASH("No ZStreamBuf for allocation");
       }
     }
 
     void Free(void *ptr)
     {
-      if (stateBuf.Equals(ptr)) {
-        stateBuf.Release();
-      } else if (windowBuf.Equals(ptr)) {
-        windowBuf.Release();
+      if (stateBuf1.Equals(ptr)) {
+        stateBuf1.Release();
+      } else if (stateBuf2.Equals(ptr)) {
+        stateBuf2.Release();
+      }else if (windowBuf1.Equals(ptr)) {
+        windowBuf1.Release();
+      } else if (windowBuf2.Equals(ptr)) {
+        windowBuf2.Release();
       } else {
         MOZ_CRASH("Pointer doesn't match a ZStreamBuf");
       }
     }
 
-    ZStreamBuf<0x3000> stateBuf; // 0x3000 is an arbitrary size above 10K.
-    ZStreamBuf<1 << MAX_WBITS> windowBuf;
+    // 0x3000 is an arbitrary size above 10K.
+    ZStreamBuf<0x3000> stateBuf1, stateBuf2;
+    ZStreamBuf<1 << MAX_WBITS> windowBuf1, windowBuf2;
   };
 
 private:
   StaticAllocator *allocator;
 };
 
 /**
  * Forward declaration
@@ -330,17 +344,17 @@ private:
     /**
      * Returns a pointer to the data associated with this header
      */
     const void *GetData() const
     {
       return reinterpret_cast<const char *>(this) + sizeof(*this)
              + filenameSize + extraFieldSize;
     }
-    
+
     le_uint16 minVersion;
     le_uint16 generalFlag;
     le_uint16 compression;
     le_uint16 lastModifiedTime;
     le_uint16 lastModifiedDate;
     le_uint32 CRC32;
     le_uint32 compressedSize;
     le_uint32 uncompressedSize;