@@ -20,6 +20,7 @@ import (
20
20
"encoding/base64"
21
21
"io"
22
22
"strconv"
23
+ "sync"
23
24
"sync/atomic"
24
25
"time"
25
26
"unicode/utf8"
@@ -273,7 +274,13 @@ func (p *serport) writerRaw() {
273
274
h .broadcastSys <- []byte (msgstr )
274
275
}
275
276
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
+
276
281
func spHandlerOpen (portname string , baud int , buftype string ) {
282
+ spHandlerOpenLock .Lock ()
283
+ defer spHandlerOpenLock .Unlock ()
277
284
278
285
log .Print ("Inside spHandler" )
279
286
@@ -295,11 +302,14 @@ func spHandlerOpen(portname string, baud int, buftype string) {
295
302
sp , err := serial .Open (portname , mode )
296
303
log .Print ("Just tried to open port" )
297
304
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
+ }
303
313
return
304
314
}
305
315
log .Print ("Opened port successfully" )
@@ -331,7 +341,6 @@ func spHandlerOpen(portname string, baud int, buftype string) {
331
341
p .bufferwatcher = bw
332
342
333
343
sh .Register (p )
334
- defer sh .Unregister (p )
335
344
336
345
serialPorts .MarkPortAsOpened (portname )
337
346
serialPorts .List ()
@@ -342,10 +351,12 @@ func spHandlerOpen(portname string, baud int, buftype string) {
342
351
go p .writerNoBuf ()
343
352
// this is thread to send to serial port but with base64 decoding
344
353
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
+ }()
349
360
}
350
361
351
362
func (p * serport ) Close () {
0 commit comments