...

Source file src/go.etcd.io/bbolt/bolt_unix_aix.go

Documentation: go.etcd.io/bbolt

     1  //go:build aix
     2  // +build aix
     3  
     4  package bbolt
     5  
     6  import (
     7  	"fmt"
     8  	"syscall"
     9  	"time"
    10  	"unsafe"
    11  
    12  	"golang.org/x/sys/unix"
    13  )
    14  
    15  // flock acquires an advisory lock on a file descriptor.
    16  func flock(db *DB, exclusive bool, timeout time.Duration) error {
    17  	var t time.Time
    18  	if timeout != 0 {
    19  		t = time.Now()
    20  	}
    21  	fd := db.file.Fd()
    22  	var lockType int16
    23  	if exclusive {
    24  		lockType = syscall.F_WRLCK
    25  	} else {
    26  		lockType = syscall.F_RDLCK
    27  	}
    28  	for {
    29  		// Attempt to obtain an exclusive lock.
    30  		lock := syscall.Flock_t{Type: lockType}
    31  		err := syscall.FcntlFlock(fd, syscall.F_SETLK, &lock)
    32  		if err == nil {
    33  			return nil
    34  		} else if err != syscall.EAGAIN {
    35  			return err
    36  		}
    37  
    38  		// If we timed out then return an error.
    39  		if timeout != 0 && time.Since(t) > timeout-flockRetryTimeout {
    40  			return ErrTimeout
    41  		}
    42  
    43  		// Wait for a bit and try again.
    44  		time.Sleep(flockRetryTimeout)
    45  	}
    46  }
    47  
    48  // funlock releases an advisory lock on a file descriptor.
    49  func funlock(db *DB) error {
    50  	var lock syscall.Flock_t
    51  	lock.Start = 0
    52  	lock.Len = 0
    53  	lock.Type = syscall.F_UNLCK
    54  	lock.Whence = 0
    55  	return syscall.FcntlFlock(uintptr(db.file.Fd()), syscall.F_SETLK, &lock)
    56  }
    57  
    58  // mmap memory maps a DB's data file.
    59  func mmap(db *DB, sz int) error {
    60  	// Map the data file to memory.
    61  	b, err := unix.Mmap(int(db.file.Fd()), 0, sz, syscall.PROT_READ, syscall.MAP_SHARED|db.MmapFlags)
    62  	if err != nil {
    63  		return err
    64  	}
    65  
    66  	// Advise the kernel that the mmap is accessed randomly.
    67  	if err := unix.Madvise(b, syscall.MADV_RANDOM); err != nil {
    68  		return fmt.Errorf("madvise: %s", err)
    69  	}
    70  
    71  	// Save the original byte slice and convert to a byte array pointer.
    72  	db.dataref = b
    73  	db.data = (*[maxMapSize]byte)(unsafe.Pointer(&b[0]))
    74  	db.datasz = sz
    75  	return nil
    76  }
    77  
    78  // munmap unmaps a DB's data file from memory.
    79  func munmap(db *DB) error {
    80  	// Ignore the unmap if we have no mapped data.
    81  	if db.dataref == nil {
    82  		return nil
    83  	}
    84  
    85  	// Unmap using the original byte slice.
    86  	err := unix.Munmap(db.dataref)
    87  	db.dataref = nil
    88  	db.data = nil
    89  	db.datasz = 0
    90  	return err
    91  }
    92  

View as plain text