Commit 56d0b374 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent e58e9845
...@@ -1414,29 +1414,34 @@ func (f *BigFile) readPinWatchers(ctx context.Context, blk int64, treepath []btr ...@@ -1414,29 +1414,34 @@ func (f *BigFile) readPinWatchers(ctx context.Context, blk int64, treepath []btr
blkrev := blkrevMax blkrev := blkrevMax
blkrevRough := true blkrevRough := true
// XXX locking (f.watchTab)
wg, ctx := errgroup.WithContext(ctx) wg, ctx := errgroup.WithContext(ctx)
for w := range f.watchTab { for w := range f.watchTab { // XXX locking (f.watchTab)
w := w w := w
fmt.Printf("S: read -> pin watchers: w @%s\n", w.at) // make sure w.at stays unchanged while we pin the block
w.atMu.RLock()
// XXX locking (w) fmt.Printf("S: read -> pin watchers: w @%s\n", w.at)
// the block is already covered by @w.at database view // the block is already covered by @w.at database view
if blkrev <= w.at { // XXX locking if blkrev <= w.at {
w.atMu.RUnlock()
continue continue
} }
// if blkrev is rough estimation and that upper bound is > w.at // if blkrev is rough estimation and that upper bound is > w.at
// we have to recompute ~exact file[blk] revision @head. // we have to recompute ~exact file[blk] revision @head.
if blkrevRough { if blkrevRough {
// unlock atMu while we are (re-)calculating blkrev
// we'll relock atMu again and recheck blkrev vs w.at after.
w.atMu.RUnlock()
blkrev, _ = f.LastBlkRev(ctx, blk, f.head.zconn.At()) blkrev, _ = f.LastBlkRev(ctx, blk, f.head.zconn.At())
blkrevRough = false blkrevRough = false
// XXX w.at could be only ↑ ? if not - locking is more complex w.atMu.RLock()
if blkrev <= w.at { // XXX locking if blkrev <= w.at {
w.atMu.RUnlock()
continue continue
} }
} }
...@@ -1447,10 +1452,11 @@ func (f *BigFile) readPinWatchers(ctx context.Context, blk int64, treepath []btr ...@@ -1447,10 +1452,11 @@ func (f *BigFile) readPinWatchers(ctx context.Context, blk int64, treepath []btr
// and most of them would be on different w.at - cache of the file will // and most of them would be on different w.at - cache of the file will
// be lost. Via pinning to particular block revision, we make sure the // be lost. Via pinning to particular block revision, we make sure the
// revision to pin is the same on all clients, and so file cache is shared. // revision to pin is the same on all clients, and so file cache is shared.
pinrev, _ := w.file.LastBlkRev(ctx, blk, w.at) // XXX locking (w), move into go? pinrev, _ := w.file.LastBlkRev(ctx, blk, w.at) // XXX move into go?
wg.Go(func() error { wg.Go(func() error {
// XXX close watcher on any error // XXX close watcher on any error
defer w.atMu.RUnlock()
return w.pin(ctx, blk, pinrev) return w.pin(ctx, blk, pinrev)
}) })
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment