aboutsummaryrefslogtreecommitdiff
path: root/var.go
diff options
context:
space:
mode:
authorMatt Joiner <anacrolix@gmail.com>2020-09-30 19:13:27 +1000
committerMatt Joiner <anacrolix@gmail.com>2020-09-30 19:13:27 +1000
commita3e788d52494b75b927538c9c2bfee1573aa50e1 (patch)
treef1eed1cda0c25008c51b375799b9d65a33ce080d /var.go
parentDon't sleep and only wake watchers if the variable value has changed (diff)
downloadstm-a3e788d52494b75b927538c9c2bfee1573aa50e1.tar.gz
stm-a3e788d52494b75b927538c9c2bfee1573aa50e1.tar.xz
Wake watchers until the var changes again
Diffstat (limited to 'var.go')
-rw-r--r--var.go10
1 files changed, 6 insertions, 4 deletions
diff --git a/var.go b/var.go
index 7e50cac..f3b8d40 100644
--- a/var.go
+++ b/var.go
@@ -17,20 +17,22 @@ func (v *Var) changeValue(new interface{}) {
newVarValue := old.Set(new)
v.value.Store(newVarValue)
if old.Changed(newVarValue) {
- v.wakeWatchers()
+ go v.wakeWatchers(newVarValue)
}
}
-func (v *Var) wakeWatchers() {
+func (v *Var) wakeWatchers(new VarValue) {
v.watchers.Range(func(k, _ interface{}) bool {
tx := k.(*Tx)
-
// 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()
+ }
tx.mu.Unlock()
- return true
+ return !v.value.Load().(VarValue).Changed(new)
})
}