Skip to content

Commit 1f3c9c6

Browse files
committed
Try blocking locks again.
1 parent b64b9b0 commit 1f3c9c6

File tree

4 files changed

+64
-229
lines changed

4 files changed

+64
-229
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 207 deletions
Original file line numberDiff line numberDiff line change
@@ -22,215 +22,10 @@ permissions:
2222

2323
jobs:
2424
test:
25-
strategy:
26-
matrix:
27-
os: [macos-latest, ubuntu-latest, windows-latest]
28-
runs-on: ${{ matrix.os }}
29-
permissions:
30-
contents: write
25+
runs-on: windows-latest
3126

3227
steps:
3328
- uses: actions/checkout@v4
34-
- uses: actions/setup-go@v5
35-
with: { go-version: stable }
36-
37-
- name: Format
38-
run: gofmt -s -w . && git diff --exit-code
39-
if: matrix.os != 'windows-latest'
40-
41-
- name: Tidy
42-
run: go mod tidy && git diff --exit-code
43-
44-
- name: Download
45-
run: go mod download
46-
47-
- name: Verify
48-
run: go mod verify
49-
50-
- name: Vet
51-
run: go vet ./...
52-
53-
- name: Build
54-
run: go build -v ./...
55-
56-
- name: Test
57-
run: go test -v ./... -bench . -benchtime=1x
58-
59-
- name: Test BSD locks
60-
run: go test -v -tags sqlite3_flock ./...
61-
if: matrix.os != 'windows-latest'
62-
63-
- name: Test dot locks
64-
run: go test -v -tags sqlite3_dotlk ./...
65-
if: matrix.os != 'windows-latest'
66-
67-
- name: Test modules
68-
shell: bash
69-
run: |
70-
go work init .
71-
go work use -r embed gormlite
72-
go test -v ./embed/bcw2/...
73-
74-
- name: Test GORM
75-
shell: bash
76-
run: gormlite/test.sh
77-
if: matrix.os != 'windows-latest'
78-
79-
- name: Collect coverage
80-
run: |
81-
go get -tool github.com/dave/courtney@v0.4.4
82-
go tool courtney
83-
if: |
84-
github.event_name == 'push' &&
85-
matrix.os == 'ubuntu-latest'
86-
87-
- uses: ncruces/go-coverage-report@v0
88-
with:
89-
coverage-file: coverage.out
90-
chart: true
91-
amend: true
92-
if: |
93-
github.event_name == 'push' &&
94-
matrix.os == 'ubuntu-latest'
95-
96-
test-bsd:
97-
strategy:
98-
matrix:
99-
os:
100-
- name: freebsd
101-
version: '14.2'
102-
flags: '-test.v'
103-
- name: netbsd
104-
version: '10.1'
105-
flags: '-test.v'
106-
- name: freebsd
107-
arch: arm64
108-
version: '14.2'
109-
flags: '-test.v -test.short'
110-
- name: netbsd
111-
arch: arm64
112-
version: '10.1'
113-
flags: '-test.v -test.short'
114-
- name: openbsd
115-
version: '7.7'
116-
flags: '-test.v -test.short'
117-
runs-on: ubuntu-latest
118-
needs: test
119-
120-
steps:
121-
- uses: actions/checkout@v4
122-
123-
- name: Build
124-
env:
125-
GOOS: ${{ matrix.os.name }}
126-
GOARCH: ${{ matrix.os.arch }}
127-
TESTFLAGS: ${{ matrix.os.flags }}
128-
run: .github/workflows/build-test.sh
129-
130-
- name: Test
131-
uses: cross-platform-actions/action@v0.28.0
132-
with:
133-
operating_system: ${{ matrix.os.name }}
134-
architecture: ${{ matrix.os.arch }}
135-
version: ${{ matrix.os.version }}
136-
shell: bash
137-
run: . ./test.sh
138-
sync_files: runner-to-vm
139-
140-
test-vm:
141-
strategy:
142-
matrix:
143-
os:
144-
- name: dragonfly
145-
action: 'vmactions/dragonflybsd-vm@v1'
146-
tflags: '-test.v'
147-
- name: illumos
148-
action: 'vmactions/omnios-vm@v1'
149-
tflags: '-test.v'
150-
- name: solaris
151-
action: 'vmactions/solaris-vm@v1'
152-
bflags: '-tags sqlite3_dotlk'
153-
tflags: '-test.v'
154-
runs-on: ubuntu-latest
155-
needs: test
156-
157-
steps:
158-
- uses: actions/checkout@v4
159-
160-
- name: Build
161-
env:
162-
GOOS: ${{ matrix.os.name }}
163-
BUILDFLAGS: ${{ matrix.os.bflags }}
164-
TESTFLAGS: ${{ matrix.os.tflags }}
165-
VMACTIONS: ${{ matrix.os.action }}
166-
run: .github/workflows/build-test.sh
167-
168-
- name: Test
169-
uses: ./.github/actions/vmactions
170-
171-
test-wasip1:
172-
runs-on: ubuntu-latest
173-
needs: test
174-
175-
steps:
176-
- uses: bytecodealliance/actions/wasmtime/setup@v1
177-
- uses: actions/checkout@v4
178-
- uses: actions/setup-go@v5
179-
with: { go-version: stable }
180-
181-
- name: Set path
182-
run: echo "$(go env GOROOT)/lib/wasm" >> "$GITHUB_PATH"
183-
184-
- name: Test wasmtime
185-
env:
186-
GOOS: wasip1
187-
GOARCH: wasm
188-
GOWASIRUNTIME: wasmtime
189-
GOWASIRUNTIMEARGS: '--env CI=true'
190-
run: go test -v -short -tags sqlite3_dotlk -skip Example ./...
191-
192-
test-qemu:
193-
runs-on: ubuntu-latest
194-
needs: test
195-
196-
steps:
197-
- uses: docker/setup-qemu-action@v3
198-
- uses: actions/checkout@v4
199-
- uses: actions/setup-go@v5
200-
with: { go-version: stable }
201-
202-
- name: Test 386 (32-bit)
203-
run: GOARCH=386 go test -v -short ./...
204-
205-
- name: Test riscv64 (interpreter)
206-
run: GOARCH=riscv64 go test -v -short ./...
207-
208-
- name: Test ppc64le (interpreter)
209-
run: GOARCH=ppc64le go test -v -short ./...
210-
211-
- name: Test s390x (big-endian)
212-
run: GOARCH=s390x go test -v -short -tags sqlite3_dotlk ./...
213-
214-
test-linuxarm:
215-
runs-on: ubuntu-24.04-arm
216-
needs: test
217-
218-
steps:
219-
- uses: actions/checkout@v4
220-
- uses: actions/setup-go@v5
221-
with: { go-version: stable }
222-
223-
- name: Test
224-
run: go test -v ./...
225-
226-
test-macintel:
227-
runs-on: macos-13
228-
needs: test
229-
230-
steps:
231-
- uses: actions/checkout@v4
232-
- uses: actions/setup-go@v5
233-
with: { go-version: stable }
23429

