github.com/v2fly/tools@v0.100.0/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 "github.com/v2fly/tools/godoc/vfs/gatefs" 8 9 import ( 10 "fmt" 11 "os" 12 13 "github.com/v2fly/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) RootType(path string) vfs.RootType { 41 return fs.fs.RootType(path) 42 } 43 44 func (fs gatefs) Open(p string) (vfs.ReadSeekCloser, error) { 45 fs.enter() 46 defer fs.leave() 47 rsc, err := fs.fs.Open(p) 48 if err != nil { 49 return nil, err 50 } 51 return gatef{rsc, fs.gate}, nil 52 } 53 54 func (fs gatefs) Lstat(p string) (os.FileInfo, error) { 55 fs.enter() 56 defer fs.leave() 57 return fs.fs.Lstat(p) 58 } 59 60 func (fs gatefs) Stat(p string) (os.FileInfo, error) { 61 fs.enter() 62 defer fs.leave() 63 return fs.fs.Stat(p) 64 } 65 66 func (fs gatefs) ReadDir(p string) ([]os.FileInfo, error) { 67 fs.enter() 68 defer fs.leave() 69 return fs.fs.ReadDir(p) 70 } 71 72 type gatef struct { 73 rsc vfs.ReadSeekCloser 74 gate 75 } 76 77 func (f gatef) Read(p []byte) (n int, err error) { 78 f.enter() 79 defer f.leave() 80 return f.rsc.Read(p) 81 } 82 83 func (f gatef) Seek(offset int64, whence int) (ret int64, err error) { 84 f.enter() 85 defer f.leave() 86 return f.rsc.Seek(offset, whence) 87 } 88 89 func (f gatef) Close() error { 90 f.enter() 91 defer f.leave() 92 return f.rsc.Close() 93 }