diff --git a/serial.go b/serial.go index 0bfd77873..743cbfa1f 100755 --- a/serial.go +++ b/serial.go @@ -6,6 +6,7 @@ import ( "encoding/json" "strconv" "strings" + "sync" "time" "github.com/arduino/arduino-create-agent/upload" @@ -29,11 +30,14 @@ type serialhub struct { // Unregister requests from connections. unregister chan *serport + + mu sync.Mutex } type SpPortList struct { Ports []SpPortItem Network bool + mu sync.Mutex `json:"-"` } type SpPortItem struct { @@ -72,15 +76,19 @@ func (sh *serialhub) run() { for { select { case p := <-sh.register: + sh.mu.Lock() //log.Print("Registering a port: ", p.portConf.Name) h.broadcastSys <- []byte("{\"Cmd\":\"Open\",\"Desc\":\"Got register/open on port.\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + ",\"BufferType\":\"" + p.BufferType + "\"}") sh.ports[p] = true + sh.mu.Unlock() case p := <-sh.unregister: + sh.mu.Lock() //log.Print("Unregistering a port: ", p.portConf.Name) h.broadcastSys <- []byte("{\"Cmd\":\"Close\",\"Desc\":\"Got unregister/close on port.\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + "}") delete(sh.ports, p) close(p.sendBuffered) close(p.sendNoBuf) + sh.mu.Unlock() case wr := <-sh.write: // if user sent in the commands as one text mode line write(wr) @@ -102,13 +110,17 @@ func write(wr writeRequest) { // spList broadcasts a Json representation of the ports found func spList(network bool) { - var list SpPortList + var ls []byte + var err error if network { - list = NetworkPorts + NetworkPorts.mu.Lock() + ls, err = json.MarshalIndent(NetworkPorts, "", "\t") + NetworkPorts.mu.Unlock() } else { - list = SerialPorts + SerialPorts.mu.Lock() + ls, err = json.MarshalIndent(SerialPorts, "", "\t") + SerialPorts.mu.Unlock() } - ls, err := json.MarshalIndent(list, "", "\t") if err != nil { //log.Println(err) h.broadcastSys <- []byte("Error creating json on port list " + @@ -120,10 +132,14 @@ func spList(network bool) { // discoverLoop periodically update the list of ports found func discoverLoop() { + SerialPorts.mu.Lock() SerialPorts.Network = false SerialPorts.Ports = make([]SpPortItem, 0) + SerialPorts.mu.Unlock() + NetworkPorts.mu.Lock() NetworkPorts.Network = true NetworkPorts.Ports = make([]SpPortItem, 0) + NetworkPorts.mu.Unlock() go func() { for { @@ -184,13 +200,13 @@ func spListDual(network bool) { // to append the open/close state, baud rates, etc to make // a super clean nice list to send back to browser n := len(list) - spl := SpPortList{make([]SpPortItem, n, n), network} + spl := make([]SpPortItem, n) ctr := 0 for _, item := range list { - spl.Ports[ctr] = SpPortItem{ + spl[ctr] = SpPortItem{ Name: item.Name, SerialNumber: item.ISerial, DeviceClass: item.DeviceClass, @@ -209,17 +225,21 @@ func spListDual(network bool) { if isFound { // we found our port - spl.Ports[ctr].IsOpen = true - spl.Ports[ctr].Baud = myport.portConf.Baud - spl.Ports[ctr].BufferAlgorithm = myport.BufferType + spl[ctr].IsOpen = true + spl[ctr].Baud = myport.portConf.Baud + spl[ctr].BufferAlgorithm = myport.BufferType } ctr++ } if network { - NetworkPorts = spl + NetworkPorts.mu.Lock() + NetworkPorts.Ports = spl + NetworkPorts.mu.Unlock() } else { - SerialPorts = spl + SerialPorts.mu.Lock() + SerialPorts.Ports = spl + SerialPorts.mu.Unlock() } } diff --git a/seriallist.go b/seriallist.go index 4e26f4dee..fc02295dc 100755 --- a/seriallist.go +++ b/seriallist.go @@ -71,6 +71,8 @@ func GetList(network bool) ([]OsSerialPort, error) { func findPortByName(portname string) (*serport, bool) { portnamel := strings.ToLower(portname) + sh.mu.Lock() + defer sh.mu.Unlock() for port := range sh.ports { if strings.ToLower(port.portConf.Name) == portnamel { // we found our port @@ -80,14 +82,3 @@ func findPortByName(portname string) (*serport, bool) { } return nil, false } - -func findPortByNameRerun(portname string, network bool) (OsSerialPort, bool) { - portnamel := strings.ToLower(portname) - list, _ := GetList(network) - for _, item := range list { - if strings.ToLower(item.Name) == portnamel { - return item, true - } - } - return OsSerialPort{}, false -}