Skip to content

Commit 4db186e

Browse files
committed
Created a coreInstancesContainer
This container will handle all the atomic access to the instances map.
1 parent 3b39d7c commit 4db186e

File tree

1 file changed

+48
-26
lines changed

1 file changed

+48
-26
lines changed

commands/instances.go

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,6 @@ import (
4646

4747
var tr = i18n.Tr
4848

49-
// this map contains all the running Arduino Core Services instances
50-
// referenced by an int32 handle
51-
var instances = map[int32]*CoreInstance{}
52-
var instancesCount int32 = 1
53-
var instancesMux sync.Mutex
54-
5549
// CoreInstance is an instance of the Arduino Core Services. The user can
5650
// instantiate as many as needed by providing a different configuration
5751
// for each one.
@@ -60,18 +54,55 @@ type CoreInstance struct {
6054
lm *librariesmanager.LibrariesManager
6155
}
6256

57+
// coreInstancesContainer has methods to add an remove instances atomically.
58+
type coreInstancesContainer struct {
59+
instances map[int32]*CoreInstance
60+
instancesCount int32
61+
instancesMux sync.Mutex
62+
}
63+
64+
// instances contains all the running Arduino Core Services instances
65+
var instances = &coreInstancesContainer{
66+
instances: map[int32]*CoreInstance{},
67+
instancesCount: 1,
68+
}
69+
6370
// GetInstance returns a CoreInstance for the given ID, or nil if ID
6471
// doesn't exist
65-
func GetInstance(id int32) *CoreInstance {
66-
instancesMux.Lock()
67-
defer instancesMux.Unlock()
68-
return instances[id]
72+
func (c *coreInstancesContainer) GetInstance(id int32) *CoreInstance {
73+
c.instancesMux.Lock()
74+
defer c.instancesMux.Unlock()
75+
return c.instances[id]
76+
}
77+
78+
// AddAndAssignID saves the CoreInstance and assign an unique ID to
79+
// retrieve it later
80+
func (c *coreInstancesContainer) AddAndAssignID(i *CoreInstance) int32 {
81+
c.instancesMux.Lock()
82+
defer c.instancesMux.Unlock()
83+
id := c.instancesCount
84+
c.instances[id] = i
85+
c.instancesCount++
86+
return id
87+
}
88+
89+
// RemoveID removed the CoreInstance referenced by id. Returns true
90+
// if the operation is successful, or false if the CoreInstance does
91+
// not exists
92+
func (c *coreInstancesContainer) RemoveID(id int32) bool {
93+
c.instancesMux.Lock()
94+
defer c.instancesMux.Unlock()
95+
if _, ok := c.instances[id]; !ok {
96+
return false
97+
}
98+
delete(c.instances, id)
99+
return true
69100
}
70101

71102
// GetPackageManager returns a PackageManager for the given ID, or nil if
72103
// ID doesn't exist
73104
func GetPackageManager(id int32) *packagemanager.PackageManager {
74-
i := GetInstance(id)
105+
i := instances.GetInstance(id)
75106
if i == nil {
76107
return nil
77108
}
@@ -82,7 +113,7 @@ func GetPackageManager(id int32) *packagemanager.PackageManager {
82113
// explorer holds a read lock on the underlying PackageManager and it should
83114
// be released by calling the returned "release" function.
84115
func GetPackageManagerExplorer(instance rpc.InstanceCommand) (explorer *packagemanager.Explorer, release func()) {
85-
i := GetInstance(instance.GetInstance().GetId())
116+
i := instances.GetInstance(instance.GetInstance().GetId())
86117
if i == nil {
87118
return nil, nil
88119
}
@@ -91,7 +122,7 @@ func GetPackageManagerExplorer(instance rpc.InstanceCommand) (explorer *packagem
91122

92123
// GetLibraryManager returns the library manager for the given instance ID
93124
func GetLibraryManager(id int32) *librariesmanager.LibrariesManager {
94-
i := GetInstance(id)
125+
i := instances.GetInstance(id)
95126
if i == nil {
96127
return nil
97128
}
@@ -154,11 +185,7 @@ func Create(req *rpc.CreateRequest, extraUserAgent ...string) (*rpc.CreateRespon
154185
)
155186

156187
// Save instance
157-
instancesMux.Lock()
158-
instanceID := instancesCount
159-
instances[instanceID] = instance
160-
instancesCount++
161-
instancesMux.Unlock()
188+
instanceID := instances.AddAndAssignID(instance)
162189

163190
return &rpc.CreateResponse{
164191
Instance: &rpc.Instance{Id: instanceID},
@@ -178,7 +205,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro
178205
if reqInst == nil {
179206
return &arduino.InvalidInstanceError{}
180207
}
181-
instance := GetInstance(reqInst.GetId())
208+
instance := instances.GetInstance(reqInst.GetId())
182209
if instance == nil {
183210
return &arduino.InvalidInstanceError{}
184211
}
@@ -430,14 +457,9 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro
430457

431458
// Destroy FIXMEDOC
432459
func Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) {
433-
id := req.GetInstance().GetId()
434-
435-
instancesMux.Lock()
436-
defer instancesMux.Unlock()
437-
if _, ok := instances[id]; !ok {
460+
if ok := instances.RemoveID(req.GetInstance().GetId()); !ok {
438461
return nil, &arduino.InvalidInstanceError{}
439462
}
440-
delete(instances, id)
441463
return &rpc.DestroyResponse{}, nil
442464
}
443465

@@ -473,7 +495,7 @@ func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequ
473495

474496
// UpdateIndex FIXMEDOC
475497
func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB rpc.DownloadProgressCB) (*rpc.UpdateIndexResponse, error) {
476-
if GetInstance(req.GetInstance().GetId()) == nil {
498+
if instances.GetInstance(req.GetInstance().GetId()) == nil {
477499
return nil, &arduino.InvalidInstanceError{}
478500
}
479501

0 commit comments

Comments
 (0)