23530
- name: Test
236-
run: go test -v ./...
31+
run: go test -v ./tests/parallel -run Test_wal -count 10

util/osutil/osfs.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,3 @@ func (FS) Stat(name string) (fs.FileInfo, error) {
3232
func (FS) ReadFile(name string) ([]byte, error) {
3333
return os.ReadFile(name)
3434
}
35-
36-
// OpenFile behaves the same as [os.OpenFile].
37-
//
38-
// Deprecated: use os.OpenFile instead.
39-
func OpenFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
40-
return os.OpenFile(name, flag, perm)
41-
}

vfs/os_windows.go

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package vfs
44

55
import (
6+
"math"
67
"os"
78
"time"
89

@@ -133,13 +134,7 @@ func osWriteLock(file *os.File, start, len uint32, timeout time.Duration) _Error
133134
}
134135

135136
func osLock(file *os.File, flags, start, len uint32, timeout time.Duration, def _ErrorCode) _ErrorCode {
136-
var err error
137-
switch {
138-
default:
139-
err = osLockEx(file, flags|windows.LOCKFILE_FAIL_IMMEDIATELY, start, len)
140-
case timeout < 0:
141-
err = osLockEx(file, flags, start, len)
142-
}
137+
err := osLockEx(file, flags, start, len, timeout)
143138
return osLockErrorCode(err, def)
144139
}
145140

@@ -155,9 +150,40 @@ func osUnlock(file *os.File, start, len uint32) _ErrorCode {
155150
return _OK
156151
}
157152

