pgraph: semaphore: Add lock around semaphore map

I forgot about the `concurrent map write` race, but now it's fixed. I
suppose we could probably pre-create all semaphores in the graph at once
before Start, and remove this lock, but that's an optimization for a
later day.
This commit is contained in:
James Shubin
2017-03-11 09:06:18 -05:00
parent b740e0b78a
commit 6d9be15035
2 changed files with 5 additions and 0 deletions

View File

@@ -61,6 +61,7 @@ type Graph struct {
mutex *sync.Mutex // used when modifying graph State variable mutex *sync.Mutex // used when modifying graph State variable
wg *sync.WaitGroup wg *sync.WaitGroup
semas map[string]*semaphore.Semaphore semas map[string]*semaphore.Semaphore
slock *sync.Mutex // semaphore mutex
prometheus *prometheus.Prometheus // the prometheus instance prometheus *prometheus.Prometheus // the prometheus instance
} }
@@ -89,6 +90,7 @@ func NewGraph(name string) *Graph {
mutex: &sync.Mutex{}, mutex: &sync.Mutex{},
wg: &sync.WaitGroup{}, wg: &sync.WaitGroup{},
semas: make(map[string]*semaphore.Semaphore), semas: make(map[string]*semaphore.Semaphore),
slock: &sync.Mutex{},
} }
} }
@@ -126,6 +128,7 @@ func (g *Graph) Copy() *Graph {
mutex: g.mutex, mutex: g.mutex,
wg: g.wg, wg: g.wg,
semas: g.semas, semas: g.semas,
slock: g.slock,
prometheus: g.prometheus, prometheus: g.prometheus,
} }

View File

@@ -46,11 +46,13 @@ func (g *Graph) SemaLock(semas []string) error {
} }
} }
g.slock.Lock() // semaphore creation lock
sema, ok := g.semas[id] // lookup sema, ok := g.semas[id] // lookup
if !ok { if !ok {
g.semas[id] = semaphore.NewSemaphore(size) g.semas[id] = semaphore.NewSemaphore(size)
sema = g.semas[id] sema = g.semas[id]
} }
g.slock.Unlock()
if err := sema.P(1); err != nil { // lock! if err := sema.P(1); err != nil { // lock!
reterr = multierr.Append(reterr, err) // list of errors reterr = multierr.Append(reterr, err) // list of errors