Procházet zdrojové kódy

Fix for issue #4: Data race when decompressing blocks concurrently

Pierre Curto před 10 roky
rodič
revize
4bdd4b0658
1 změnil soubory, kde provedl 5 přidání a 5 odebrání
  1. 5 5
      reader.go

+ 5 - 5
reader.go

@@ -20,8 +20,8 @@ var errEndOfBlock = errors.New("end of block")
 // The Header is set after the first call to Read().
 // The Header is set after the first call to Read().
 // The Header may change between Read() calls in case of concatenated frames.
 // The Header may change between Read() calls in case of concatenated frames.
 type Reader struct {
 type Reader struct {
+	Pos int64 // position within the source
 	Header
 	Header
-	Pos      int64 // position within the source
 	src      io.Reader
 	src      io.Reader
 	checksum hash.Hash32    // frame hash
 	checksum hash.Hash32    // frame hash
 	wg       sync.WaitGroup // decompressing go routine wait group
 	wg       sync.WaitGroup // decompressing go routine wait group
@@ -227,17 +227,17 @@ func (z *Reader) readBlock(buf []byte, b *block) error {
 	if err := binary.Read(z.src, binary.LittleEndian, &bLen); err != nil {
 	if err := binary.Read(z.src, binary.LittleEndian, &bLen); err != nil {
 		return err
 		return err
 	}
 	}
-	z.Pos += 4
+	atomic.AddInt64(&z.Pos, 4)
 
 
 	switch {
 	switch {
 	case bLen == 0:
 	case bLen == 0:
 		return errEndOfBlock
 		return errEndOfBlock
-	case bLen & (1<<31) == 0:
+	case bLen&(1<<31) == 0:
 		b.compressed = true
 		b.compressed = true
 		b.data = buf
 		b.data = buf
 		b.zdata = make([]byte, bLen)
 		b.zdata = make([]byte, bLen)
 	default:
 	default:
-		bLen = bLen & (1<<31-1)
+		bLen = bLen & (1<<31 - 1)
 		b.data = buf[:bLen]
 		b.data = buf[:bLen]
 		b.zdata = buf[:bLen]
 		b.zdata = buf[:bLen]
 	}
 	}
@@ -278,7 +278,7 @@ func (z *Reader) decompressBlock(b *block, abort *uint32) {
 		}
 		}
 		b.data = b.data[n : n+m]
 		b.data = b.data[n : n+m]
 	}
 	}
-	z.Pos += int64(len(b.data))
+	atomic.AddInt64(&z.Pos, int64(len(b.data)))
 }
 }
 
 
 // close validates the frame checksum (if any) and checks the next frame (if any).
 // close validates the frame checksum (if any) and checks the next frame (if any).