Skip to content

Commit 21ba4a1

Browse files
committed
Fix a possible deadlock in the log broker
Fixes a case where certain situations in the logbroker can create a deadlock. Fixes moby/moby#42314. Signed-off-by: Drew Erny <[email protected]>
1 parent 5a5494a commit 21ba4a1

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

manager/logbroker/subscription.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,20 +204,31 @@ func (s *subscription) watch(ch <-chan events.Event) error {
204204
}
205205

206206
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.
207209
s.mu.Lock()
208-
defer s.mu.Unlock()
209210

210211
// Un-allocated task.
211212
if t.NodeID == "" {
212213
s.pendingTasks[t.ID] = struct{}{}
214+
s.mu.Unlock()
213215
return
214216
}
215217

216218
delete(s.pendingTasks, t.ID)
217219
if _, ok := s.nodes[t.NodeID]; !ok {
218220
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.
219227
s.changed.Publish(s)
228+
return
220229
}
230+
231+
s.mu.Unlock()
221232
}
222233

223234
for {

0 commit comments

Comments
 (0)