github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/sentry/seccheck/seqatomic_sinkslice_unsafe.go (about)

     1  package seccheck
     2  
     3  import (
     4  	"unsafe"
     5  
     6  	"github.com/nicocha30/gvisor-ligolo/pkg/gohacks"
     7  	"github.com/nicocha30/gvisor-ligolo/pkg/sync"
     8  )
     9  
    10  // SeqAtomicLoad returns a copy of *ptr, ensuring that the read does not race
    11  // with any writer critical sections in seq.
    12  //
    13  //go:nosplit
    14  func SeqAtomicLoadSinkSlice(seq *sync.SeqCount, ptr *[]Sink) []Sink {
    15  	for {
    16  		if val, ok := SeqAtomicTryLoadSinkSlice(seq, seq.BeginRead(), ptr); ok {
    17  			return val
    18  		}
    19  	}
    20  }
    21  
    22  // SeqAtomicTryLoad returns a copy of *ptr while in a reader critical section
    23  // in seq initiated by a call to seq.BeginRead() that returned epoch. If the
    24  // read would race with a writer critical section, SeqAtomicTryLoad returns
    25  // (unspecified, false).
    26  //
    27  //go:nosplit
    28  func SeqAtomicTryLoadSinkSlice(seq *sync.SeqCount, epoch sync.SeqCountEpoch, ptr *[]Sink) (val []Sink, ok bool) {
    29  	if sync.RaceEnabled {
    30  
    31  		gohacks.Memmove(unsafe.Pointer(&val), unsafe.Pointer(ptr), unsafe.Sizeof(val))
    32  	} else {
    33  
    34  		val = *ptr
    35  	}
    36  	ok = seq.ReadOk(epoch)
    37  	return
    38  }