aboutsummaryrefslogtreecommitdiff
path: root/var.go
diff options
context:
space:
mode:
authorMatt Joiner <anacrolix@gmail.com>2020-09-30 18:12:44 +1000
committerMatt Joiner <anacrolix@gmail.com>2020-09-30 18:12:44 +1000
commit47e5cc608cded44f87c3120fd76fa31a9b8a8867 (patch)
tree24f618b1e37852423b2787325ceb40ff25221fbe /var.go
parentSleep by default again, and don't bother sleeping for less than 100 microseconds (diff)
downloadstm-47e5cc608cded44f87c3120fd76fa31a9b8a8867.tar.gz
stm-47e5cc608cded44f87c3120fd76fa31a9b8a8867.tar.xz
Don't sleep and only wake watchers if the variable value has changed
Diffstat (limited to 'var.go')
-rw-r--r--var.go11
1 files changed, 9 insertions, 2 deletions
diff --git a/var.go b/var.go
index cdf9667..7e50cac 100644
--- a/var.go
+++ b/var.go
@@ -13,13 +13,20 @@ type Var struct {
}
func (v *Var) changeValue(new interface{}) {
- v.value.Store(v.value.Load().(VarValue).Set(new))
- v.wakeWatchers()
+ old := v.value.Load().(VarValue)
+ newVarValue := old.Set(new)
+ v.value.Store(newVarValue)
+ if old.Changed(newVarValue) {
+ v.wakeWatchers()
+ }
}
func (v *Var) wakeWatchers() {
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()
tx.mu.Unlock()