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  }