@@ -20,6 +20,7 @@ import (
2020 "encoding/base64"
2121 "io"
2222 "strconv"
23+ "sync"
2324 "sync/atomic"
2425 "time"
2526 "unicode/utf8"
@@ -273,7 +274,13 @@ func (p *serport) writerRaw() {
273274 h .broadcastSys <- []byte (msgstr )
274275}
275276
277+ // This lock is used to prevent multiple threads from trying to open the same port at the same time.
278+ // It presents issues with the serial port driver on some OS's: https://github.com/arduino/arduino-create-agent/issues/1031
279+ var spHandlerOpenLock sync.Mutex
280+
276281func spHandlerOpen (portname string , baud int , buftype string ) {
282+ spHandlerOpenLock .Lock ()
283+ defer spHandlerOpenLock .Unlock ()
277284
278285 log .Print ("Inside spHandler" )
279286
@@ -295,11 +302,14 @@ func spHandlerOpen(portname string, baud int, buftype string) {
295302 sp , err := serial .Open (portname , mode )
296303 log .Print ("Just tried to open port" )
297304 if err != nil {
298- //log.Fatal(err)
299- log .Print ("Error opening port " + err .Error ())
300- //h.broadcastSys <- []byte("Error opening port. " + err.Error())
301- h .broadcastSys <- []byte ("{\" Cmd\" :\" OpenFail\" ,\" Desc\" :\" Error opening port. " + err .Error () + "\" ,\" Port\" :\" " + conf .Name + "\" ,\" Baud\" :" + strconv .Itoa (conf .Baud ) + "}" )
302-
305+ existingPort , ok := sh .FindPortByName (portname )
306+ if ok && existingPort .portConf .Baud == baud && existingPort .BufferType == buftype {
307+ log .Print ("Port already opened" )
308+ h .broadcastSys <- []byte ("{\" Cmd\" :\" Open\" ,\" Desc\" :\" Port already opened.\" ,\" Port\" :\" " + existingPort .portConf .Name + "\" ,\" Baud\" :" + strconv .Itoa (existingPort .portConf .Baud ) + ",\" BufferType\" :\" " + existingPort .BufferType + "\" }" )
309+ } else {
310+ log .Print ("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+ }
303313 return
304314 }
305315 log .Print ("Opened port successfully" )
@@ -331,7 +341,6 @@ func spHandlerOpen(portname string, baud int, buftype string) {
331341 p .bufferwatcher = bw
332342
333343 sh .Register (p )
334- defer sh .Unregister (p )
335344
336345 serialPorts .MarkPortAsOpened (portname )
337346 serialPorts .List ()
@@ -342,10 +351,12 @@ func spHandlerOpen(portname string, baud int, buftype string) {
342351 go p .writerNoBuf ()
343352 // this is thread to send to serial port but with base64 decoding
344353 go p .writerRaw ()
345-
346- p .reader (buftype )
347-
348- serialPorts .List ()
354+ // this is the thread that reads from the serial port
355+ go func () {
356+ p .reader (buftype )
357+ serialPorts .List ()
358+ sh .Unregister (p )
359+ }()
349360}
350361
351362func (p * serport ) Close () {
0 commit comments