Browse code

prevent data race in pkg/plugins

Signed-off-by: Victor Vieux <vieux@docker.com>

Victor Vieux authored on 2016/10/19 09:34:09
Showing 1 changed files
... ...
@@ -41,9 +41,14 @@ type plugins struct {
41 41
 	plugins map[string]*Plugin
42 42
 }
43 43
 
44
+type extpointHandlers struct {
45
+	sync.RWMutex
46
+	extpointHandlers map[string][]func(string, *Client)
47
+}
48
+
44 49
 var (
45
-	storage          = plugins{plugins: make(map[string]*Plugin)}
46
-	extpointHandlers = make(map[string][]func(string, *Client))
50
+	storage  = plugins{plugins: make(map[string]*Plugin)}
51
+	handlers = extpointHandlers{extpointHandlers: make(map[string][]func(string, *Client))}
47 52
 )
48 53
 
49 54
 // Manifest lists what a plugin implements.
... ...
@@ -128,15 +133,17 @@ func (p *Plugin) activateWithLock() error {
128 128
 
129 129
 	p.Manifest = m
130 130
 
131
+	handlers.RLock()
131 132
 	for _, iface := range m.Implements {
132
-		handlers, handled := extpointHandlers[iface]
133
+		hdlrs, handled := handlers.extpointHandlers[iface]
133 134
 		if !handled {
134 135
 			continue
135 136
 		}
136
-		for _, handler := range handlers {
137
+		for _, handler := range hdlrs {
137 138
 			handler(p.name, p.client)
138 139
 		}
139 140
 	}
141
+	handlers.RUnlock()
140 142
 	return nil
141 143
 }
142 144
 
... ...
@@ -228,16 +235,18 @@ func Get(name, imp string) (*Plugin, error) {
228 228
 
229 229
 // Handle adds the specified function to the extpointHandlers.
230 230
 func Handle(iface string, fn func(string, *Client)) {
231
-	handlers, ok := extpointHandlers[iface]
231
+	handlers.Lock()
232
+	hdlrs, ok := handlers.extpointHandlers[iface]
232 233
 	if !ok {
233
-		handlers = []func(string, *Client){}
234
+		hdlrs = []func(string, *Client){}
234 235
 	}
235 236
 
236
-	handlers = append(handlers, fn)
237
-	extpointHandlers[iface] = handlers
237
+	hdlrs = append(hdlrs, fn)
238
+	handlers.extpointHandlers[iface] = hdlrs
238 239
 	for _, p := range storage.plugins {
239 240
 		p.activated = false
240 241
 	}
242
+	handlers.Unlock()
241 243
 }
242 244
 
243 245
 // GetAll returns all the plugins for the specified implementation