engine: graph: Use an rwmutex around read/write of vertex state

This fixes two small races we had while simultaneously reading from and
writing to the vertex timestamp, and simultaneously writing to the
vertex isStateOK (dirty) flag.

They were actually "safe" races, in that it doesn't matter if the
read/write race got the old or new value, or that the double write
happened. The time sequencing was correct (I believe) in both cases, but
this triggers the race detector now that we have tests for it.
This commit is contained in:
James Shubin
2024-01-02 18:01:45 -05:00
parent a07dc0a511
commit c2f508e261
3 changed files with 37 additions and 6 deletions

View File

@@ -64,6 +64,8 @@ type State struct {
isStateOK bool // is state OK or do we need to run CheckApply ?
workerErr error // did the Worker error?
mutex *sync.RWMutex // used for editing state properties
// doneCtx is cancelled when Watch should shut down. When any of the
// following channels close, it causes this to close.
doneCtx context.Context
@@ -143,6 +145,7 @@ func (obj *State) Init() error {
return fmt.Errorf("the Logf function is missing")
}
obj.mutex = &sync.RWMutex{}
obj.doneCtx, obj.doneCtxCancel = context.WithCancel(context.Background())
obj.processDone = make(chan struct{})
@@ -387,7 +390,9 @@ func (obj *State) event() {
// CheckApply will have some work to do in order to converge it.
func (obj *State) setDirty() {
obj.tuid.StopTimer()
obj.isStateOK = false
obj.mutex.Lock()
obj.isStateOK = false // concurrent write
obj.mutex.Unlock()
}
// poll is a replacement for Watch when the Poll metaparameter is used.