Make an incoming new TCP serial port connection overwrite the previous one

This commit is contained in:
Nonoo 2020-11-05 23:59:39 +01:00
parent 83e6fa3259
commit 7d2d23fa6a
2 changed files with 75 additions and 62 deletions

View file

@ -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 {

View file

@ -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,40 +63,35 @@ 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) loop() { func (s *serialTCPSrvStruct) clientLoop() {
for { s.mutex.Lock()
var err error s.clientConnected = true
s.client, err = s.listener.Accept() s.mutex.Unlock()
if err != nil { defer func() {
if err != io.EOF { s.mutex.Lock()
reportError(err) s.clientConnected = false
} s.mutex.Unlock()
s.disconnectClient() }()
s.deinitClient()
<-s.deinitNeededChan
s.deinitFinishedChan <- true
return
}
log.Print("client ", s.client.RemoteAddr().String(), " connected") log.Print("client ", s.client.RemoteAddr().String(), " connected")
s.writeLoopDeinitNeededChan = make(chan bool) writeLoopDeinitNeededChan := make(chan bool)
s.writeLoopDeinitFinishedChan = make(chan bool) writeLoopDeinitFinishedChan := make(chan bool)
writeErrChan := make(chan error) writeErrChan := make(chan error)
go s.writeLoop(writeErrChan) go s.writeLoop(writeLoopDeinitNeededChan, writeLoopDeinitFinishedChan, writeErrChan)
connected := true connected:
for connected { for {
b := make([]byte, maxSerialFrameLength) b := make([]byte, maxSerialFrameLength)
n, err := s.client.Read(b) n, err := s.client.Read(b)
if err != nil { if err != nil {
@ -101,24 +101,41 @@ func (s *serialTCPSrvStruct) loop() {
select { select {
case s.fromClient <- b[:n]: case s.fromClient <- b[:n]:
case <-writeErrChan: case <-writeErrChan:
connected = false break connected
case <-s.deinitNeededChan: case <-s.clientLoopDeinitNeededChan:
s.disconnectClient() writeLoopDeinitNeededChan <- true
s.deinitClient() <-writeLoopDeinitFinishedChan
s.deinitFinishedChan <- true
s.clientLoopDeinitFinishedChan <- true
return return
} }
} }
s.disconnectClient()
s.deinitClient()
log.Print("client ", s.client.RemoteAddr().String(), " disconnected") log.Print("client ", s.client.RemoteAddr().String(), " disconnected")
s.mutex.Lock() writeLoopDeinitNeededChan <- true
if !s.deinitializing { <-writeLoopDeinitFinishedChan
rigctldRunner.restart()
} }
s.mutex.Unlock()
func (s *serialTCPSrvStruct) loop() {
for {
newClient, err := s.listener.Accept()
s.disconnectClient()
s.deinitClient()
if err != nil {
if err != io.EOF {
reportError(err)
}
<-s.deinitNeededChan
s.deinitFinishedChan <- true
return
}
s.client = newClient
go s.clientLoop()
} }
} }
@ -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()
} }