From 6481b583bbd1885789272c9d12cd1f6b18c687b5 Mon Sep 17 00:00:00 2001 From: umbynos <umberto.baldi@edu.unito.it> Date: Thu, 14 Jan 2021 18:47:24 +0100 Subject: [PATCH 1/2] update doc --- docs/tools.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/tools.md b/docs/tools.md index 35be570c9..93ac8e3f8 100644 --- a/docs/tools.md +++ b/docs/tools.md @@ -10,7 +10,8 @@ ```go type Tools struct { Directory string - IndexURL string + IndexURL string + LastRefresh time.Time Logger log.StdLogger } ``` @@ -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 From 0cb27d8e7a201db4f9fc27bce08a5d6271121fb6 Mon Sep 17 00:00:00 2001 From: umbynos <umberto.baldi@edu.unito.it> Date: Thu, 14 Jan 2021 18:48:31 +0100 Subject: [PATCH 2/2] add read write mutex synchronization to installed map --- tools/download.go | 6 ++++++ tools/tools.go | 21 ++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tools/download.go b/tools/download.go index c5fa4f31f..6c9ced87b 100644 --- a/tools/download.go +++ b/tools/download.go @@ -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() } @@ -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() } diff --git a/tools/tools.go b/tools/tools.go index 2884325da..88ef425ea 100644 --- a/tools/tools.go +++ b/tools/tools.go @@ -9,6 +9,7 @@ import ( "path" "path/filepath" "strings" + "sync" "time" "github.com/xrash/smetrics" @@ -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() } } @@ -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 @@ -82,12 +96,14 @@ 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 } @@ -95,12 +111,15 @@ func (t *Tools) writeMap() error { 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) }