From 06d83ca5941045e55b36939d05b7eafd1d025f27 Mon Sep 17 00:00:00 2001 From: NSMak Date: Thu, 9 Dec 2021 18:32:10 +0300 Subject: [PATCH] Fix RTU data race --- server.go | 9 +++++++++ servertu.go | 14 +++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/server.go b/server.go index 0020dd6..38fe520 100644 --- a/server.go +++ b/server.go @@ -4,6 +4,7 @@ package mbserver import ( "io" "net" + "sync" "github.com/goburrow/serial" ) @@ -14,6 +15,8 @@ type Server struct { Debug bool listeners []net.Listener ports []serial.Port + portsWG sync.WaitGroup + portsCloseChan chan struct{} requestChan chan *Request function [256](func(*Server, Framer) ([]byte, *Exception)) DiscreteInputs []byte @@ -49,6 +52,8 @@ func NewServer() *Server { s.function[16] = WriteHoldingRegisters s.requestChan = make(chan *Request) + s.portsCloseChan = make(chan struct{}) + go s.handler() return s @@ -94,6 +99,10 @@ func (s *Server) Close() { for _, listen := range s.listeners { listen.Close() } + + close(s.portsCloseChan) + s.portsWG.Wait() + for _, port := range s.ports { port.Close() } diff --git a/servertu.go b/servertu.go index eb5486f..80e050d 100644 --- a/servertu.go +++ b/servertu.go @@ -15,13 +15,25 @@ func (s *Server) ListenRTU(serialConfig *serial.Config) (err error) { log.Fatalf("failed to open %s: %v\n", serialConfig.Address, err) } s.ports = append(s.ports, port) - go s.acceptSerialRequests(port) + + s.portsWG.Add(1) + go func() { + defer s.portsWG.Done() + s.acceptSerialRequests(port) + }() + return err } func (s *Server) acceptSerialRequests(port serial.Port) { SkipFrameError: for { + select { + case <-s.portsCloseChan: + return + default: + } + buffer := make([]byte, 512) bytesRead, err := port.Read(buffer)