diff options
author | Matt Joiner <anacrolix@gmail.com> | 2019-10-31 16:21:27 +1100 |
---|---|---|
committer | Matt Joiner <anacrolix@gmail.com> | 2019-10-31 16:21:27 +1100 |
commit | d04075d6f23e92c33e30b244d2f4fc99428ee285 (patch) | |
tree | 31a2c212f4c549e43ae2e605baa4f8fbc489a4a5 /funcs.go | |
parent | Panic when trying to set a nil Var (diff) | |
download | stm-d04075d6f23e92c33e30b244d2f4fc99428ee285.tar.gz stm-d04075d6f23e92c33e30b244d2f4fc99428ee285.tar.xz |
Add Tx.Return and a return value from Atomically
Diffstat (limited to 'funcs.go')
-rw-r--r-- | funcs.go | 26 |
1 files changed, 22 insertions, 4 deletions
@@ -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. |