mirror of
https://github.com/nonoo/kappanhang.git
synced 2026-02-13 02:54:26 +01:00
Make an incoming new TCP serial port connection overwrite the previous one
This commit is contained in:
parent
83e6fa3259
commit
7d2d23fa6a
12
cmdrunner.go
12
cmdrunner.go
|
|
@ -84,13 +84,13 @@ func (c *cmdRunner) startIfNeeded(cmdLine string) {
|
||||||
go c.run(cmdLine)
|
go c.run(cmdLine)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cmdRunner) restart() {
|
// func (c *cmdRunner) restart() {
|
||||||
if c.restartNeeded == nil {
|
// if c.restartNeeded == nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
c.restartNeeded <- true
|
// c.restartNeeded <- true
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (c *cmdRunner) stop() {
|
func (c *cmdRunner) stop() {
|
||||||
if c.runEndNeeded == nil {
|
if c.runEndNeeded == nil {
|
||||||
|
|
|
||||||
125
serialtcpsrv.go
125
serialtcpsrv.go
|
|
@ -14,29 +14,34 @@ type serialTCPSrvStruct struct {
|
||||||
fromClient chan []byte
|
fromClient chan []byte
|
||||||
toClient chan []byte
|
toClient chan []byte
|
||||||
|
|
||||||
writeLoopDeinitNeededChan chan bool
|
clientLoopDeinitNeededChan chan bool
|
||||||
writeLoopDeinitFinishedChan chan bool
|
clientLoopDeinitFinishedChan chan bool
|
||||||
|
|
||||||
deinitNeededChan chan bool
|
deinitNeededChan chan bool
|
||||||
deinitFinishedChan chan bool
|
deinitFinishedChan chan bool
|
||||||
|
|
||||||
deinitializing bool
|
clientConnected bool
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
var serialTCPSrv serialTCPSrvStruct
|
var serialTCPSrv serialTCPSrvStruct
|
||||||
|
|
||||||
func (s *serialTCPSrvStruct) isClientConnected() bool {
|
func (s *serialTCPSrvStruct) isClientConnected() bool {
|
||||||
return s.writeLoopDeinitNeededChan != nil
|
s.mutex.Lock()
|
||||||
|
defer s.mutex.Unlock()
|
||||||
|
|
||||||
|
return s.clientConnected
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serialTCPSrvStruct) writeLoop(errChan chan error) {
|
func (s *serialTCPSrvStruct) writeLoop(writeLoopDeinitNeededChan, writeLoopDeinitFinishedChan chan bool,
|
||||||
|
errChan chan error) {
|
||||||
|
|
||||||
var b []byte
|
var b []byte
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case b = <-s.toClient:
|
case b = <-s.toClient:
|
||||||
case <-s.writeLoopDeinitNeededChan:
|
case <-writeLoopDeinitNeededChan:
|
||||||
s.writeLoopDeinitFinishedChan <- true
|
writeLoopDeinitFinishedChan <- true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,67 +63,79 @@ func (s *serialTCPSrvStruct) disconnectClient() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serialTCPSrvStruct) deinitClient() {
|
func (s *serialTCPSrvStruct) deinitClient() {
|
||||||
if s.writeLoopDeinitNeededChan != nil {
|
if s.clientLoopDeinitNeededChan != nil {
|
||||||
s.writeLoopDeinitNeededChan <- true
|
s.clientLoopDeinitNeededChan <- true
|
||||||
<-s.writeLoopDeinitFinishedChan
|
<-s.clientLoopDeinitFinishedChan
|
||||||
|
|
||||||
s.writeLoopDeinitNeededChan = nil
|
s.clientLoopDeinitNeededChan = nil
|
||||||
s.writeLoopDeinitFinishedChan = nil
|
s.clientLoopDeinitFinishedChan = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *serialTCPSrvStruct) clientLoop() {
|
||||||
|
s.mutex.Lock()
|
||||||
|
s.clientConnected = true
|
||||||
|
s.mutex.Unlock()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
s.mutex.Lock()
|
||||||
|
s.clientConnected = false
|
||||||
|
s.mutex.Unlock()
|
||||||
|
}()
|
||||||
|
|
||||||
|
log.Print("client ", s.client.RemoteAddr().String(), " connected")
|
||||||
|
|
||||||
|
writeLoopDeinitNeededChan := make(chan bool)
|
||||||
|
writeLoopDeinitFinishedChan := make(chan bool)
|
||||||
|
writeErrChan := make(chan error)
|
||||||
|
go s.writeLoop(writeLoopDeinitNeededChan, writeLoopDeinitFinishedChan, writeErrChan)
|
||||||
|
|
||||||
|
connected:
|
||||||
|
for {
|
||||||
|
b := make([]byte, maxSerialFrameLength)
|
||||||
|
n, err := s.client.Read(b)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case s.fromClient <- b[:n]:
|
||||||
|
case <-writeErrChan:
|
||||||
|
break connected
|
||||||
|
case <-s.clientLoopDeinitNeededChan:
|
||||||
|
writeLoopDeinitNeededChan <- true
|
||||||
|
<-writeLoopDeinitFinishedChan
|
||||||
|
|
||||||
|
s.clientLoopDeinitFinishedChan <- true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Print("client ", s.client.RemoteAddr().String(), " disconnected")
|
||||||
|
|
||||||
|
writeLoopDeinitNeededChan <- true
|
||||||
|
<-writeLoopDeinitFinishedChan
|
||||||
|
}
|
||||||
|
|
||||||
func (s *serialTCPSrvStruct) loop() {
|
func (s *serialTCPSrvStruct) loop() {
|
||||||
for {
|
for {
|
||||||
var err error
|
newClient, err := s.listener.Accept()
|
||||||
s.client, err = s.listener.Accept()
|
|
||||||
|
s.disconnectClient()
|
||||||
|
s.deinitClient()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
reportError(err)
|
reportError(err)
|
||||||
}
|
}
|
||||||
s.disconnectClient()
|
|
||||||
s.deinitClient()
|
|
||||||
<-s.deinitNeededChan
|
<-s.deinitNeededChan
|
||||||
s.deinitFinishedChan <- true
|
s.deinitFinishedChan <- true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("client ", s.client.RemoteAddr().String(), " connected")
|
s.client = newClient
|
||||||
|
|
||||||
s.writeLoopDeinitNeededChan = make(chan bool)
|
go s.clientLoop()
|
||||||
s.writeLoopDeinitFinishedChan = make(chan bool)
|
|
||||||
writeErrChan := make(chan error)
|
|
||||||
go s.writeLoop(writeErrChan)
|
|
||||||
|
|
||||||
connected := true
|
|
||||||
for connected {
|
|
||||||
b := make([]byte, maxSerialFrameLength)
|
|
||||||
n, err := s.client.Read(b)
|
|
||||||
if err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case s.fromClient <- b[:n]:
|
|
||||||
case <-writeErrChan:
|
|
||||||
connected = false
|
|
||||||
case <-s.deinitNeededChan:
|
|
||||||
s.disconnectClient()
|
|
||||||
s.deinitClient()
|
|
||||||
s.deinitFinishedChan <- true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s.disconnectClient()
|
|
||||||
s.deinitClient()
|
|
||||||
log.Print("client ", s.client.RemoteAddr().String(), " disconnected")
|
|
||||||
|
|
||||||
s.mutex.Lock()
|
|
||||||
if !s.deinitializing {
|
|
||||||
rigctldRunner.restart()
|
|
||||||
}
|
|
||||||
s.mutex.Unlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,10 +171,6 @@ func (s *serialTCPSrvStruct) initIfNeeded() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serialTCPSrvStruct) deinit() {
|
func (s *serialTCPSrvStruct) deinit() {
|
||||||
s.mutex.Lock()
|
|
||||||
s.deinitializing = true
|
|
||||||
s.mutex.Unlock()
|
|
||||||
|
|
||||||
if s.listener != nil {
|
if s.listener != nil {
|
||||||
s.listener.Close()
|
s.listener.Close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue