From 034eb063640eff64466118965deb66ae06b114a8 Mon Sep 17 00:00:00 2001 From: nikandfor Date: Sat, 6 Jan 2024 16:36:43 +0100 Subject: [PATCH] bug fix --- batch3.go | 25 ++++++++++++++++++------- go.mod | 2 ++ multi.go | 5 ++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/batch3.go b/batch3.go index 742cc06..aca44b1 100644 --- a/batch3.go +++ b/batch3.go @@ -22,9 +22,10 @@ type ( cnt int // number of goroutines in a critical zone - res Res - err error - ready bool + res Res + err error + + in, out bool } Batch[Res any] struct { @@ -116,7 +117,7 @@ func (c *Controller[Res]) exit() int { if c.cnt == 0 { var zero Res c.res, c.err = zero, nil - c.ready = false + c.in, c.out = false, false } c.mu.Unlock() @@ -133,12 +134,14 @@ func (c *Controller[Res]) commit(ctx context.Context, err error) (Res, error) { again: if err != nil || atomic.LoadInt32(&c.queue) == 0 { c.cnt = -c.cnt - c.ready = true + c.in = true if ep, ok := err.(PanicError); ok { + c.out = true c.err = err panic(ep.Panic) } else if err != nil { + c.out = true c.err = err } else { func() { @@ -146,6 +149,7 @@ again: var err error defer func() { + c.out = true c.res, c.err = res, err if p := recover(); p != nil { @@ -162,7 +166,7 @@ again: } else { c.cond.Wait() - if !c.ready { + if !c.in { goto again } } @@ -260,8 +264,15 @@ func (b *Batch[Res]) Rollback(ctx context.Context, err error) (Res, error) { return b.c.commit(ctx, err) } +func AsPanicError(err error) (PanicError, bool) { + var pe PanicError + + return pe, errors.As(err, &pe) +} + func (e PanicError) Error() string { return fmt.Sprintf("panic: %v", e.Panic) } -func (noCopy) Lock() {} +func (*noCopy) Lock() {} +func (*noCopy) Unlock() {} diff --git a/go.mod b/go.mod index 3750a31..cfbd2ff 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module nikand.dev/go/batch go 1.18 + +retract v0.4.0 // has a bug diff --git a/multi.go b/multi.go index f42d577..844a89c 100644 --- a/multi.go +++ b/multi.go @@ -40,7 +40,10 @@ func (c *Multi[Res]) Enter(blocking bool) (b Batch[Res], coach, index int) { for coach := range c.cs { b, idx := c.cs[coach].Enter(false) if idx >= 0 { - return b, coach, idx + return Batch[Res]{ + c: b.c, + state: b.state, + }, coach, idx } }