From: Matt Joiner Date: Tue, 12 Aug 2025 13:29:42 +0000 (+1000) Subject: Add checks that defers only occur on write locks X-Git-Tag: v1.59.0~2^2~28 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=f55725250a599db8e59034e4901950a6450b88f1;p=btrtrc.git Add checks that defers only occur on write locks --- diff --git a/deferrwl.go b/deferrwl.go index dd8011d0..e3aa93b8 100644 --- a/deferrwl.go +++ b/deferrwl.go @@ -5,6 +5,7 @@ import ( "reflect" g "github.com/anacrolix/generics" + "github.com/anacrolix/missinggo/v2/panicif" "github.com/anacrolix/sync" ) @@ -16,15 +17,18 @@ type lockWithDeferreds struct { unlockActions []func() uniqueActions map[any]struct{} // Currently unlocking, defers should not occur? - unlocking bool + allowDefers bool } func (me *lockWithDeferreds) Lock() { me.internal.Lock() + panicif.True(me.allowDefers) + me.allowDefers = true } func (me *lockWithDeferreds) Unlock() { - me.unlocking = true + panicif.False(me.allowDefers) + me.allowDefers = false startLen := len(me.unlockActions) var i int for i = 0; i < len(me.unlockActions); i++ { @@ -35,7 +39,6 @@ func (me *lockWithDeferreds) Unlock() { } me.unlockActions = me.unlockActions[:0] me.uniqueActions = nil - me.unlocking = false me.internal.Unlock() } @@ -49,19 +52,18 @@ func (me *lockWithDeferreds) RUnlock() { // Not allowed after unlock has started. func (me *lockWithDeferreds) Defer(action func()) { - if me.unlocking { - panic("defer called while unlocking") - } me.deferInner(action) } // Already guarded. func (me *lockWithDeferreds) deferInner(action func()) { + panicif.False(me.allowDefers) me.unlockActions = append(me.unlockActions, action) } // Protected from looping by once filter. func (me *lockWithDeferreds) deferOnceInner(key any, action func()) { + panicif.False(me.allowDefers) g.MakeMapIfNil(&me.uniqueActions) if g.MapContains(me.uniqueActions, key) { return