github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/godoc/vfs/gatefs/gatefs.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package gatefs provides an implementation of the FileSystem 6 // interface that wraps another FileSystem and limits its concurrency. 7 package gatefs // import "golang.org/x/tools/godoc/vfs/gatefs" 8 9 import ( 10 "fmt" 11 "os" 12 13 "golang.org/x/tools/godoc/vfs" 14 ) 15 16 // New returns a new FileSystem that delegates to fs. 17 // If gateCh is non-nil and buffered, it's used as a gate 18 // to limit concurrency on calls to fs. 19 func New(fs vfs.FileSystem, gateCh chan bool) vfs.FileSystem { 20 if cap(gateCh) == 0 { 21 return fs 22 } 23 return gatefs{fs, gate(gateCh)} 24 } 25 26 type gate chan bool 27 28 func (g gate) enter() { g <- true } 29 func (g gate) leave() { <-g } 30 31 type gatefs struct { 32 fs vfs.FileSystem 33 gate 34 } 35 36 func (fs gatefs) String() string { 37 return fmt.Sprintf("gated(%s, %d)", fs.fs.String(), cap(fs.gate)) 38 } 39 40 func (fs gatefs) Open(p string) (vfs.ReadSeekCloser, error) { 41 fs.enter() 42 defer fs.leave() 43 rsc, err := fs.fs.Open(p) 44 if err != nil { 45 return nil, err 46 } 47 return gatef{rsc, fs.gate}, nil 48 } 49 50 func (fs gatefs) Lstat(p string) (os.FileInfo, error) { 51 fs.enter() 52 defer fs.leave() 53 return fs.fs.Lstat(p) 54 } 55 56 func (fs gatefs) Stat(p string) (os.FileInfo, error) { 57 fs.enter() 58 defer fs.leave() 59 return fs.fs.Stat(p) 60 } 61 62 func (fs gatefs) ReadDir(p string) ([]os.FileInfo, error) { 63 fs.enter() 64 defer fs.leave() 65 return fs.fs.ReadDir(p) 66 } 67 68 type gatef struct { 69 rsc vfs.ReadSeekCloser 70 gate 71 } 72 73 func (f gatef) Read(p []byte) (n int, err error) { 74 f.enter() 75 defer f.leave() 76 return f.rsc.Read(p) 77 } 78 79 func (f gatef) Seek(offset int64, whence int) (ret int64, err error) { 80 f.enter() 81 defer f.leave() 82 return f.rsc.Seek(offset, whence) 83 } 84 85 func (f gatef) Close() error { 86 f.enter() 87 defer f.leave() 88 return f.rsc.Close() 89 }