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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user