From d04075d6f23e92c33e30b244d2f4fc99428ee285 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Thu, 31 Oct 2019 16:21:27 +1100 Subject: Add Tx.Return and a return value from Atomically --- funcs.go | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'funcs.go') diff --git a/funcs.go b/funcs.go index f87efb8..a7ff6e0 100644 --- a/funcs.go +++ b/funcs.go @@ -1,16 +1,33 @@ package stm // Atomically executes the atomic function fn. -func Atomically(fn func(*Tx)) { +func Atomically(fn func(*Tx)) interface{} { retry: // run the transaction tx := &Tx{ reads: make(map[*Var]uint64), writes: make(map[*Var]interface{}), } - if catchRetry(fn, tx) { - // wait for one of the variables we read to change before retrying - tx.wait() + var ret interface{} + if func() (retry bool) { + defer func() { + r := recover() + if r == nil { + return + } + if _ret, ok := r.(_return); ok { + ret = _ret.value + } else if r == Retry { + // wait for one of the variables we read to change before retrying + tx.wait() + retry = true + } else { + panic(r) + } + }() + fn(tx) + return false + }() { goto retry } // verify the read log @@ -25,6 +42,7 @@ retry: globalCond.Broadcast() } globalLock.Unlock() + return ret } // AtomicGet is a helper function that atomically reads a value. -- cgit v1.2.3