Commit 01de174c authored by Cristian Maglie's avatar Cristian Maglie

Fixed an extremely rare race-condition during compile (#2512)

parent 5edfa984
...@@ -19,6 +19,7 @@ import ( ...@@ -19,6 +19,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os" "os"
"sync"
"github.com/arduino/arduino-cli/executils" "github.com/arduino/arduino-cli/executils"
"github.com/arduino/arduino-cli/i18n" "github.com/arduino/arduino-cli/i18n"
...@@ -29,8 +30,9 @@ var tr = i18n.Tr ...@@ -29,8 +30,9 @@ var tr = i18n.Tr
// Database keeps track of all the compile commands run by the builder // Database keeps track of all the compile commands run by the builder
type Database struct { type Database struct {
Contents []Command lock sync.Mutex
File *paths.Path contents []Command
file *paths.Path
} }
// Command keeps track of a single run of a compile command // Command keeps track of a single run of a compile command
...@@ -44,8 +46,8 @@ type Command struct { ...@@ -44,8 +46,8 @@ type Command struct {
// NewDatabase creates an empty CompilationDatabase // NewDatabase creates an empty CompilationDatabase
func NewDatabase(filename *paths.Path) *Database { func NewDatabase(filename *paths.Path) *Database {
return &Database{ return &Database{
File: filename, file: filename,
Contents: []Command{}, contents: []Command{},
} }
} }
...@@ -56,16 +58,18 @@ func LoadDatabase(file *paths.Path) (*Database, error) { ...@@ -56,16 +58,18 @@ func LoadDatabase(file *paths.Path) (*Database, error) {
return nil, err return nil, err
} }
res := NewDatabase(file) res := NewDatabase(file)
return res, json.Unmarshal(f, &res.Contents) return res, json.Unmarshal(f, &res.contents)
} }
// SaveToFile save the CompilationDatabase to file as a clangd-compatible compile_commands.json, // SaveToFile save the CompilationDatabase to file as a clangd-compatible compile_commands.json,
// see https://clang.llvm.org/docs/JSONCompilationDatabase.html // see https://clang.llvm.org/docs/JSONCompilationDatabase.html
func (db *Database) SaveToFile() { func (db *Database) SaveToFile() {
if jsonContents, err := json.MarshalIndent(db.Contents, "", " "); err != nil { db.lock.Lock()
defer db.lock.Unlock()
if jsonContents, err := json.MarshalIndent(db.contents, "", " "); err != nil {
fmt.Println(tr("Error serializing compilation database: %s", err)) fmt.Println(tr("Error serializing compilation database: %s", err))
return return
} else if err := db.File.WriteFile(jsonContents); err != nil { } else if err := db.file.WriteFile(jsonContents); err != nil {
fmt.Println(tr("Error writing compilation database: %s", err)) fmt.Println(tr("Error writing compilation database: %s", err))
} }
} }
...@@ -89,5 +93,7 @@ func (db *Database) Add(target *paths.Path, command *executils.Process) { ...@@ -89,5 +93,7 @@ func (db *Database) Add(target *paths.Path, command *executils.Process) {
File: target.String(), File: target.String(),
} }
db.Contents = append(db.Contents, entry) db.lock.Lock()
db.contents = append(db.contents, entry)
db.lock.Unlock()
} }
...@@ -37,11 +37,11 @@ func TestCompilationDatabase(t *testing.T) { ...@@ -37,11 +37,11 @@ func TestCompilationDatabase(t *testing.T) {
db2, err := LoadDatabase(tmpfile) db2, err := LoadDatabase(tmpfile)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, db, db2) require.Equal(t, db, db2)
require.Len(t, db2.Contents, 1) require.Len(t, db2.contents, 1)
require.Equal(t, db2.Contents[0].File, "test") require.Equal(t, db2.contents[0].File, "test")
require.Equal(t, db2.Contents[0].Command, "") require.Equal(t, db2.contents[0].Command, "")
require.Equal(t, db2.Contents[0].Arguments, []string{"gcc", "arg1", "arg2"}) require.Equal(t, db2.contents[0].Arguments, []string{"gcc", "arg1", "arg2"})
cwd, err := paths.Getwd() cwd, err := paths.Getwd()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, db2.Contents[0].Directory, cwd.String()) require.Equal(t, db2.contents[0].Directory, cwd.String())
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment