]> Sergey Matveev's repositories - btrtrc.git/commitdiff
mmap_span: Synchronize access to memory maps to avoid race when unmapping
authorMatt Joiner <anacrolix@gmail.com>
Sat, 6 Jan 2018 05:39:52 +0000 (16:39 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Sat, 6 Jan 2018 05:39:52 +0000 (16:39 +1100)
mmap_span/mmap_span.go
storage/mmap.go

index bbaa7fcaba5c3c822eeafaedaccb09b73296d706..21f6bd26b76a93b5229a895f69de404b041054b9 100644 (file)
@@ -3,6 +3,7 @@ package mmap_span
 import (
        "io"
        "log"
+       "sync"
 
        "github.com/edsrzf/mmap-go"
 )
@@ -16,6 +17,7 @@ func (s segment) Size() int64 {
 }
 
 type MMapSpan struct {
+       mu sync.RWMutex
        span
 }
 
@@ -23,7 +25,9 @@ func (ms *MMapSpan) Append(mmap mmap.MMap) {
        ms.span = append(ms.span, segment{&mmap})
 }
 
-func (ms MMapSpan) Close() error {
+func (ms *MMapSpan) Close() error {
+       ms.mu.Lock()
+       defer ms.mu.Unlock()
        for _, mMap := range ms.span {
                err := mMap.(segment).Unmap()
                if err != nil {
@@ -33,14 +37,18 @@ func (ms MMapSpan) Close() error {
        return nil
 }
 
-func (ms MMapSpan) Size() (ret int64) {
+func (ms *MMapSpan) Size() (ret int64) {
+       ms.mu.RLock()
+       defer ms.mu.RUnlock()
        for _, seg := range ms.span {
                ret += seg.Size()
        }
        return
 }
 
-func (ms MMapSpan) ReadAt(p []byte, off int64) (n int, err error) {
+func (ms *MMapSpan) ReadAt(p []byte, off int64) (n int, err error) {
+       ms.mu.RLock()
+       defer ms.mu.RUnlock()
        ms.ApplyTo(off, func(intervalOffset int64, interval sizer) (stop bool) {
                _n := copy(p, (*interval.(segment).MMap)[intervalOffset:])
                p = p[_n:]
@@ -53,7 +61,9 @@ func (ms MMapSpan) ReadAt(p []byte, off int64) (n int, err error) {
        return
 }
 
-func (ms MMapSpan) WriteAt(p []byte, off int64) (n int, err error) {
+func (ms *MMapSpan) WriteAt(p []byte, off int64) (n int, err error) {
+       ms.mu.RLock()
+       defer ms.mu.RUnlock()
        ms.ApplyTo(off, func(iOff int64, i sizer) (stop bool) {
                mMap := i.(segment)
                _n := copy((*mMap.MMap)[iOff:], p)
index f48a2bcc79d95f31657f7ed5f08b78a58001d332..d859c2e54ebd99d3cd64a1bab609e254489bd44f 100644 (file)
@@ -55,8 +55,8 @@ func (ts *mmapTorrentStorage) Piece(p metainfo.Piece) PieceImpl {
                pc:       ts.pc,
                p:        p,
                ih:       ts.infoHash,
-               ReaderAt: io.NewSectionReader(ts.span, p.Offset(), p.Length()),
-               WriterAt: missinggo.NewSectionWriter(ts.span, p.Offset(), p.Length()),
+               ReaderAt: io.NewSectionReader(&ts.span, p.Offset(), p.Length()),
+               WriterAt: missinggo.NewSectionWriter(&ts.span, p.Offset(), p.Length()),
        }
 }