@@ -2,7 +2,6 @@ package memdb
22
33import (
44 "io"
5- "runtime"
65 "sync"
76 "time"
87
@@ -85,9 +84,10 @@ type memDB struct {
8584 // +checklocks:memoryMtx
8685 refs int32
8786
88- shared int32 // +checklocks:lockMtx
89- pending bool // +checklocks:lockMtx
90- reserved bool // +checklocks:lockMtx
87+ shared int32 // +checklocks:lockMtx
88+ pending bool // +checklocks:lockMtx
89+ reserved bool // +checklocks:lockMtx
90+ waiter * sync.Cond // +checklocks:lockMtx
9191
9292 lockMtx sync.Mutex
9393 dataMtx sync.RWMutex
@@ -195,8 +195,6 @@ func (m *memFile) Size() (int64, error) {
195195 return m .size , nil
196196}
197197
198- const spinWait = 25 * time .Microsecond
199-
200198func (m * memFile ) Lock (lock vfs.LockLevel ) error {
201199 if m .lock >= lock {
202200 return nil
@@ -228,13 +226,18 @@ func (m *memFile) Lock(lock vfs.LockLevel) error {
228226 m .pending = true
229227 }
230228
231- for before := time .Now (); m .shared > 1 ; {
232- if time .Since (before ) > spinWait {
233- return sqlite3 .BUSY
229+ if m .shared > 1 {
230+ before := time .Now ()
231+ if m .waiter == nil {
232+ m .waiter = sync .NewCond (& m .lockMtx )
233+ }
234+ defer time .AfterFunc (time .Millisecond , m .waiter .Broadcast ).Stop ()
235+ for m .shared > 1 {
236+ if time .Since (before ) > time .Millisecond {
237+ return sqlite3 .BUSY
238+ }
239+ m .waiter .Wait ()
234240 }
235- m .lockMtx .Unlock ()
236- runtime .Gosched ()
237- m .lockMtx .Lock ()
238241 }
239242 }
240243
@@ -257,7 +260,9 @@ func (m *memFile) Unlock(lock vfs.LockLevel) error {
257260 m .pending = false
258261 }
259262 if lock < vfs .LOCK_SHARED {
260- m .shared --
263+ if m .shared -- ; m .pending && m .shared <= 1 && m .waiter != nil {
264+ m .waiter .Broadcast ()
265+ }
261266 }
262267 m .lock = lock
263268 return nil
0 commit comments