Skip to content

Commit 64afca7

Browse files
committed
Revert "Use a channel to better sync the closing of a port"
This reverts commit 45bf557.
1 parent b75d7ee commit 64afca7

File tree

1 file changed

+80
-82
lines changed

1 file changed

+80
-82
lines changed

serialport.go

Lines changed: 80 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -94,95 +94,95 @@ func (p *serport) reader() {
9494
ch := make([]byte, 1024)
9595
timeCheckOpen := time.Now()
9696

97-
mainLoop:
9897
for {
99-
select {
100-
case <-p.done:
98+
99+
n, err := p.portIo.Read(ch)
100+
101+
//if we detect that port is closing, break out o this for{} loop.
102+
if p.isClosing {
101103
strmsg := "Shutting down reader on " + p.portConf.Name
102104
log.Println(strmsg)
103105
h.broadcastSys <- []byte(strmsg)
104-
break mainLoop
105-
default:
106-
n, err := p.portIo.Read(ch)
107-
108-
// read can return legitimate bytes as well as an error
109-
// so process the bytes if n > 0
110-
if n > 0 {
111-
//log.Print("Read " + strconv.Itoa(n) + " bytes ch: " + string(ch))
112-
data := string(ch[:n])
113-
//log.Print("The data i will convert to json is:")
114-
//log.Print(data)
115-
116-
// give the data to our bufferflow so it can do it's work
117-
// to read/translate the data to see if it wants to block
118-
// writes to the serialport. each bufferflow type will decide
119-
// this on its own based on its logic, i.e. tinyg vs grbl vs others
120-
//p.b.bufferwatcher..OnIncomingData(data)
121-
p.bufferwatcher.OnIncomingData(data)
122-
123-
// see if the OnIncomingData handled the broadcast back
124-
// to the user. this option was added in case the OnIncomingData wanted
125-
// to do something fancier or implementation specific, i.e. TinyG Buffer
126-
// actually sends back data on a perline basis rather than our method
127-
// where we just send the moment we get it. the reason for this is that
128-
// the browser was sometimes getting back packets out of order which
129-
// of course would screw things up when parsing
130-
131-
if p.bufferwatcher.IsBufferGloballySendingBackIncomingData() == false {
132-
//m := SpPortMessage{"Alice", "Hello"}
133-
m := SpPortMessage{data}
134-
//log.Print("The m obj struct is:")
135-
//log.Print(m)
136-
137-
//b, err := json.MarshalIndent(m, "", "\t")
138-
b, err := json.Marshal(m)
139-
if err != nil {
140-
log.Println(err)
141-
h.broadcastSys <- []byte("Error creating json on " + p.portConf.Name + " " +
142-
err.Error() + " The data we were trying to convert is: " + string(ch[:n]))
143-
break
144-
}
145-
//log.Print("Printing out json byte data...")
146-
//log.Print(string(b))
147-
h.broadcastSys <- b
148-
//h.broadcastSys <- []byte("{ \"p\" : \"" + p.portConf.Name + "\", \"d\": \"" + string(ch[:n]) + "\" }\n")
149-
}
150-
}
151-
152-
// double check that we got characters in the buffer
153-
// before deciding if an EOF is legitimately a reason
154-
// to close the port because we're seeing that on some
155-
// os's like Linux/Ubuntu you get an EOF when you open
156-
// the port. Perhaps the EOF was buffered from a previous
157-
// close and the OS doesn't clear out that buffer on a new
158-
// connect. This means we'll only catch EOF's when there are
159-
// other characters with it, but that seems to work ok
160-
if n <= 0 {
161-
if err == io.EOF || err == io.ErrUnexpectedEOF {
162-
// hit end of file
163-
log.Println("Hit end of file on serial port")
164-
h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Got EOF (End of File) on port which usually means another app other than Serial Port JSON Server is locking your port. " + err.Error() + "\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + "}")
165-
166-
}
106+
break
107+
}
167108

109+
// read can return legitimate bytes as well as an error
110+
// so process the bytes if n > 0
111+
if n > 0 {
112+
//log.Print("Read " + strconv.Itoa(n) + " bytes ch: " + string(ch))
113+
data := string(ch[:n])
114+
//log.Print("The data i will convert to json is:")
115+
//log.Print(data)
116+
117+
// give the data to our bufferflow so it can do it's work
118+
// to read/translate the data to see if it wants to block
119+
// writes to the serialport. each bufferflow type will decide
120+
// this on its own based on its logic, i.e. tinyg vs grbl vs others
121+
//p.b.bufferwatcher..OnIncomingData(data)
122+
p.bufferwatcher.OnIncomingData(data)
123+
124+
// see if the OnIncomingData handled the broadcast back
125+
// to the user. this option was added in case the OnIncomingData wanted
126+
// to do something fancier or implementation specific, i.e. TinyG Buffer
127+
// actually sends back data on a perline basis rather than our method
128+
// where we just send the moment we get it. the reason for this is that
129+
// the browser was sometimes getting back packets out of order which
130+
// of course would screw things up when parsing
131+
132+
if p.bufferwatcher.IsBufferGloballySendingBackIncomingData() == false {
133+
//m := SpPortMessage{"Alice", "Hello"}
134+
m := SpPortMessage{data}
135+
//log.Print("The m obj struct is:")
136+
//log.Print(m)
137+
138+
//b, err := json.MarshalIndent(m, "", "\t")
139+
b, err := json.Marshal(m)
168140
if err != nil {
169141
log.Println(err)
170-
h.broadcastSys <- []byte("Error reading on " + p.portConf.Name + " " +
171-
err.Error() + " Closing port.")
172-
h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Got error reading on port. " + err.Error() + "\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + "}")
142+
h.broadcastSys <- []byte("Error creating json on " + p.portConf.Name + " " +
143+
err.Error() + " The data we were trying to convert is: " + string(ch[:n]))
173144
break
174145
}
146+
//log.Print("Printing out json byte data...")
147+
//log.Print(string(b))
148+
h.broadcastSys <- b
149+
//h.broadcastSys <- []byte("{ \"p\" : \"" + p.portConf.Name + "\", \"d\": \"" + string(ch[:n]) + "\" }\n")
150+
}
151+
}
152+
153+
// double check that we got characters in the buffer
154+
// before deciding if an EOF is legitimately a reason
155+
// to close the port because we're seeing that on some
156+
// os's like Linux/Ubuntu you get an EOF when you open
157+
// the port. Perhaps the EOF was buffered from a previous
158+
// close and the OS doesn't clear out that buffer on a new
159+
// connect. This means we'll only catch EOF's when there are
160+
// other characters with it, but that seems to work ok
161+
if n <= 0 {
162+
if err == io.EOF || err == io.ErrUnexpectedEOF {
163+
// hit end of file
164+
log.Println("Hit end of file on serial port")
165+
h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Got EOF (End of File) on port which usually means another app other than Serial Port JSON Server is locking your port. " + err.Error() + "\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + "}")
166+
167+
}
175168

176-
// Keep track of time difference between two consecutive read with n == 0 and err == nil
177-
// we get here if the port has been disconnected while open (cpu usage will jump to 100%)
178-
// let's close the port only if the events are extremely fast (<1ms)
179-
if err == nil {
180-
diff := time.Since(timeCheckOpen)
181-
if diff.Nanoseconds() < 1000000 {
182-
p.isClosing = true
183-
}
184-
timeCheckOpen = time.Now()
169+
if err != nil {
170+
log.Println(err)
171+
h.broadcastSys <- []byte("Error reading on " + p.portConf.Name + " " +
172+
err.Error() + " Closing port.")
173+
h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Got error reading on port. " + err.Error() + "\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + "}")
174+
break
175+
}
176+
177+
// Keep track of time difference between two consecutive read with n == 0 and err == nil
178+
// we get here if the port has been disconnected while open (cpu usage will jump to 100%)
179+
// let's close the port only if the events are extremely fast (<1ms)
180+
if err == nil {
181+
diff := time.Since(timeCheckOpen)
182+
if diff.Nanoseconds() < 1000000 {
183+
p.isClosing = true
185184
}
185+
timeCheckOpen = time.Now()
186186
}
187187
}
188188
}
@@ -338,7 +338,7 @@ func spHandlerOpen(portname string, baud int, buftype string, isSecondary bool)
338338
log.Print("Opened port successfully")
339339
//p := &serport{send: make(chan []byte, 256), portConf: conf, portIo: sp}
340340
// we can go up to 256,000 lines of gcode in the buffer
341-
p := &serport{sendBuffered: make(chan Cmd, 256000), done: make(chan bool), sendNoBuf: make(chan Cmd), portConf: conf, portIo: sp, BufferType: buftype, IsPrimary: isPrimary, IsSecondary: isSecondary}
341+
p := &serport{sendBuffered: make(chan Cmd, 256000), sendNoBuf: make(chan Cmd), portConf: conf, portIo: sp, BufferType: buftype, IsPrimary: isPrimary, IsSecondary: isSecondary}
342342

343343
bw := &BufferflowDefault{}
344344
bw.Init()
@@ -358,9 +358,7 @@ func spHandlerOpen(portname string, baud int, buftype string, isSecondary bool)
358358
}
359359

360360
func spHandlerClose(p *serport) {
361-
// p.isClosing = true
362-
p.done <- true
363-
361+
p.isClosing = true
364362
//close the port
365363
//elicit response from hardware to close out p.reader()
366364
_, _ = p.portIo.Write([]byte("?"))

0 commit comments

Comments
 (0)