Skip to content

Commit

Permalink
Avoid syscall.
Browse files Browse the repository at this point in the history
  • Loading branch information
ncruces committed Dec 21, 2024
1 parent e08c7b3 commit f2d8941
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 8 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ jobs:
shell: bash
run: gormlite/test.sh

- name: Test modules
shell: bash
run: go test -v ./embed/bcw2/...

- name: Collect coverage
run: go run github.com/dave/courtney@latest
if: |
Expand Down
69 changes: 64 additions & 5 deletions tests/parallel/parallel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func Test_xts(t *testing.T) {
testIntegrity(t, name)
}

func TestMultiProcess(t *testing.T) {
func Test_MultiProcess_rollback(t *testing.T) {
if !vfs.SupportsFileLocking {
t.Skip("skipping without locks")
}
Expand All @@ -149,7 +149,7 @@ func TestMultiProcess(t *testing.T) {
}

file := filepath.Join(t.TempDir(), "test.db")
t.Setenv("TestMultiProcess_dbfile", file)
t.Setenv("Test_MultiProcess_dbfile", file)

name := "file:" + filepath.ToSlash(file) +
"?_pragma=busy_timeout(10000)" +
Expand All @@ -161,7 +161,7 @@ func TestMultiProcess(t *testing.T) {
t.Fatal(err)
}

cmd := exec.Command(exe, append(os.Args[1:], "-test.v", "-test.run=TestChildProcess")...)
cmd := exec.Command(exe, append(os.Args[1:], "-test.v", "-test.run=Test_ChildProcess_rollback")...)
out, err := cmd.StdoutPipe()
if err != nil {
t.Fatal(err)
Expand All @@ -185,8 +185,8 @@ func TestMultiProcess(t *testing.T) {
testIntegrity(t, name)
}

func TestChildProcess(t *testing.T) {
file := os.Getenv("TestMultiProcess_dbfile")
func Test_ChildProcess_rollback(t *testing.T) {
file := os.Getenv("Test_MultiProcess_dbfile")
if file == "" || testing.Short() {
t.SkipNow()
}
Expand All @@ -199,6 +199,65 @@ func TestChildProcess(t *testing.T) {
testParallel(t, name, 1000)
}

func Test_MultiProcess_wal(t *testing.T) {
if !vfs.SupportsFileLocking {
t.Skip("skipping without locks")
}
if testing.Short() {
t.Skip("skipping in short mode")
}

file := filepath.Join(t.TempDir(), "test.db")
t.Setenv("Test_MultiProcess_dbfile", file)

name := "file:" + filepath.ToSlash(file) +
"?_pragma=busy_timeout(10000)" +
"&_pragma=journal_mode(wal)" +
"&_pragma=synchronous(off)"

exe, err := os.Executable()
if err != nil {
t.Fatal(err)
}

cmd := exec.Command(exe, append(os.Args[1:], "-test.v", "-test.run=Test_ChildProcess_wal")...)
out, err := cmd.StdoutPipe()
if err != nil {
t.Fatal(err)
}
if err := cmd.Start(); err != nil {
t.Fatal(err)
}

var buf [3]byte
// Wait for child to start.
if _, err := io.ReadFull(out, buf[:]); err != nil {
t.Fatal(err)
} else if str := string(buf[:]); str != "===" {
t.Fatal(str)
}

testParallel(t, name, 1000)
if err := cmd.Wait(); err != nil {
t.Error(err)
}
testIntegrity(t, name)
}

func Test_ChildProcess_wal(t *testing.T) {
file := os.Getenv("Test_MultiProcess_dbfile")
if file == "" || testing.Short() {
t.SkipNow()
}

name := "file:" + filepath.ToSlash(file) +
"?_pragma=busy_timeout(10000)" +
"&_pragma=journal_mode(wal)" +
"&_pragma=synchronous(off)"

testParallel(t, name, 1000)
}

func Benchmark_parallel(b *testing.B) {
if !vfs.SupportsSharedMemory {
b.Skip("skipping without shared memory")
Expand Down
16 changes: 13 additions & 3 deletions vfs/shm_bsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func (s *vfsShm) shmLock(offset, n int32, flags _ShmFlag) _ErrorCode {
s.Lock()
defer s.Unlock()

// Check if we could obtain/release the lock locally.
// Check if we can obtain/release locks locally.
rc := s.shmMemLock(offset, n, flags)
if rc != _OK {
return rc
Expand All @@ -187,6 +187,8 @@ func (s *vfsShm) shmLock(offset, n int32, flags _ShmFlag) _ErrorCode {
// Obtain/release the appropriate file locks.
switch {
case flags&_SHM_UNLOCK != 0:
// Relasing a shared lock decrements the counter,
// but may leave parts of the range still locked.
begin, end := offset, offset+n
for i := begin; i < end; i++ {
if s.vfsShmParent.lock[i] != 0 {
Expand All @@ -201,14 +203,22 @@ func (s *vfsShm) shmLock(offset, n int32, flags _ShmFlag) _ErrorCode {
}
return rc
case flags&_SHM_SHARED != 0:
rc = osReadLock(s.File, _SHM_BASE+int64(offset), int64(n))
// Acquiring a new shared lock on the file is only necessary
// if there was a new shared lock in the range.
for i := offset; i < offset+n; i++ {
if s.vfsShmParent.lock[i] == 1 {
rc = osReadLock(s.File, _SHM_BASE+int64(offset), int64(n))
break
}
}
case flags&_SHM_EXCLUSIVE != 0:
// Acquiring an exclusive lock on the file is always necessary.
rc = osWriteLock(s.File, _SHM_BASE+int64(offset), int64(n))
default:
panic(util.AssertErr())
}

// Release the local lock we had acquired.
// Release the local locks we had acquired.
if rc != _OK {
s.shmMemLock(offset, n, flags^(_SHM_UNLOCK|_SHM_LOCK))
}
Expand Down

0 comments on commit f2d8941

Please sign in to comment.