Skip to content

Commit 1598ee1

Browse files
committed
Merge remote-tracking branch 'arduino/main' into remove-global-clients
Imported #1032
2 parents 9cbe49e + e7ea376 commit 1598ee1

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

hub.go

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"runtime/debug"
2626
"strconv"
2727
"strings"
28+
"sync"
2829

2930
"github.com/arduino/arduino-create-agent/systray"
3031
"github.com/arduino/arduino-create-agent/tools"
@@ -56,6 +57,10 @@ type hub struct {
5657
tools *tools.Tools
5758

5859
systray *systray.Systray
60+
61+
// This lock is used to prevent multiple threads from trying to open the same port at the same time.
62+
// It presents issues with the serial port driver on some OS's: https://github.com/arduino/arduino-create-agent/issues/1031
63+
spHandlerOpenLock sync.Mutex
5964
}
6065

6166
func newHub(tools *tools.Tools, systray *systray.Systray) *hub {

serial.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import (
3131

3232
type serialhub struct {
3333
// Opened serial ports.
34-
ports map[*serport]bool
34+
ports map[string]*serport
3535

3636
mu sync.Mutex
3737

@@ -41,7 +41,7 @@ type serialhub struct {
4141

4242
func newSerialHub(onRegister func(port *serport), onUnregister func(port *serport)) *serialhub {
4343
return &serialhub{
44-
ports: make(map[*serport]bool),
44+
ports: make(map[string]*serport),
4545
onRegister: onRegister,
4646
onUnregister: onUnregister,
4747
}
@@ -75,15 +75,15 @@ type SpPortItem struct {
7575
func (sh *serialhub) Register(port *serport) {
7676
sh.mu.Lock()
7777
sh.onRegister(port)
78-
sh.ports[port] = true
78+
sh.ports[port.portName] = port
7979
sh.mu.Unlock()
8080
}
8181

8282
// Unregister requests from connections.
8383
func (sh *serialhub) Unregister(port *serport) {
8484
sh.mu.Lock()
8585
sh.onUnregister(port)
86-
delete(sh.ports, port)
86+
delete(sh.ports, port.portName)
8787
close(port.sendBuffered)
8888
close(port.sendNoBuf)
8989
sh.mu.Unlock()
@@ -93,8 +93,8 @@ func (sh *serialhub) FindPortByName(portname string) (*serport, bool) {
9393
sh.mu.Lock()
9494
defer sh.mu.Unlock()
9595

96-
for port := range sh.ports {
97-
if strings.EqualFold(port.portConf.Name, portname) {
96+
for name, port := range sh.ports {
97+
if strings.EqualFold(name, portname) {
9898
// we found our port
9999
return port, true
100100
}

serialport.go

+16-10
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ func (p *serport) writerRaw() {
284284

285285
// FIXME: move this into the `hub.go` file
286286
func (h *hub) spHandlerOpen(portname string, baud int, buftype string) {
287+
h.spHandlerOpenLock.Lock()
288+
defer h.spHandlerOpenLock.Unlock()
287289

288290
log.Print("Inside spHandler")
289291

@@ -305,11 +307,14 @@ func (h *hub) spHandlerOpen(portname string, baud int, buftype string) {
305307
sp, err := serial.Open(portname, mode)
306308
log.Print("Just tried to open port")
307309
if err != nil {
308-
//log.Fatal(err)
309-
log.Print("Error opening port " + err.Error())
310-
//h.broadcastSys <- []byte("Error opening port. " + err.Error())
311-
h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Error opening port. " + err.Error() + "\",\"Port\":\"" + conf.Name + "\",\"Baud\":" + strconv.Itoa(conf.Baud) + "}")
312-
310+
existingPort, ok := h.serialHub.FindPortByName(portname)
311+
if ok && existingPort.portConf.Baud == baud && existingPort.BufferType == buftype {
312+
log.Print("Port already opened")
313+
h.broadcastSys <- []byte("{\"Cmd\":\"Open\",\"Desc\":\"Port already opened.\",\"Port\":\"" + existingPort.portConf.Name + "\",\"Baud\":" + strconv.Itoa(existingPort.portConf.Baud) + ",\"BufferType\":\"" + existingPort.BufferType + "\"}")
314+
} else {
315+
log.Print("Error opening port " + err.Error())
316+
h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Error opening port. " + err.Error() + "\",\"Port\":\"" + conf.Name + "\",\"Baud\":" + strconv.Itoa(conf.Baud) + "}")
317+
}
313318
return
314319
}
315320
log.Print("Opened port successfully")
@@ -348,7 +353,6 @@ func (h *hub) spHandlerOpen(portname string, baud int, buftype string) {
348353
p.bufferwatcher = bw
349354

350355
h.serialHub.Register(p)
351-
defer h.serialHub.Unregister(p)
352356

353357
h.serialPortList.MarkPortAsOpened(portname)
354358
h.serialPortList.List()
@@ -359,10 +363,12 @@ func (h *hub) spHandlerOpen(portname string, baud int, buftype string) {
359363
go p.writerNoBuf()
360364
// this is thread to send to serial port but with base64 decoding
361365
go p.writerRaw()
362-
363-
p.reader(buftype)
364-
365-
h.serialPortList.List()
366+
// this is the thread that reads from the serial port
367+
go func() {
368+
p.reader(buftype)
369+
h.serialPortList.List()
370+
h.serialHub.Unregister(p)
371+
}()
366372
}
367373

368374
func (p *serport) Close() {

0 commit comments

Comments
 (0)