diff --git a/vfs_files.go b/vfs_files.go index 8b96c18..05891fa 100644 --- a/vfs_files.go +++ b/vfs_files.go @@ -44,25 +44,25 @@ func vfsGetOpenFileID(file *os.File) (uint32, error) { } } - of := vfsOpenFile{ + of := &vfsOpenFile{ file: file, info: fi, nref: 1, - vfsLocker: &vfsDebugLocker{}, + vfsLocker: &vfsNoopLocker{}, } // Find an empty slot. for id, ptr := range vfsOpenFiles { if ptr == nil { - vfsOpenFiles[id] = &of + vfsOpenFiles[id] = of return uint32(id), nil } } // Add a new slot. id := len(vfsOpenFiles) - vfsOpenFiles = append(vfsOpenFiles, &of) + vfsOpenFiles = append(vfsOpenFiles, of) return uint32(id), nil } @@ -99,12 +99,12 @@ func (p vfsFilePtr) ID() uint32 { return id } -func (p vfsFilePtr) Lock() uint32 { +func (p vfsFilePtr) Lock() vfsLockState { lk, ok := p.Memory().ReadUint32Le(p.ptr + 2*wordSize) if !ok { panic(rangeErr) } - return lk + return vfsLockState(lk) } func (p vfsFilePtr) SetID(id uint32) vfsFilePtr { @@ -114,8 +114,8 @@ func (p vfsFilePtr) SetID(id uint32) vfsFilePtr { return p } -func (p vfsFilePtr) SetLock(lock uint32) vfsFilePtr { - if ok := p.Memory().WriteUint32Le(p.ptr+2*wordSize, lock); !ok { +func (p vfsFilePtr) SetLock(lock vfsLockState) vfsFilePtr { + if ok := p.Memory().WriteUint32Le(p.ptr+2*wordSize, uint32(lock)); !ok { panic(rangeErr) } return p diff --git a/vfs_lock.go b/vfs_lock.go index b36a937..6954ae8 100644 --- a/vfs_lock.go +++ b/vfs_lock.go @@ -52,20 +52,22 @@ const ( _SHARED_SIZE = 510 ) +type vfsLockState uint32 + type vfsLocker interface { - LockerState() uint32 + LockState() vfsLockState LockShared() uint32 // UNLOCKED -> SHARED LockReserved() uint32 // SHARED -> RESERVED LockPending() uint32 // SHARED|RESERVED -> PENDING LockExclusive() uint32 // PENDING -> EXCLUSIVE DowngradeLock() uint32 // SHARED <- EXCLUSIVE|PENDING|RESERVED - ReleaseLock() uint32 // UNLOCKED <- EXCLUSIVE|PENDING|RESERVED|SHARED + Unlock() uint32 // UNLOCKED <- EXCLUSIVE|PENDING|RESERVED|SHARED - CheckReserved() (bool, uint32) + CheckReservedLock() (bool, uint32) } -func vfsLock(ctx context.Context, mod api.Module, pFile, eLock uint32) uint32 { +func vfsLock(ctx context.Context, mod api.Module, pFile uint32, eLock vfsLockState) uint32 { if assert && (eLock == _NO_LOCK || eLock == _PENDING_LOCK) { panic(assertErr + " [d4oxww]") } @@ -92,7 +94,7 @@ func vfsLock(ctx context.Context, mod api.Module, pFile, eLock uint32) uint32 { vfsOpenFilesMtx.Lock() defer vfsOpenFilesMtx.Unlock() of := vfsOpenFiles[ptr.ID()] - fLock := of.LockerState() + fLock := of.LockState() // If some other connection has a lock that precludes the requested lock, return BUSY. if cLock != fLock && (eLock > _SHARED_LOCK || fLock >= _PENDING_LOCK) { @@ -155,7 +157,7 @@ func vfsLock(ctx context.Context, mod api.Module, pFile, eLock uint32) uint32 { } } -func vfsUnlock(ctx context.Context, mod api.Module, pFile, eLock uint32) uint32 { +func vfsUnlock(ctx context.Context, mod api.Module, pFile uint32, eLock vfsLockState) uint32 { if assert && (eLock != _NO_LOCK && eLock != _SHARED_LOCK) { panic(assertErr + " [7i4jw3]") } @@ -171,7 +173,7 @@ func vfsUnlock(ctx context.Context, mod api.Module, pFile, eLock uint32) uint32 vfsOpenFilesMtx.Lock() defer vfsOpenFilesMtx.Unlock() of := vfsOpenFiles[ptr.ID()] - fLock := of.LockerState() + fLock := of.LockState() if assert && of.shared <= 0 { panic(assertErr + " [2bhkwg]") @@ -206,7 +208,7 @@ func vfsUnlock(ctx context.Context, mod api.Module, pFile, eLock uint32) uint32 return _OK case of.shared == 1: - if rc := of.ReleaseLock(); rc != _OK { + if rc := of.Unlock(); rc != _OK { return uint32(IOERR_UNLOCK) } ptr.SetLock(_NO_LOCK) @@ -230,7 +232,7 @@ func vfsCheckReservedLock(ctx context.Context, mod api.Module, pFile, pResOut ui defer vfsOpenFilesMtx.Unlock() of := vfsOpenFiles[ptr.ID()] - locked, rc := of.CheckReserved() + locked, rc := of.CheckReservedLock() if rc != _OK { return uint32(IOERR_CHECKRESERVEDLOCK) } diff --git a/vfs_lock_debug.go b/vfs_lock_noop.go similarity index 62% rename from vfs_lock_debug.go rename to vfs_lock_noop.go index 4b1ba31..22f04e3 100644 --- a/vfs_lock_debug.go +++ b/vfs_lock_noop.go @@ -2,17 +2,17 @@ package sqlite3 const assert = true -type vfsDebugLocker struct { - state uint32 +type vfsNoopLocker struct { + state vfsLockState } -var _ vfsLocker = &vfsDebugLocker{} +var _ vfsLocker = &vfsNoopLocker{} -func (l *vfsDebugLocker) LockerState() uint32 { +func (l *vfsNoopLocker) LockState() vfsLockState { return l.state } -func (l *vfsDebugLocker) LockShared() uint32 { +func (l *vfsNoopLocker) LockShared() uint32 { if assert && !(l.state == _NO_LOCK) { panic(assertErr + " [wz9dcw]") } @@ -20,7 +20,7 @@ func (l *vfsDebugLocker) LockShared() uint32 { return _OK } -func (l *vfsDebugLocker) LockReserved() uint32 { +func (l *vfsNoopLocker) LockReserved() uint32 { if assert && !(l.state == _SHARED_LOCK) { panic(assertErr + " [m9hcil]") } @@ -28,7 +28,7 @@ func (l *vfsDebugLocker) LockReserved() uint32 { return _OK } -func (l *vfsDebugLocker) LockPending() uint32 { +func (l *vfsNoopLocker) LockPending() uint32 { if assert && !(l.state == _SHARED_LOCK || l.state == _RESERVED_LOCK) { panic(assertErr + " [wx8nk2]") } @@ -36,7 +36,7 @@ func (l *vfsDebugLocker) LockPending() uint32 { return _OK } -func (l *vfsDebugLocker) LockExclusive() uint32 { +func (l *vfsNoopLocker) LockExclusive() uint32 { if assert && !(l.state == _PENDING_LOCK) { panic(assertErr + " [84nbax]") } @@ -44,7 +44,7 @@ func (l *vfsDebugLocker) LockExclusive() uint32 { return _OK } -func (l *vfsDebugLocker) DowngradeLock() uint32 { +func (l *vfsNoopLocker) DowngradeLock() uint32 { if assert && !(l.state > _SHARED_LOCK) { panic(assertErr + " [je31i3]") } @@ -52,7 +52,7 @@ func (l *vfsDebugLocker) DowngradeLock() uint32 { return _OK } -func (l *vfsDebugLocker) ReleaseLock() uint32 { +func (l *vfsNoopLocker) Unlock() uint32 { if assert && !(l.state > _NO_LOCK) { panic(assertErr + " [m6e9w5]") } @@ -60,8 +60,8 @@ func (l *vfsDebugLocker) ReleaseLock() uint32 { return _OK } -func (l *vfsDebugLocker) CheckReserved() (bool, uint32) { - if l.state > _SHARED_LOCK { +func (l *vfsNoopLocker) CheckReservedLock() (bool, uint32) { + if l.state >= _RESERVED_LOCK { return true, _OK } return false, _OK