Browse code

vendor: swarmkit to fix deadlock in log broker

Signed-off-by: Ameya Gawde <agawde@mirantis.com>

Ameya Gawde authored on 2021/06/24 06:59:26
Showing 2 changed files
... ...
@@ -142,7 +142,7 @@ github.com/gogo/googleapis                          01e0f9cca9b92166042241267ee2
142 142
 github.com/cilium/ebpf                              1c8d4c9ef7759622653a1d319284a44652333b28
143 143
 
144 144
 # cluster
145
-github.com/docker/swarmkit                          17d8d4e4d8bdec33d386e6362d3537fa9493ba00
145
+github.com/docker/swarmkit                          c9afb5fd44bb419bae719f400f31671712bcb99e # bump_20.10
146 146
 github.com/gogo/protobuf                            5628607bb4c51c3157aacc3a50f0ab707582b805 # v1.3.1
147 147
 github.com/golang/protobuf                          84668698ea25b64748563aa20726db66a6b8d299 # v1.3.5
148 148
 github.com/cloudflare/cfssl                         5d63dbd981b5c408effbb58c442d54761ff94fbd # 1.3.2
... ...
@@ -204,20 +204,31 @@ func (s *subscription) watch(ch <-chan events.Event) error {
204 204
 	}
205 205
 
206 206
 	add := func(t *api.Task) {
207
+		// this mutex does not have a deferred unlock, because there is work
208
+		// we need to do after we release it.
207 209
 		s.mu.Lock()
208
-		defer s.mu.Unlock()
209 210
 
210 211
 		// Un-allocated task.
211 212
 		if t.NodeID == "" {
212 213
 			s.pendingTasks[t.ID] = struct{}{}
214
+			s.mu.Unlock()
213 215
 			return
214 216
 		}
215 217
 
216 218
 		delete(s.pendingTasks, t.ID)
217 219
 		if _, ok := s.nodes[t.NodeID]; !ok {
218 220
 			s.nodes[t.NodeID] = struct{}{}
221
+
222
+			s.mu.Unlock()
223
+
224
+			// if we try to call Publish before we release the lock, we can end
225
+			// up in a situation where the receiver is trying to acquire a read
226
+			// lock on it. it's hard to explain.
219 227
 			s.changed.Publish(s)
228
+			return
220 229
 		}
230
+
231
+		s.mu.Unlock()
221 232
 	}
222 233
 
223 234
 	for {