summaryrefslogtreecommitdiff
path: root/vendor/github.com/ncruces/go-sqlite3/vfs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/ncruces/go-sqlite3/vfs')
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go32
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go48
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go96
3 files changed, 86 insertions, 90 deletions
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go b/vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go
index 7d809b223..07de7c3d8 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go
@@ -56,16 +56,12 @@ func osAllocate(file *os.File, size int64) error {
return file.Truncate(size)
}
-func osUnlock(file *os.File, start, len int64) _ErrorCode {
- err := unix.FcntlFlock(file.Fd(), _F_OFD_SETLK, &unix.Flock_t{
- Type: unix.F_UNLCK,
- Start: start,
- Len: len,
- })
- if err != nil {
- return _IOERR_UNLOCK
- }
- return _OK
+func osReadLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
+ return osLock(file, unix.F_RDLCK, start, len, timeout, _IOERR_RDLOCK)
+}
+
+func osWriteLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
+ return osLock(file, unix.F_WRLCK, start, len, timeout, _IOERR_LOCK)
}
func osLock(file *os.File, typ int16, start, len int64, timeout time.Duration, def _ErrorCode) _ErrorCode {
@@ -88,10 +84,14 @@ func osLock(file *os.File, typ int16, start, len int64, timeout time.Duration, d
return osLockErrorCode(err, def)
}
-func osReadLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
- return osLock(file, unix.F_RDLCK, start, len, timeout, _IOERR_RDLOCK)
-}
-
-func osWriteLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
- return osLock(file, unix.F_WRLCK, start, len, timeout, _IOERR_LOCK)
+func osUnlock(file *os.File, start, len int64) _ErrorCode {
+ err := unix.FcntlFlock(file.Fd(), _F_OFD_SETLK, &unix.Flock_t{
+ Type: unix.F_UNLCK,
+ Start: start,
+ Len: len,
+ })
+ if err != nil {
+ return _IOERR_UNLOCK
+ }
+ return _OK
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go b/vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go
index f5841fc20..6199c7b00 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go
@@ -3,7 +3,6 @@
package vfs
import (
- "math/rand"
"os"
"time"
@@ -22,16 +21,12 @@ func osAllocate(file *os.File, size int64) error {
return unix.Fallocate(int(file.Fd()), 0, 0, size)
}
-func osUnlock(file *os.File, start, len int64) _ErrorCode {
- err := unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLK, &unix.Flock_t{
- Type: unix.F_UNLCK,
- Start: start,
- Len: len,
- })
- if err != nil {
- return _IOERR_UNLOCK
- }
- return _OK
+func osReadLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
+ return osLock(file, unix.F_RDLCK, start, len, timeout, _IOERR_RDLOCK)
+}
+
+func osWriteLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
+ return osLock(file, unix.F_WRLCK, start, len, timeout, _IOERR_LOCK)
}
func osLock(file *os.File, typ int16, start, len int64, timeout time.Duration, def _ErrorCode) _ErrorCode {
@@ -42,31 +37,22 @@ func osLock(file *os.File, typ int16, start, len int64, timeout time.Duration, d
}
var err error
switch {
- case timeout == 0:
- err = unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLK, &lock)
case timeout < 0:
err = unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLKW, &lock)
default:
- before := time.Now()
- for {
- err = unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLK, &lock)
- if errno, _ := err.(unix.Errno); errno != unix.EAGAIN {
- break
- }
- if time.Since(before) > timeout {
- break
- }
- const sleepIncrement = 1024*1024 - 1 // power of two, ~1ms
- time.Sleep(time.Duration(rand.Int63() & sleepIncrement))
- }
+ err = unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLK, &lock)
}
return osLockErrorCode(err, def)
}
-func osReadLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
- return osLock(file, unix.F_RDLCK, start, len, timeout, _IOERR_RDLOCK)
-}
-
-func osWriteLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
- return osLock(file, unix.F_WRLCK, start, len, timeout, _IOERR_LOCK)
+func osUnlock(file *os.File, start, len int64) _ErrorCode {
+ err := unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLK, &unix.Flock_t{
+ Type: unix.F_UNLCK,
+ Start: start,
+ Len: len,
+ })
+ if err != nil {
+ return _IOERR_UNLOCK
+ }
+ return _OK
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go b/vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go
index 2872201b0..0398f4760 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go
@@ -45,6 +45,7 @@ func osGetExclusiveLock(file *os.File, state *LockLevel) _ErrorCode {
osUnlock(file, _SHARED_FIRST, _SHARED_SIZE)
// Acquire the EXCLUSIVE lock.
+ // Can't wait here, because the file is not OVERLAPPED.
rc := osWriteLock(file, _SHARED_FIRST, _SHARED_SIZE, 0)
if rc != _OK {
@@ -106,64 +107,73 @@ func osCheckReservedLock(file *os.File) (bool, _ErrorCode) {
return false, rc
}
-func osUnlock(file *os.File, start, len uint32) _ErrorCode {
- err := windows.UnlockFileEx(windows.Handle(file.Fd()),
- 0, len, 0, &windows.Overlapped{Offset: start})
- if err == windows.ERROR_NOT_LOCKED {
- return _OK
- }
- if err != nil {
- return _IOERR_UNLOCK
- }
- return _OK
+func osReadLock(file *os.File, start, len uint32, timeout time.Duration) _ErrorCode {
+ return osLock(file, 0, start, len, timeout, _IOERR_RDLOCK)
+}
+
+func osWriteLock(file *os.File, start, len uint32, timeout time.Duration) _ErrorCode {
+ return osLock(file, windows.LOCKFILE_EXCLUSIVE_LOCK, start, len, timeout, _IOERR_LOCK)
}
func osLock(file *os.File, flags, start, len uint32, timeout time.Duration, def _ErrorCode) _ErrorCode {
var err error
switch {
case timeout == 0:
- err = osLockEx(file, flags|windows.LOCKFILE_FAIL_IMMEDIATELY, start, len, 0)
+ err = osLockEx(file, flags|windows.LOCKFILE_FAIL_IMMEDIATELY, start, len)
case timeout < 0:
- err = osLockEx(file, flags, start, len, 0)
+ err = osLockEx(file, flags, start, len)
default:
- var event windows.Handle
- event, err = windows.CreateEvent(nil, 1, 0, nil)
- if err != nil {
- break
- }
- defer windows.CloseHandle(event)
-
- err = osLockEx(file, flags, start, len, event)
- if err == windows.ERROR_IO_PENDING {
- rc, serr := windows.WaitForSingleObject(event, uint32(timeout/time.Millisecond))
- if rc == windows.WAIT_OBJECT_0 {
- return _OK
- }
- if serr != nil {
- err = serr
- } else {
- err = windows.Errno(rc)
- }
- windows.CancelIo(windows.Handle(file.Fd()))
- }
+ err = osLockExTimeout(file, flags, start, len, timeout)
}
return osLockErrorCode(err, def)
}
-func osLockEx(file *os.File, flags, start, len uint32, event windows.Handle) error {
- return windows.LockFileEx(windows.Handle(file.Fd()), flags,
- 0, len, 0, &windows.Overlapped{
- Offset: start,
- HEvent: event,
- })
+func osUnlock(file *os.File, start, len uint32) _ErrorCode {
+ err := windows.UnlockFileEx(windows.Handle(file.Fd()),
+ 0, len, 0, &windows.Overlapped{Offset: start})
+ if err == windows.ERROR_NOT_LOCKED {
+ return _OK
+ }
+ if err != nil {
+ return _IOERR_UNLOCK
+ }
+ return _OK
}
-func osReadLock(file *os.File, start, len uint32, timeout time.Duration) _ErrorCode {
- return osLock(file, 0, start, len, timeout, _IOERR_RDLOCK)
+func osLockEx(file *os.File, flags, start, len uint32) error {
+ return windows.LockFileEx(windows.Handle(file.Fd()), flags,
+ 0, len, 0, &windows.Overlapped{Offset: start})
}
-func osWriteLock(file *os.File, start, len uint32, timeout time.Duration) _ErrorCode {
- return osLock(file, windows.LOCKFILE_EXCLUSIVE_LOCK, start, len, timeout, _IOERR_LOCK)
+func osLockExTimeout(file *os.File, flags, start, len uint32, timeout time.Duration) error {
+ event, err := windows.CreateEvent(nil, 1, 0, nil)
+ if err != nil {
+ return err
+ }
+ defer windows.CloseHandle(event)
+
+ fd := windows.Handle(file.Fd())
+ overlapped := &windows.Overlapped{
+ Offset: start,
+ HEvent: event,
+ }
+
+ err = windows.LockFileEx(fd, flags, 0, len, 0, overlapped)
+ if err != windows.ERROR_IO_PENDING {
+ return err
+ }
+
+ ms := (timeout + time.Millisecond - 1) / time.Millisecond
+ rc, err := windows.WaitForSingleObject(event, uint32(ms))
+ if rc == windows.WAIT_OBJECT_0 {
+ return nil
+ }
+ defer windows.CancelIoEx(fd, overlapped)
+
+ if err != nil {
+ return err
+ }
+ return windows.Errno(rc)
}
func osLockErrorCode(err error, def _ErrorCode) _ErrorCode {
@@ -175,8 +185,8 @@ func osLockErrorCode(err error, def _ErrorCode) _ErrorCode {
switch errno {
case
windows.ERROR_LOCK_VIOLATION,
- windows.ERROR_IO_PENDING,
windows.ERROR_OPERATION_ABORTED,
+ windows.ERROR_IO_PENDING,
windows.WAIT_TIMEOUT:
return _BUSY
}