plugin: allow querying plugin graph to be re-entrant

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day 2017-10-09 20:34:24 -07:00
parent 363d692f35
commit d8bd6b70ce
No known key found for this signature in database
GPG Key ID: 67B3DED84EDC823F

View File

@ -70,7 +70,7 @@ type Service interface {
}
var register = struct {
sync.Mutex
sync.RWMutex
r []*Registration
}{}
@ -103,24 +103,28 @@ func Register(r *Registration) {
// Graph returns an ordered list of registered plugins for initialization
func Graph() (ordered []*Registration) {
register.RLock()
defer register.RUnlock()
added := map[*Registration]bool{}
for _, r := range register.r {
children(r.Requires, &ordered)
if !r.added {
children(r.Requires, added, &ordered)
if !added[r] {
ordered = append(ordered, r)
r.added = true
added[r] = true
}
}
return ordered
}
func children(types []Type, ordered *[]*Registration) {
func children(types []Type, added map[*Registration]bool, ordered *[]*Registration) {
for _, t := range types {
for _, r := range register.r {
if r.Type == t {
children(r.Requires, ordered)
if !r.added {
children(r.Requires, added, ordered)
if !added[r] {
*ordered = append(*ordered, r)
r.added = true
added[r] = true
}
}
}