Skip to content

Commit

Permalink
[EDITOR-512] Fix concurrent map read and map write (#585)
Browse files Browse the repository at this point in the history
* update doc

* add read write mutex synchronization to installed map
  • Loading branch information
umbynos committed Jan 29, 2021
1 parent ee6b074 commit 88e424a
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
4 changes: 3 additions & 1 deletion docs/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
```go
type Tools struct {
Directory string
IndexURL string
IndexURL string
LastRefresh time.Time
Logger log.StdLogger
}
```
Expand All @@ -20,6 +21,7 @@ to download a tool from the arduino servers.

- *Directory* contains the location where the tools are downloaded.
- *IndexURL* contains the url where the tools description is contained.
- *LastRefresh* contains the last update time
- *Logger* is a StdLogger used for reporting debug and info messages
- *installed* contains a map of the tools and their exact location

Expand Down
6 changes: 6 additions & 0 deletions tools/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,14 @@ func (t *Tools) Download(pack, name, version, behaviour string) error {

// Check if it already exists
if behaviour == "keep" {
t.mutex.RLock()
location, ok := t.installed[key]
t.mutex.RUnlock()
if ok && pathExists(location) {
// overwrite the default tool with this one
t.mutex.Lock()
t.installed[correctTool.Name] = location
t.mutex.Unlock()
t.Logger("The tool is already present on the system")
return t.writeMap()
}
Expand Down Expand Up @@ -267,8 +271,10 @@ func (t *Tools) Download(pack, name, version, behaviour string) error {
// Update the tool map
t.Logger("Updating map with location " + location)

t.mutex.Lock()
t.installed[name] = location
t.installed[name+"-"+correctTool.Version] = location
t.mutex.Unlock()
return t.writeMap()
}

Expand Down
21 changes: 20 additions & 1 deletion tools/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"path"
"path/filepath"
"strings"
"sync"
"time"

"github.com/xrash/smetrics"
Expand All @@ -35,21 +36,30 @@ type Tools struct {
LastRefresh time.Time
Logger func(msg string)
installed map[string]string
mutex sync.RWMutex
}

// Init creates the Installed map and populates it from a file in .arduino-create
func (t *Tools) Init(APIlevel string) {
createDir(t.Directory)
t.mutex.Lock()
t.installed = make(map[string]string)
t.mutex.Unlock()
t.readMap()
t.mutex.RLock()
if t.installed["apilevel"] != APIlevel {
t.mutex.RUnlock()
// wipe the folder and reinitialize the data
os.RemoveAll(t.Directory)
createDir(t.Directory)
t.mutex.Lock()
t.installed = make(map[string]string)
t.installed["apilevel"] = APIlevel
t.mutex.Unlock()
t.writeMap()
t.readMap()
} else {
t.mutex.RUnlock()
}
}

Expand All @@ -62,13 +72,17 @@ func (t *Tools) GetLocation(command string) (string, error) {
var ok bool

// Load installed
t.mutex.RLock()
fmt.Println(t.installed)
t.mutex.RUnlock()

err := t.readMap()
if err != nil {
return "", err
}

t.mutex.RLock()
defer t.mutex.RUnlock()
fmt.Println(t.installed)

// use string similarity to resolve a runtime var with a "similar" map element
Expand All @@ -82,25 +96,30 @@ func (t *Tools) GetLocation(command string) (string, error) {
}
}
}

return filepath.ToSlash(location), nil
}

// writeMap() writes installed map to the json file "installed.json"
func (t *Tools) writeMap() error {
t.mutex.RLock()
b, err := json.Marshal(t.installed)
t.mutex.RUnlock()
if err != nil {
return err
}
filePath := path.Join(dir(), "installed.json")
return ioutil.WriteFile(filePath, b, 0644)
}

// readMap() reads the installed map from json file "installed.json"
func (t *Tools) readMap() error {
filePath := path.Join(dir(), "installed.json")
b, err := ioutil.ReadFile(filePath)
if err != nil {
return err
}
t.mutex.Lock()
defer t.mutex.Unlock()
return json.Unmarshal(b, &t.installed)
}

Expand Down

0 comments on commit 88e424a

Please sign in to comment.