mirror of
https://github.com/docker/compose.git
synced 2026-08-04 14:47:40 +00:00
Fix deadlock in ttyWriter.Done()
Resolves race condition between main thread calling Done() and UI thread calling printWithDimensions(). The issue was that Done() held the mutex while sending to the done channel, but the UI thread needed the same mutex to process the done signal. Fixed by sending the done signal before acquiring the mutex, allowing the UI thread to receive the signal and release any held locks. Fixes #13639 Signed-off-by: maks2134 <maks210306@yandex.by>
This commit is contained in:
parent
e8c2143498
commit
25b29d776b
8 changed files with 70 additions and 1 deletions
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
9
.idea/compose.iml
generated
Normal file
9
.idea/compose.iml
generated
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
7
.idea/golinter.xml
generated
Normal file
7
.idea/golinter.xml
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GoLinterSettings">
|
||||
<option name="customConfigFile" value="$PROJECT_DIR$/.golangci.yml" />
|
||||
<option name="useCustomConfigFile" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
10
.idea/material_theme_project_new.xml
generated
Normal file
10
.idea/material_theme_project_new.xml
generated
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MaterialThemeProjectNewConfig">
|
||||
<option name="metadata">
|
||||
<MTProjectMetadataState>
|
||||
<option name="userId" value="-7a070d14:19cf87c5499:-7ff2" />
|
||||
</MTProjectMetadataState>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/compose.iml" filepath="$PROJECT_DIR$/.idea/compose.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -176,13 +176,13 @@ func (w *ttyWriter) Start(ctx context.Context, operation string) {
|
|||
|
||||
func (w *ttyWriter) Done(operation string, success bool) {
|
||||
w.print()
|
||||
w.done <- true
|
||||
w.mtx.Lock()
|
||||
defer w.mtx.Unlock()
|
||||
if w.ticker != nil {
|
||||
w.ticker.Stop()
|
||||
}
|
||||
w.operation = ""
|
||||
w.done <- true
|
||||
}
|
||||
|
||||
func (w *ttyWriter) On(events ...api.Resource) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package display
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
|
@ -422,3 +423,23 @@ func TestLenAnsi(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoneDeadlockFix(t *testing.T) {
|
||||
w, _ := newTestWriter()
|
||||
addTask(w, "test-task", "Working", "details", api.Working)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
w.Start(ctx, "test")
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
w.Done("test", true)
|
||||
done <- true
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("Deadlock detected: Done() did not complete within 5 seconds")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue