From d8bd6b70ce49f38d6282da2ae30640814de4de61 Mon Sep 17 00:00:00 2001 From: Stephen J Day Date: Mon, 9 Oct 2017 20:34:24 -0700 Subject: [PATCH] plugin: allow querying plugin graph to be re-entrant Signed-off-by: Stephen J Day --- plugin/plugin.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/plugin/plugin.go b/plugin/plugin.go index bcd4013c2..03a8ebad6 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -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 } } }