66 "encoding/json"
77 "strconv"
88 "strings"
9+ "sync"
910 "time"
1011
1112 "github.com/arduino/arduino-create-agent/upload"
@@ -29,11 +30,14 @@ type serialhub struct {
2930
3031 // Unregister requests from connections.
3132 unregister chan * serport
33+
34+ mu sync.Mutex
3235}
3336
3437type SpPortList struct {
3538 Ports []SpPortItem
3639 Network bool
40+ mu sync.Mutex `json:"-"`
3741}
3842
3943type SpPortItem struct {
@@ -72,15 +76,19 @@ func (sh *serialhub) run() {
7276 for {
7377 select {
7478 case p := <- sh .register :
79+ sh .mu .Lock ()
7580 //log.Print("Registering a port: ", p.portConf.Name)
7681 h .broadcastSys <- []byte ("{\" Cmd\" :\" Open\" ,\" Desc\" :\" Got register/open on port.\" ,\" Port\" :\" " + p .portConf .Name + "\" ,\" Baud\" :" + strconv .Itoa (p .portConf .Baud ) + ",\" BufferType\" :\" " + p .BufferType + "\" }" )
7782 sh .ports [p ] = true
83+ sh .mu .Unlock ()
7884 case p := <- sh .unregister :
85+ sh .mu .Lock ()
7986 //log.Print("Unregistering a port: ", p.portConf.Name)
8087 h .broadcastSys <- []byte ("{\" Cmd\" :\" Close\" ,\" Desc\" :\" Got unregister/close on port.\" ,\" Port\" :\" " + p .portConf .Name + "\" ,\" Baud\" :" + strconv .Itoa (p .portConf .Baud ) + "}" )
8188 delete (sh .ports , p )
8289 close (p .sendBuffered )
8390 close (p .sendNoBuf )
91+ sh .mu .Unlock ()
8492 case wr := <- sh .write :
8593 // if user sent in the commands as one text mode line
8694 write (wr )
@@ -102,13 +110,17 @@ func write(wr writeRequest) {
102110
103111// spList broadcasts a Json representation of the ports found
104112func spList (network bool ) {
105- var list SpPortList
113+ var ls []byte
114+ var err error
106115 if network {
107- list = NetworkPorts
116+ NetworkPorts .mu .Lock ()
117+ ls , err = json .MarshalIndent (NetworkPorts , "" , "\t " )
118+ NetworkPorts .mu .Unlock ()
108119 } else {
109- list = SerialPorts
120+ SerialPorts .mu .Lock ()
121+ ls , err = json .MarshalIndent (SerialPorts , "" , "\t " )
122+ SerialPorts .mu .Unlock ()
110123 }
111- ls , err := json .MarshalIndent (list , "" , "\t " )
112124 if err != nil {
113125 //log.Println(err)
114126 h .broadcastSys <- []byte ("Error creating json on port list " +
@@ -120,10 +132,14 @@ func spList(network bool) {
120132
121133// discoverLoop periodically update the list of ports found
122134func discoverLoop () {
135+ SerialPorts .mu .Lock ()
123136 SerialPorts .Network = false
124137 SerialPorts .Ports = make ([]SpPortItem , 0 )
138+ SerialPorts .mu .Unlock ()
139+ NetworkPorts .mu .Lock ()
125140 NetworkPorts .Network = true
126141 NetworkPorts .Ports = make ([]SpPortItem , 0 )
142+ NetworkPorts .mu .Unlock ()
127143
128144 go func () {
129145 for {
@@ -184,13 +200,13 @@ func spListDual(network bool) {
184200 // to append the open/close state, baud rates, etc to make
185201 // a super clean nice list to send back to browser
186202 n := len (list )
187- spl := SpPortList { make ([]SpPortItem , n , n ), network }
203+ spl := make ([]SpPortItem , n )
188204
189205 ctr := 0
190206
191207 for _ , item := range list {
192208
193- spl . Ports [ctr ] = SpPortItem {
209+ spl [ctr ] = SpPortItem {
194210 Name : item .Name ,
195211 SerialNumber : item .ISerial ,
196212 DeviceClass : item .DeviceClass ,
@@ -209,17 +225,21 @@ func spListDual(network bool) {
209225
210226 if isFound {
211227 // we found our port
212- spl . Ports [ctr ].IsOpen = true
213- spl . Ports [ctr ].Baud = myport .portConf .Baud
214- spl . Ports [ctr ].BufferAlgorithm = myport .BufferType
228+ spl [ctr ].IsOpen = true
229+ spl [ctr ].Baud = myport .portConf .Baud
230+ spl [ctr ].BufferAlgorithm = myport .BufferType
215231 }
216232 ctr ++
217233 }
218234
219235 if network {
220- NetworkPorts = spl
236+ NetworkPorts .mu .Lock ()
237+ NetworkPorts .Ports = spl
238+ NetworkPorts .mu .Unlock ()
221239 } else {
222- SerialPorts = spl
240+ SerialPorts .mu .Lock ()
241+ SerialPorts .Ports = spl
242+ SerialPorts .mu .Unlock ()
223243 }
224244}
225245
0 commit comments