aboutsummaryrefslogtreecommitdiff
path: root/funcs.go
diff options
context:
space:
mode:
authorMatt Joiner <anacrolix@gmail.com>2019-10-31 16:35:43 +1100
committerMatt Joiner <anacrolix@gmail.com>2019-10-31 16:35:43 +1100
commite6b2d4ff0d0d5afaf71ef6df45351909faf7c87b (patch)
treefa264666735c15bc05782a6b4f53ccf545207365 /funcs.go
parentPanic when trying to set a nil Var (diff)
parentAdd Tx.Return and a return value from Atomically (diff)
downloadstm-e6b2d4ff0d0d5afaf71ef6df45351909faf7c87b.tar.gz
stm-e6b2d4ff0d0d5afaf71ef6df45351909faf7c87b.tar.xz
Merge branch 'master' into var-conds
* master: Add Tx.Return and a return value from Atomically Panic when trying to set a nil Var # Conflicts: # funcs.go
Diffstat (limited to 'funcs.go')
-rw-r--r--funcs.go26
1 files changed, 22 insertions, 4 deletions
diff --git a/funcs.go b/funcs.go
index 7b5df38..4967e83 100644
--- a/funcs.go
+++ b/funcs.go
@@ -1,7 +1,7 @@
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{
@@ -9,9 +9,26 @@ retry:
writes: make(map[*Var]interface{}),
}
tx.cond.L = &globalLock
- 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
@@ -23,6 +40,7 @@ retry:
// commit the write log and broadcast that variables have changed
tx.commit()
globalLock.Unlock()
+ return ret
}
// AtomicGet is a helper function that atomically reads a value.