mirror of
https://github.com/etcd-io/bbolt.git
synced 2025-05-01 13:13:32 +00:00
Rather than having the build setup such that it will only work on the specifically defined operating systems, this commit modifies it to use more liberal !windows,!plan9 build tag for the unix specific bits. This means bolt will compile on more Operating Systems such as OpenBSD, FreeBSD, and NetBSD. See boltdb/bolt#257 for discussion.
70 lines
1.5 KiB
Go
70 lines
1.5 KiB
Go
// +build !windows,!plan9
|
|
|
|
package bolt
|
|
|
|
import (
|
|
"os"
|
|
"syscall"
|
|
"time"
|
|
"unsafe"
|
|
)
|
|
|
|
// flock acquires an advisory lock on a file descriptor.
|
|
func flock(f *os.File, timeout time.Duration) error {
|
|
var t time.Time
|
|
for {
|
|
// If we're beyond our timeout then return an error.
|
|
// This can only occur after we've attempted a flock once.
|
|
if t.IsZero() {
|
|
t = time.Now()
|
|
} else if timeout > 0 && time.Since(t) > timeout {
|
|
return ErrTimeout
|
|
}
|
|
|
|
// Otherwise attempt to obtain an exclusive lock.
|
|
err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
|
|
if err == nil {
|
|
return nil
|
|
} else if err != syscall.EWOULDBLOCK {
|
|
return err
|
|
}
|
|
|
|
// Wait for a bit and try again.
|
|
time.Sleep(50 * time.Millisecond)
|
|
}
|
|
}
|
|
|
|
// funlock releases an advisory lock on a file descriptor.
|
|
func funlock(f *os.File) error {
|
|
return syscall.Flock(int(f.Fd()), syscall.LOCK_UN)
|
|
}
|
|
|
|
// mmap memory maps a DB's data file.
|
|
func mmap(db *DB, sz int) error {
|
|
b, err := syscall.Mmap(int(db.file.Fd()), 0, sz, syscall.PROT_READ, syscall.MAP_SHARED)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Save the original byte slice and convert to a byte array pointer.
|
|
db.dataref = b
|
|
db.data = (*[maxMapSize]byte)(unsafe.Pointer(&b[0]))
|
|
db.datasz = sz
|
|
return nil
|
|
}
|
|
|
|
// munmap unmaps a DB's data file from memory.
|
|
func munmap(db *DB) error {
|
|
// Ignore the unmap if we have no mapped data.
|
|
if db.dataref == nil {
|
|
return nil
|
|
}
|
|
|
|
// Unmap using the original byte slice.
|
|
err := syscall.Munmap(db.dataref)
|
|
db.dataref = nil
|
|
db.data = nil
|
|
db.datasz = 0
|
|
return err
|
|
}
|