diff options
Diffstat (limited to 'funcs.go')
-rw-r--r-- | funcs.go | 26 |
1 files changed, 22 insertions, 4 deletions
@@ -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. |