@@ -22,12 +22,14 @@ import (
2222 "github.com/arduino/arduino-cli/arduino/discovery"
2323 "github.com/arduino/arduino-cli/i18n"
2424 "github.com/pkg/errors"
25+ "github.com/sirupsen/logrus"
2526)
2627
2728// DiscoveryManager is required to handle multiple pluggable-discovery that
2829// may be shared across platforms
2930type DiscoveryManager struct {
30- discoveries map [string ]* discovery.PluggableDiscovery
31+ discoveriesMutex sync.Mutex
32+ discoveries map [string ]* discovery.PluggableDiscovery
3133}
3234
3335var tr = i18n .Tr
@@ -42,12 +44,16 @@ func New() *DiscoveryManager {
4244// Clear resets the DiscoveryManager to its initial state
4345func (dm * DiscoveryManager ) Clear () {
4446 dm .QuitAll ()
47+ dm .discoveriesMutex .Lock ()
48+ defer dm .discoveriesMutex .Unlock ()
4549 dm .discoveries = map [string ]* discovery.PluggableDiscovery {}
4650}
4751
4852// IDs returns the list of discoveries' ids in this DiscoveryManager
4953func (dm * DiscoveryManager ) IDs () []string {
5054 ids := []string {}
55+ dm .discoveriesMutex .Lock ()
56+ defer dm .discoveriesMutex .Unlock ()
5157 for id := range dm .discoveries {
5258 ids = append (ids , id )
5359 }
@@ -57,19 +63,38 @@ func (dm *DiscoveryManager) IDs() []string {
5763// Add adds a discovery to the list of managed discoveries
5864func (dm * DiscoveryManager ) Add (disc * discovery.PluggableDiscovery ) error {
5965 id := disc .GetID ()
66+ dm .discoveriesMutex .Lock ()
67+ defer dm .discoveriesMutex .Unlock ()
6068 if _ , has := dm .discoveries [id ]; has {
6169 return errors .Errorf (tr ("pluggable discovery already added: %s" ), id )
6270 }
6371 dm .discoveries [id ] = disc
6472 return nil
6573}
6674
75+ // remove quits and deletes the discovery with specified id
76+ // from the discoveries managed by this DiscoveryManager
77+ func (dm * DiscoveryManager ) remove (id string ) {
78+ dm .discoveriesMutex .Lock ()
79+ d := dm .discoveries [id ]
80+ delete (dm .discoveries , id )
81+ dm .discoveriesMutex .Unlock ()
82+ d .Quit ()
83+ logrus .Infof ("Closed and removed discovery %s" , id )
84+ }
85+
6786// parallelize runs function f concurrently for each discovery.
6887// Returns a list of errors returned by each call of f.
6988func (dm * DiscoveryManager ) parallelize (f func (d * discovery.PluggableDiscovery ) error ) []error {
7089 var wg sync.WaitGroup
7190 errChan := make (chan error )
91+ dm .discoveriesMutex .Lock ()
92+ discoveries := []* discovery.PluggableDiscovery {}
7293 for _ , d := range dm .discoveries {
94+ discoveries = append (discoveries , d )
95+ }
96+ dm .discoveriesMutex .Unlock ()
97+ for _ , d := range discoveries {
7398 wg .Add (1 )
7499 go func (d * discovery.PluggableDiscovery ) {
75100 defer wg .Done ()
@@ -103,6 +128,7 @@ func (dm *DiscoveryManager) RunAll() []error {
103128 }
104129
105130 if err := d .Run (); err != nil {
131+ dm .remove (d .GetID ())
106132 return fmt .Errorf (tr ("discovery %[1]s process not started: %[2]w" ), d .GetID (), err )
107133 }
108134 return nil
@@ -119,6 +145,7 @@ func (dm *DiscoveryManager) StartAll() []error {
119145 return nil
120146 }
121147 if err := d .Start (); err != nil {
148+ dm .remove (d .GetID ())
122149 return fmt .Errorf (tr ("starting discovery %[1]s: %[2]w" ), d .GetID (), err )
123150 }
124151 return nil
@@ -139,6 +166,7 @@ func (dm *DiscoveryManager) StartSyncAll() (<-chan *discovery.Event, []error) {
139166
140167 eventCh , err := d .StartSync (5 )
141168 if err != nil {
169+ dm .remove (d .GetID ())
142170 return fmt .Errorf (tr ("start syncing discovery %[1]s: %[2]w" ), d .GetID (), err )
143171 }
144172
@@ -170,6 +198,7 @@ func (dm *DiscoveryManager) StopAll() []error {
170198 }
171199
172200 if err := d .Stop (); err != nil {
201+ dm .remove (d .GetID ())
173202 return fmt .Errorf (tr ("stopping discovery %[1]s: %[2]w" ), d .GetID (), err )
174203 }
175204 return nil
@@ -185,9 +214,7 @@ func (dm *DiscoveryManager) QuitAll() []error {
185214 return nil
186215 }
187216
188- if err := d .Quit (); err != nil {
189- return fmt .Errorf (tr ("quitting discovery %[1]s: %[2]w" ), d .GetID (), err )
190- }
217+ d .Quit ()
191218 return nil
192219 })
193220 return errs
@@ -204,7 +231,13 @@ func (dm *DiscoveryManager) List() ([]*discovery.Port, []error) {
204231 Port * discovery.Port
205232 }
206233 msgChan := make (chan listMsg )
234+ dm .discoveriesMutex .Lock ()
235+ discoveries := []* discovery.PluggableDiscovery {}
207236 for _ , d := range dm .discoveries {
237+ discoveries = append (discoveries , d )
238+ }
239+ dm .discoveriesMutex .Unlock ()
240+ for _ , d := range discoveries {
208241 wg .Add (1 )
209242 go func (d * discovery.PluggableDiscovery ) {
210243 defer wg .Done ()
@@ -243,7 +276,13 @@ func (dm *DiscoveryManager) List() ([]*discovery.Port, []error) {
243276// ListCachedPorts return the current list of ports detected from all discoveries
244277func (dm * DiscoveryManager ) ListCachedPorts () []* discovery.Port {
245278 res := []* discovery.Port {}
279+ dm .discoveriesMutex .Lock ()
280+ discoveries := []* discovery.PluggableDiscovery {}
246281 for _ , d := range dm .discoveries {
282+ discoveries = append (discoveries , d )
283+ }
284+ dm .discoveriesMutex .Unlock ()
285+ for _ , d := range discoveries {
247286 if d .State () != discovery .Syncing {
248287 // Discovery is not syncing
249288 continue
0 commit comments