github.com/dshulyak/uring@v0.0.0-20210209113719-1b2ec51f1542/fs/fixed.go (about) 1 package fs 2 3 import ( 4 "sync" 5 ) 6 7 // FileRegistry ... 8 type FileRegistry interface { 9 RegisterFiles([]int32) error 10 UnregisterFiles() error 11 UpdateFiles([]int32, uint32) error 12 } 13 14 func newFixedFiles(reg FileRegistry, n int) *fixedFiles { 15 fds := make([]int32, n) 16 for i := range fds { 17 fds[i] = -1 18 } 19 return &fixedFiles{ 20 fds: fds, 21 reg: reg, 22 requiresReg: true, 23 } 24 } 25 26 type fixedFiles struct { 27 mu sync.Mutex 28 requiresReg bool 29 fds []int32 30 // registered might be lower than len(fds) if some of the fds are -1 31 registered int 32 33 reg FileRegistry 34 } 35 36 func (f *fixedFiles) register(fd uintptr) (uintptr, error) { 37 f.mu.Lock() 38 defer f.mu.Unlock() 39 if len(f.fds) == f.registered { 40 err := f.reg.UnregisterFiles() 41 if err != nil { 42 return 0, err 43 } 44 fds := make([]int32, len(f.fds)) 45 for i := range fds { 46 if fds[i] == 0 { 47 fds[i] = -1 48 } 49 } 50 f.requiresReg = true 51 f.fds = append(f.fds, fds...) 52 } 53 var i int 54 for i = range f.fds { 55 if f.fds[i] == -1 { 56 f.fds[i] = int32(fd) 57 break 58 } 59 } 60 f.registered++ 61 if f.requiresReg { 62 err := f.reg.RegisterFiles(f.fds) 63 if err != nil { 64 return 0, err 65 } 66 f.requiresReg = false 67 } else { 68 err := f.reg.UpdateFiles(f.fds, 0) 69 if err != nil { 70 return 0, err 71 } 72 } 73 return uintptr(i), nil 74 } 75 76 func (f *fixedFiles) unregister(idx uintptr) error { 77 f.mu.Lock() 78 defer f.mu.Unlock() 79 f.fds[idx] = -1 80 f.registered-- 81 return f.reg.UpdateFiles(f.fds, 0) 82 }