158-
func osLockEx(file *os.File, flags, start, len uint32) error {
159-
return windows.LockFileEx(windows.Handle(file.Fd()), flags,
160-
0, len, 0, &windows.Overlapped{Offset: start})
153+
func osLockEx(file *os.File, flags, start, len uint32, timeout time.Duration) error {
154+
event, err := windows.CreateEvent(nil, 1, 0, nil)
155+
if err != nil {
156+
return err
157+
}
158+
defer windows.CloseHandle(event)
159+
160+
fd := windows.Handle(file.Fd())
161+
overlapped := &windows.Overlapped{
162+
Offset: start,
163+
HEvent: event,
164+
}
165+
if timeout == 0 {
166+
flags |= windows.LOCKFILE_FAIL_IMMEDIATELY
167+
}
168+
169+
err = windows.LockFileEx(fd, flags, 0, len, 0, overlapped)
170+
if err != windows.ERROR_IO_PENDING {
171+
return err
172+
}
173+
defer windows.CancelIoEx(fd, overlapped)
174+
175+
var ms uint32 = math.MaxUint32
176+
if timeout > 0 {
177+
ms = 10 + uint32(timeout/time.Millisecond)
178+
}
179+
rc, err := windows.WaitForSingleObject(event, ms)
180+
if rc == windows.WAIT_OBJECT_0 {
181+
return nil
182+
}
183+
if err != nil {
184+
return err
185+
}
186+
return windows.Errno(rc)
161187
}
162188

163189
func osLockErrorCode(err error, def _ErrorCode) _ErrorCode {

vfs/shm_windows.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io"
88
"os"
99
"sync"
10+
"time"
1011

1112
"github.com/tetratelabs/wazero/api"
1213
"golang.org/x/sys/windows"
@@ -26,9 +27,12 @@ type vfsShm struct {
2627
ptrs []ptr_t
2728
stack [1]stk_t
2829
fileLock bool
30+
blocking bool
2931
sync.Mutex
3032
}
3133

34+
var _ blockingSharedMemory = &vfsShm{}
35+
3236
func (s *vfsShm) Close() error {
3337
// Unmap regions.
3438
for _, r := range s.regions {
@@ -42,11 +46,19 @@ func (s *vfsShm) Close() error {
4246

4347
func (s *vfsShm) shmOpen() _ErrorCode {
4448
if s.File == nil {
45-
f, err := os.OpenFile(s.path, os.O_RDWR|os.O_CREATE, 0666)
49+
path, err := windows.UTF16PtrFromString(s.path)
50+
if err != nil {
51+
return _CANTOPEN
52+
}
53+
h, err := windows.CreateFile(path,
54+
windows.GENERIC_READ|windows.GENERIC_WRITE,
55+
windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE,
56+
nil, windows.OPEN_ALWAYS,
57+
windows.FILE_ATTRIBUTE_NORMAL|windows.FILE_FLAG_OVERLAPPED, 0)
4658
if err != nil {
4759
return _CANTOPEN
4860
}
49-
s.File = f
61+
s.File = os.NewFile(uintptr(h), s.path)
5062
}
5163
if s.fileLock {
5264
return _OK
@@ -60,7 +72,7 @@ func (s *vfsShm) shmOpen() _ErrorCode {
6072
return _IOERR_SHMOPEN
6173
}
6274
}
63-
rc := osReadLock(s.File, _SHM_DMS, 1, 0)
75+
rc := osReadLock(s.File, _SHM_DMS, 1, time.Millisecond)
6476
s.fileLock = rc == _OK
6577
return rc
6678
}
@@ -128,6 +140,11 @@ func (s *vfsShm) shmMap(ctx context.Context, mod api.Module, id, size int32, ext
128140
}
129141

130142
func (s *vfsShm) shmLock(offset, n int32, flags _ShmFlag) (rc _ErrorCode) {
143+
var timeout time.Duration
144+
if s.blocking {
145+
timeout = time.Millisecond
146+
}
147+
131148
switch {
132149
case flags&_SHM_LOCK != 0:
133150
defer s.shmAcquire(&rc)
@@ -139,9 +156,9 @@ func (s *vfsShm) shmLock(offset, n int32, flags _ShmFlag) (rc _ErrorCode) {
139156
case flags&_SHM_UNLOCK != 0:
140157
return osUnlock(s.File, _SHM_BASE+uint32(offset), uint32(n))
141158
case flags&_SHM_SHARED != 0:
142-
return osReadLock(s.File, _SHM_BASE+uint32(offset), uint32(n), 0)
159+
return osReadLock(s.File, _SHM_BASE+uint32(offset), uint32(n), timeout)
143160
case flags&_SHM_EXCLUSIVE != 0:
144-
return osWriteLock(s.File, _SHM_BASE+uint32(offset), uint32(n), 0)
161+
return osWriteLock(s.File, _SHM_BASE+uint32(offset), uint32(n), timeout)
145162
default:
146163
panic(util.AssertErr())
147164
}
@@ -172,3 +189,7 @@ func (s *vfsShm) shmUnmap(delete bool) {
172189
os.Remove(s.path)
173190
}
174191
}
192+
193+
func (s *vfsShm) shmEnableBlocking(block bool) {
194+
s.blocking = block
195+
}

0 commit comments

Comments
 (0)