Skip to content

Commit 0dfb27e

Browse files
authored
Fixed an extremely rare race-condition during compile (#2512)
1 parent 47645e9 commit 0dfb27e

File tree

2 files changed

+19
-13
lines changed

2 files changed

+19
-13
lines changed

Diff for: internal/arduino/builder/internal/compilation/database.go

+14-8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"encoding/json"
2020
"fmt"
2121
"os"
22+
"sync"
2223

2324
"github.com/arduino/arduino-cli/internal/i18n"
2425
"github.com/arduino/go-paths-helper"
@@ -28,8 +29,9 @@ var tr = i18n.Tr
2829

2930
// Database keeps track of all the compile commands run by the builder
3031
type Database struct {
31-
Contents []Command
32-
File *paths.Path
32+
lock sync.Mutex
33+
contents []Command
34+
file *paths.Path
3335
}
3436

3537
// Command keeps track of a single run of a compile command
@@ -43,8 +45,8 @@ type Command struct {
4345
// NewDatabase creates an empty CompilationDatabase
4446
func NewDatabase(filename *paths.Path) *Database {
4547
return &Database{
46-
File: filename,
47-
Contents: []Command{},
48+
file: filename,
49+
contents: []Command{},
4850
}
4951
}
5052

@@ -55,16 +57,18 @@ func LoadDatabase(file *paths.Path) (*Database, error) {
5557
return nil, err
5658
}
5759
res := NewDatabase(file)
58-
return res, json.Unmarshal(f, &res.Contents)
60+
return res, json.Unmarshal(f, &res.contents)
5961
}
6062

6163
// SaveToFile save the CompilationDatabase to file as a clangd-compatible compile_commands.json,
6264
// see https://clang.llvm.org/docs/JSONCompilationDatabase.html
6365
func (db *Database) SaveToFile() {
64-
if jsonContents, err := json.MarshalIndent(db.Contents, "", " "); err != nil {
66+
db.lock.Lock()
67+
defer db.lock.Unlock()
68+
if jsonContents, err := json.MarshalIndent(db.contents, "", " "); err != nil {
6569
fmt.Println(tr("Error serializing compilation database: %s", err))
6670
return
67-
} else if err := db.File.WriteFile(jsonContents); err != nil {
71+
} else if err := db.file.WriteFile(jsonContents); err != nil {
6872
fmt.Println(tr("Error writing compilation database: %s", err))
6973
}
7074
}
@@ -88,5 +92,7 @@ func (db *Database) Add(target *paths.Path, command *paths.Process) {
8892
File: target.String(),
8993
}
9094

91-
db.Contents = append(db.Contents, entry)
95+
db.lock.Lock()
96+
db.contents = append(db.contents, entry)
97+
db.lock.Unlock()
9298
}

Diff for: internal/arduino/builder/internal/compilation/database_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ func TestCompilationDatabase(t *testing.T) {
3636
db2, err := LoadDatabase(tmpfile)
3737
require.NoError(t, err)
3838
require.Equal(t, db, db2)
39-
require.Len(t, db2.Contents, 1)
40-
require.Equal(t, db2.Contents[0].File, "test")
41-
require.Equal(t, db2.Contents[0].Command, "")
42-
require.Equal(t, db2.Contents[0].Arguments, []string{"gcc", "arg1", "arg2"})
39+
require.Len(t, db2.contents, 1)
40+
require.Equal(t, db2.contents[0].File, "test")
41+
require.Equal(t, db2.contents[0].Command, "")
42+
require.Equal(t, db2.contents[0].Arguments, []string{"gcc", "arg1", "arg2"})
4343
cwd, err := paths.Getwd()
4444
require.NoError(t, err)
45-
require.Equal(t, db2.Contents[0].Directory, cwd.String())
45+
require.Equal(t, db2.contents[0].Directory, cwd.String())
4646
}

0 commit comments

Comments
 (0)