fid.go (1356B)
1 package client 2 3 import ( 4 "fmt" 5 "sync" 6 7 "git.mtkn.jp/lib9p" 8 ) 9 10 type filePool struct { 11 m map[uint32]*File 12 *sync.Mutex 13 } 14 15 func newFilePool() *filePool { 16 return &filePool{ 17 make(map[uint32]*File), 18 new(sync.Mutex), 19 } 20 } 21 22 func (pool *filePool) lookup(fid uint32) (*File, bool) { 23 if fid == lib9p.NOFID { 24 return nil, false 25 } 26 pool.Lock() 27 defer pool.Unlock() 28 f, ok := pool.m[fid] 29 return f, ok 30 } 31 32 // NextFid does not lock pool. Lock it before calling this function. 33 func (pool *filePool) nextFid() (uint32, error) { 34 for i := uint32(0); i < lib9p.NOFID; i++ { 35 if _, ok := pool.m[i]; !ok { 36 return i, nil 37 } 38 } 39 return 0, fmt.Errorf("run out of fid") 40 } 41 42 func (pool *filePool) add() (*File, error) { 43 pool.Lock() 44 defer pool.Unlock() 45 fid, err := pool.nextFid() 46 if err != nil { 47 return nil, err 48 } 49 f := &File{ 50 fid: fid, 51 omode: -1, 52 offset: 0, 53 } 54 pool.m[fid] = f 55 return f, nil 56 } 57 58 func (pool *filePool) delete(fid uint32) { 59 pool.Lock() 60 defer pool.Unlock() 61 delete(pool.m, fid) 62 } 63 64 func (pool *filePool) String() string { 65 pool.Lock() // TODO: need? 66 defer pool.Unlock() 67 s := "{" 68 for fid, file := range pool.m { 69 if file == nil { // TODO: need? 70 s += fmt.Sprintf(" [%d]<nil>", fid) 71 continue 72 } 73 st, err := file.Stat() 74 if err != nil { 75 panic(err) 76 } 77 s += fmt.Sprintf(" [%d]%v", fid, st.Name()) 78 } 79 s += "}" 80 return s 81 }