aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--funcs.go2
-rw-r--r--tx.go2
-rw-r--r--var.go8
3 files changed, 9 insertions, 3 deletions
diff --git a/funcs.go b/funcs.go
index 91d6bc8..80c25b1 100644
--- a/funcs.go
+++ b/funcs.go
@@ -71,7 +71,9 @@ retry:
time.Sleep(time.Duration(ns))
}
}
+ tx.mu.Lock()
ret, retry := catchRetry(op, tx)
+ tx.mu.Unlock()
if retry {
expvars.Add("retries", 1)
// wait for one of the variables we read to change before retrying
diff --git a/tx.go b/tx.go
index 3a1506c..c064f76 100644
--- a/tx.go
+++ b/tx.go
@@ -121,12 +121,14 @@ func (tx *Tx) Assert(p bool) {
}
func (tx *Tx) reset() {
+ tx.mu.Lock()
for k := range tx.reads {
delete(tx.reads, k)
}
for k := range tx.writes {
delete(tx.writes, k)
}
+ tx.mu.Unlock()
tx.removeRetryProfiles()
tx.resetLocks()
}
diff --git a/var.go b/var.go
index f3b8d40..3f43096 100644
--- a/var.go
+++ b/var.go
@@ -27,9 +27,11 @@ func (v *Var) wakeWatchers(new VarValue) {
// We have to lock here to ensure that the Tx is waiting before we signal it. Otherwise we
// could signal it before it goes to sleep and it will miss the notification.
tx.mu.Lock()
- tx.cond.Broadcast()
- for !tx.waiting && !tx.completed {
- tx.cond.Wait()
+ if read := tx.reads[v]; read != nil && read.Changed(new) {
+ tx.cond.Broadcast()
+ for !tx.waiting && !tx.completed {
+ tx.cond.Wait()
+ }
}
tx.mu.Unlock()
return !v.value.Load().(VarValue).Changed(new)